utSchema.pp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953
  1. {
  2. This file is part of the Free Component Library
  3. Testsuite for JSONSchema class
  4. Copyright (c) 2024 by Michael Van Canneyt [email protected]
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit utSchema;
  12. {$mode ObjFPC}{$H+}
  13. interface
  14. uses
  15. Classes, SysUtils, fpcunit, testregistry, fpjson, fpjson.schema.types, fpjson.schema.schema,
  16. fpjson.schema.testutils;
  17. type
  18. { TTestSchemaObject }
  19. TTestSchemaObject = class(TSchemaTestcase)
  20. private
  21. FSchema: TJSONSchema;
  22. Public
  23. Procedure SetUp; override;
  24. Procedure TearDown; override;
  25. Property Schema : TJSONSchema Read FSchema;
  26. end;
  27. TTestJSONSchemaMetadata = class(TJSONSchemaMetadata)
  28. Public
  29. Property AVailableKeywords : TJSONSchemaKeywords Read Keywords;
  30. end;
  31. { TTestMetadata }
  32. TTestMetadata = class(TTestSchemaObject)
  33. private
  34. FData: TJSONSchemaMetadata;
  35. Public
  36. Procedure SetUp; override;
  37. Procedure TearDown; override;
  38. procedure TestHavekeyword(aKeyword : TJSONSchemaKeyword);
  39. property Data : TJSONSchemaMetadata Read FData;
  40. Published
  41. Procedure TestHookup;
  42. Procedure TestTitle;
  43. Procedure TestKeywords;
  44. Procedure TestDescription;
  45. Procedure TestDefaultValue;
  46. Procedure TestDeprecated;
  47. Procedure TestExamples;
  48. Procedure TestReadOnly;
  49. Procedure TestWriteOnly;
  50. Procedure TestAssign;
  51. end;
  52. { TTestSchemaValidations }
  53. TTestSchemaValidations = class(TTestSchemaObject)
  54. private
  55. FData: TJSONSchemaValidations;
  56. Public
  57. Procedure SetUp; override;
  58. Procedure TearDown; override;
  59. procedure TestHavekeyword(aKeyword : TJSONSchemaKeyword);
  60. property Data : TJSONSchemaValidations Read FData;
  61. Published
  62. Procedure TestHookup;
  63. Procedure TestTypes;
  64. Procedure TestconstValue;
  65. Procedure TestEnum;
  66. Procedure TestExclusiveMaximum;
  67. Procedure TestExclusiveMinimum;
  68. Procedure TestMaximum;
  69. Procedure TestMinimum;
  70. Procedure TestMaxItems;
  71. Procedure TestMinItems;
  72. Procedure TestRequired;
  73. Procedure TestMaxLength;
  74. Procedure TestMinLength;
  75. Procedure TestMaxProperties;
  76. Procedure TestMinProperties;
  77. Procedure TestPattern;
  78. Procedure TestUniqueItems;
  79. Procedure TestMinContains;
  80. Procedure TestMaxContains;
  81. Procedure TestMultipleOf;
  82. Procedure TestDependentRequired;
  83. Procedure TestFormat;
  84. Procedure TestFormatValidator;
  85. Procedure TestcontentMediaType;
  86. Procedure TestcontentEncoding;
  87. Procedure TestcontentSchema;
  88. Procedure TestAssign;
  89. end;
  90. TTestSchema = Class(TTestSchemaObject)
  91. private
  92. procedure CheckKeyword(aKeyword: TJSONSchemaKeyword);
  93. Published
  94. Procedure TestHookup;
  95. Procedure TestCreateChildSchemaName;
  96. Procedure TestCreateChildSchemaKeyword;
  97. Procedure TestCreateChildSchemaNoName;
  98. Procedure TestRootSchema;
  99. Procedure TestFind;
  100. Procedure TestIndexOfChild;
  101. Procedure TestFindChild;
  102. Procedure TestPath;
  103. // Vocabulary
  104. Procedure TestValidation;
  105. Procedure TestMetaData;
  106. Procedure TestID;
  107. Procedure TestSchema;
  108. Procedure TestRef;
  109. Procedure TestComment;
  110. Procedure TestAnchor;
  111. Procedure TestDefs;
  112. Procedure TestDynamicAnchor;
  113. Procedure TestDynamicRef;
  114. Procedure TestVocabulary;
  115. Procedure TestAllof;
  116. Procedure TestAnyOf;
  117. Procedure TestOneOf;
  118. Procedure TestNotSchema;
  119. Procedure TestIfSchema;
  120. Procedure TestThenSchema;
  121. Procedure TestElseSchema;
  122. Procedure TestProperties;
  123. Procedure TestItems;
  124. Procedure TestPrefixItems;
  125. Procedure TestPatternProperties;
  126. Procedure TestPropertyNames;
  127. Procedure TestAdditionalProperties;
  128. Procedure TestDependentSchemas;
  129. Procedure TestContains;
  130. Procedure TestUnevaluatedItems;
  131. Procedure TestUnevaluatedProperties;
  132. end;
  133. implementation
  134. { TTestSchemaObject }
  135. procedure TTestSchemaObject.SetUp;
  136. begin
  137. inherited SetUp;
  138. FSchema:=TJSONSchema.Create;
  139. end;
  140. procedure TTestSchemaObject.TearDown;
  141. begin
  142. FreeAndNil(FSchema);
  143. inherited TearDown;
  144. end;
  145. { TTestMetadata }
  146. procedure TTestMetadata.SetUp;
  147. begin
  148. inherited SetUp;
  149. FData:=TTestJSONSchemaMetadata.Create(Schema);
  150. end;
  151. procedure TTestMetadata.TearDown;
  152. begin
  153. FreeAndNil(FData);
  154. inherited TearDown;
  155. end;
  156. procedure TTestMetadata.TestHavekeyword(aKeyword: TJSONSchemaKeyword);
  157. begin
  158. AssertTrue('Have '+aKeyword.AsString+' data',Data.HasKeywordData(aKeyword));
  159. AssertTrue('Keywords',Data.KeywordsWithData=[aKeyWord]);
  160. AssertTrue('Schema constrained',Data.Schema.MatchType=smConstrained);
  161. end;
  162. procedure TTestMetadata.TestHookup;
  163. var
  164. T : TJSONSchemaKeyword;
  165. begin
  166. AssertNotNull('Have data',Data);
  167. AssertSame('Schema',Schema,Data.Schema);
  168. For T in TJSONSchemaKeyword do
  169. AssertFalse('No '+t.AsString+' data on init',Data.HasKeywordData(T));
  170. end;
  171. procedure TTestMetadata.TestTitle;
  172. begin
  173. Data.Title:='Solo';
  174. TestHavekeyword(jskTitle);
  175. AssertTrue('Sets constrained',Schema.MatchType=smConstrained);
  176. end;
  177. procedure TTestMetadata.TestKeywords;
  178. const
  179. KW = [jskTitle,jskDescription,jskDefault,jskDeprecated,
  180. jskExamples,jskReadOnly,jskWriteOnly];
  181. begin
  182. AssertTrue('Correct keyword list',Kw=TTestJSONSchemaMetadata(Data).AvailableKeywords)
  183. end;
  184. procedure TTestMetadata.TestDescription;
  185. begin
  186. Data.Description:='Solo';
  187. TestHavekeyword(jskDescription);
  188. end;
  189. procedure TTestMetadata.TestDefaultValue;
  190. begin
  191. Data.DefaultValue:=TJSONIntegerNumber.Create(12);
  192. TestHavekeyword(jskDefault);
  193. end;
  194. procedure TTestMetadata.TestDeprecated;
  195. begin
  196. Data.Deprecated:=False;
  197. TestHavekeyword(jskDeprecated);
  198. end;
  199. procedure TTestMetadata.TestExamples;
  200. begin
  201. // Needs to be done manually, we do not detect changes to
  202. // Schema.MatchType:=smConstrained;
  203. Data.Examples:=TJSONArray.Create(['Example1']);
  204. TestHavekeyword(jskExamples);
  205. end;
  206. procedure TTestMetadata.TestReadOnly;
  207. begin
  208. Data.ReadOnly:=True;
  209. TestHavekeyword(jskReadOnly);
  210. end;
  211. procedure TTestMetadata.TestWriteOnly;
  212. begin
  213. Data.WriteOnly:=True;
  214. TestHavekeyword(jskWriteOnly);
  215. end;
  216. procedure TTestMetadata.TestAssign;
  217. var
  218. M : TJSONSchemaMetadata;
  219. begin
  220. M:=TJSONSchemaMetadata.Create(Schema);
  221. try
  222. Data.Title:='Solo';
  223. Data.Description:='Solo2';
  224. Data.DefaultValue:=TJSONIntegerNumber.Create(12);
  225. Data.Deprecated:=True;
  226. Data.Examples.Add(TJSONString.Create('Example1'));
  227. Data.ReadOnly:=True;
  228. Data.WriteOnly:=True;
  229. M.Assign(Data);
  230. AssertEquals('Title',Data.Title,M.Title);
  231. AssertEquals('Description',Data.Description,m.Description);
  232. AssertEquals('Deprecated',Data.Deprecated,m.Deprecated);
  233. AssertEquals('ReadOnly',Data.ReadOnly,m.ReadOnly);
  234. AssertEquals('WriteOnly',Data.WriteOnly,m.WriteOnly);
  235. AssertNotNull('Default copied',M.DefaultValue);
  236. AssertEquals('Correct value',12,m.DefaultValue.AsInteger);
  237. AssertEquals('Examples copied',Data.Examples.Count,M.Examples.Count);
  238. finally
  239. M.Free;
  240. end;
  241. end;
  242. { TTestSchemaValidations }
  243. procedure TTestSchemaValidations.SetUp;
  244. begin
  245. inherited SetUp;
  246. FData:=TJSONSchemaValidations.Create(Schema);
  247. end;
  248. procedure TTestSchemaValidations.TearDown;
  249. begin
  250. FreeAndNil(FData);
  251. inherited TearDown;
  252. end;
  253. procedure TTestSchemaValidations.TestHavekeyword(aKeyword: TJSONSchemaKeyword);
  254. begin
  255. AssertTrue('Have '+aKeyword.AsString+' data',Data.HasKeywordData(aKeyword));
  256. AssertTrue('Correct keywords ',Data.KeywordsWithData=[aKeyword]);
  257. AssertTrue('Schema set to constrained',Schema.MatchType=smConstrained);
  258. end;
  259. procedure TTestSchemaValidations.TestHookup;
  260. var
  261. T : TJSONSchemaKeyword;
  262. begin
  263. AssertNotNull('Have data',Data);
  264. AssertSame('Schema',Schema,Data.Schema);
  265. For T in TJSONSchemaKeyword do
  266. AssertFalse('No '+t.AsString+' data on init',Data.HasKeywordData(T));
  267. end;
  268. procedure TTestSchemaValidations.TestTypes;
  269. begin
  270. Data.Types:=[sstObject,sstString];
  271. TestHavekeyword(jskType);
  272. AssertTrue('Sets constrained',Schema.MatchType=smConstrained);
  273. end;
  274. procedure TTestSchemaValidations.TestconstValue;
  275. begin
  276. Data.ConstValue:=TJSONObject.Create(['me','you']);
  277. TestHavekeyword(jskConst);
  278. end;
  279. procedure TTestSchemaValidations.TestEnum;
  280. begin
  281. Data.Enum:=TJSONArray.Create([TJSONObject.Create(['me','you'])]);
  282. TestHavekeyword(jskEnum);
  283. end;
  284. procedure TTestSchemaValidations.TestExclusiveMaximum;
  285. begin
  286. Data.ExclusiveMaximum:=10.0;
  287. TestHavekeyword(jskExclusiveMaximum);
  288. end;
  289. procedure TTestSchemaValidations.TestExclusiveMinimum;
  290. begin
  291. Data.ExclusiveMinimum:=10.0;
  292. TestHavekeyword(jskExclusiveMinimum);
  293. end;
  294. procedure TTestSchemaValidations.TestMaximum;
  295. begin
  296. Data.Maximum:=10.0;
  297. TestHavekeyword(jskMaximum);
  298. end;
  299. procedure TTestSchemaValidations.TestMinimum;
  300. begin
  301. Data.Minimum:=10.0;
  302. TestHavekeyword(jskMinimum);
  303. end;
  304. procedure TTestSchemaValidations.TestMaxItems;
  305. begin
  306. Data.MaxItems:=10;
  307. TestHavekeyword(jskMaxItems);
  308. end;
  309. procedure TTestSchemaValidations.TestMinItems;
  310. begin
  311. Data.MaxItems:=13;
  312. TestHavekeyword(jskMaxItems);
  313. end;
  314. procedure TTestSchemaValidations.TestRequired;
  315. begin
  316. Data.Required.Add('type');
  317. TestHavekeyword(jskRequired);
  318. end;
  319. procedure TTestSchemaValidations.TestMaxLength;
  320. begin
  321. Data.MaxLength:=10;
  322. TestHavekeyword(jskMaxLength);
  323. end;
  324. procedure TTestSchemaValidations.TestMinLength;
  325. begin
  326. Data.MinLength:=10;
  327. TestHavekeyword(jskMinLength);
  328. end;
  329. procedure TTestSchemaValidations.TestMaxProperties;
  330. begin
  331. Data.MaxProperties:=10;
  332. TestHavekeyword(jskMaxProperties);
  333. end;
  334. procedure TTestSchemaValidations.TestMinProperties;
  335. begin
  336. Data.MinProperties:=10;
  337. TestHavekeyword(jskMinProperties);
  338. end;
  339. procedure TTestSchemaValidations.TestPattern;
  340. begin
  341. Data.MinProperties:=10;
  342. TestHavekeyword(jskMinProperties);
  343. end;
  344. procedure TTestSchemaValidations.TestUniqueItems;
  345. begin
  346. Data.UniqueItems:=True;
  347. TestHavekeyword(jskUniqueItems);
  348. end;
  349. procedure TTestSchemaValidations.TestMinContains;
  350. begin
  351. Data.MinContains:=10;
  352. TestHavekeyword(jskMinContains);
  353. end;
  354. procedure TTestSchemaValidations.TestMaxContains;
  355. begin
  356. Data.MaxContains:=10;
  357. TestHavekeyword(jskMaxContains);
  358. end;
  359. procedure TTestSchemaValidations.TestMultipleOf;
  360. begin
  361. Data.MultipleOf:=10.1;
  362. TestHavekeyword(jskMultipleOf);
  363. end;
  364. procedure TTestSchemaValidations.TestDependentRequired;
  365. begin
  366. Data.DependentRequired.AddDependent('xyz');
  367. TestHavekeyword(jskDependentRequired);
  368. end;
  369. procedure TTestSchemaValidations.TestFormat;
  370. begin
  371. Data.Format:='uri';
  372. TestHavekeyword(jskFormat);
  373. end;
  374. procedure TTestSchemaValidations.TestFormatValidator;
  375. begin
  376. Data.FormatValidator:=sfvUri;
  377. TestHavekeyword(jskFormat);
  378. AssertEquals('String','uri',Data.Format);
  379. end;
  380. procedure TTestSchemaValidations.TestcontentMediaType;
  381. begin
  382. Data.contentMediaType:='application/json';
  383. TestHavekeyword(jskContentMediaType);
  384. end;
  385. procedure TTestSchemaValidations.TestcontentEncoding;
  386. begin
  387. Data.contentEncoding:='utf8';
  388. TestHavekeyword(jskContentEncoding);
  389. end;
  390. procedure TTestSchemaValidations.TestcontentSchema;
  391. begin
  392. Data.contentSchema.MatchType:=smAny;
  393. TestHavekeyword(jskContentSchema);
  394. end;
  395. procedure TTestSchemaValidations.TestAssign;
  396. var
  397. V : TJSONSchemaValidations;
  398. begin
  399. Data.UniqueItems:=True;
  400. Data.Types:=[sstObject];
  401. Data.Required.Add('x');
  402. Data.Pattern:='Pattern';
  403. Data.MultipleOf:=10;
  404. Data.MinProperties:=11;
  405. Data.MinLength:=12;
  406. Data.MinItems:=13;
  407. Data.Minimum:=14;
  408. Data.MinContains:=15;
  409. Data.MaxProperties:=16;
  410. Data.MaxLength:=17;
  411. Data.MaxItems:=18;
  412. Data.Maximum:=19;
  413. Data.MaxContains:=20;
  414. Data.Format:='uri';
  415. Data.ExclusiveMinimum:=12;
  416. Data.ExclusiveMaximum:=13;
  417. Data.contentMediaType:='application/json';
  418. Data.contentEncoding:='utf8';
  419. Data.constValue:=TJSONBoolean.Create(True);
  420. V:=TJSONSchemaValidations.Create(Schema);
  421. try
  422. V.Assign(data);
  423. With Data do
  424. begin
  425. AssertEquals('UniqueItems',UniqueItems,V.UniqueItems);
  426. AssertTrue('Types',Types=V.Types);
  427. AssertEquals('Required',Required.Text,V.Required.Text);
  428. AssertEquals('Pattern',Pattern,V.Pattern);
  429. AssertEquals('MultipleOf',MultipleOf,V.MultipleOf);
  430. AssertEquals('MinProperties',MinProperties,V.MinProperties);
  431. AssertEquals('MinLength',MinLength,V.MinLength);
  432. AssertEquals('MinItems',MinItems,V.MinItems);
  433. AssertEquals('Minimum',Minimum,V.Minimum);
  434. AssertEquals('MinContains',MinContains,V.MinContains);
  435. AssertEquals('MaxProperties',MaxProperties,V.MaxProperties);
  436. AssertEquals('MaxLength',MaxLength,V.MaxLength);
  437. AssertEquals('MaxItems',MaxItems,V.MaxItems);
  438. AssertEquals('Maximum',Maximum,V.Maximum);
  439. AssertEquals('MaxContains',MaxContains,V.MaxContains);
  440. AssertEquals('Format',Format,V.Format);
  441. AssertEquals('ExclusiveMinimum',ExclusiveMinimum,V.ExclusiveMinimum);
  442. AssertEquals('ExclusiveMaximum',ExclusiveMaximum,V.ExclusiveMaximum);
  443. AssertEquals('contentMediaType',contentMediaType,V.contentMediaType);
  444. AssertEquals('contentEncoding',contentEncoding,V.contentEncoding);
  445. AssertEquals('constValue',constValue.asJSON,V.constValue.aSJSON);
  446. end
  447. finally
  448. V.Free
  449. end;
  450. end;
  451. procedure TTestSchema.TestHookup;
  452. var
  453. K : TJSONSchemaKeyword;
  454. begin
  455. AssertNotNull('Have schema',Schema);
  456. AssertNotNull('Have metadata',Schema.MetaData);
  457. AssertNotNull('Have validations',Schema.Validations);
  458. for K in TJSONSchemaKeyword do
  459. AssertFalse('No keyword '+K.AsString,Schema.HasKeywordData(k));
  460. AssertSame('Metadata schema',Schema,Schema.Metadata.Schema);
  461. AssertSame('Validations schema',Schema,Schema.Validations.Schema);
  462. AssertEquals('No children',0,Schema.ChildSchemaCount);
  463. AssertSame('root',Schema,Schema.RootSchema);
  464. end;
  465. procedure TTestSchema.TestCreateChildSchemaName;
  466. var
  467. S : TJSONSchema;
  468. begin
  469. // Create child schema with given name
  470. // function CreateChildSchema(aName : string): TJsonSchema; overload;
  471. S:=Schema.CreateChildSchema('ok');
  472. try
  473. AssertSame('Schema parent',schema,S.Parent);
  474. AssertEquals('Name','ok',S.Name);
  475. AssertEquals('Count',1,Schema.ChildSchemaCount);
  476. AssertSame('Child',S,Schema.ChildSchemas[0]);
  477. finally
  478. S.Free;
  479. end;
  480. AssertEquals('Count',0,Schema.ChildSchemaCount);
  481. end;
  482. procedure TTestSchema.TestCreateChildSchemaKeyword;
  483. var
  484. S : TJSONSchema;
  485. begin
  486. // Create child schema with given name
  487. // function CreateChildSchema(aName : string): TJsonSchema; overload;
  488. S:=Schema.CreateChildSchema(jskContentSchema);
  489. try
  490. AssertSame('Schema parent',schema,S.Parent);
  491. AssertEquals('Name','contentSchema',S.Name);
  492. AssertEquals('Count',1,Schema.ChildSchemaCount);
  493. AssertSame('Child',S,Schema.ChildSchemas[0]);
  494. finally
  495. S.Free;
  496. end;
  497. AssertEquals('Count',0,Schema.ChildSchemaCount);
  498. end;
  499. procedure TTestSchema.TestCreateChildSchemaNoName;
  500. var
  501. S : TJSONSchema;
  502. begin
  503. // Create child schema with given name
  504. // function CreateChildSchema(aName : string): TJsonSchema; overload;
  505. S:=Schema.CreateChildSchema();
  506. try
  507. AssertSame('Schema parent',schema,S.Parent);
  508. AssertEquals('Name','',S.Name);
  509. AssertEquals('Count',1,Schema.ChildSchemaCount);
  510. AssertSame('Child',S,Schema.ChildSchemas[0]);
  511. finally
  512. S.Free;
  513. end;
  514. AssertEquals('Count',0,Schema.ChildSchemaCount);
  515. end;
  516. procedure TTestSchema.TestRootSchema;
  517. var
  518. S,S2 : TJSONSchema;
  519. begin
  520. // Create child schema with given name
  521. // function CreateChildSchema(aName : string): TJsonSchema; overload;
  522. S:=Schema.CreateChildSchema();
  523. try
  524. AssertSame('Schema parent',schema,S.Parent);
  525. AssertEquals('Name','',S.Name);
  526. AssertEquals('Count 1',1,Schema.ChildSchemaCount);
  527. AssertSame('Child ',S,Schema.ChildSchemas[0]);
  528. S2:=S.CreateChildSchema();
  529. AssertEquals('Count 1a',1,Schema.ChildSchemaCount);
  530. AssertEquals('Count 2',1,S.ChildSchemaCount);
  531. AssertSame('Child 2',S2,S.ChildSchemas[0]);
  532. AssertSame('root',Schema,S2.RootSchema);
  533. finally
  534. S.Free;
  535. S2.Free;
  536. end;
  537. AssertEquals('Count',0,Schema.ChildSchemaCount);
  538. end;
  539. procedure TTestSchema.TestFind;
  540. // Find schema using schema-local $Ref URI
  541. var
  542. S,S2 : TJSONSchema;
  543. begin
  544. // Create child schema with given name
  545. // function CreateChildSchema(aName : string): TJsonSchema; overload;
  546. S:=Schema.CreateChildSchema('x');
  547. try
  548. S2:=S.CreateChildSchema('y');
  549. AssertSame('Find #/x/y',S2,Schema.Find('#/x/y'));
  550. finally
  551. S.Free;
  552. S2.Free;
  553. end;
  554. end;
  555. procedure TTestSchema.TestIndexOfChild;
  556. // Find index of direct child schema with given name
  557. var
  558. S,S2 : TJSONSchema;
  559. begin
  560. // Create child schema with given name
  561. // function CreateChildSchema(aName : string): TJsonSchema; overload;
  562. S2:=nil;
  563. S:=Schema.CreateChildSchema('x');
  564. try
  565. S2:=Schema.CreateChildSchema('y');
  566. AssertEquals('Count',2,Schema.ChildSchemaCount);
  567. AssertEquals('Index',0,Schema.IndexOfChild('x'));
  568. AssertEquals('Index',1,Schema.IndexOfChild('y'));
  569. finally
  570. S.Free;
  571. S2.Free;
  572. end;
  573. AssertEquals('Count',0,Schema.ChildSchemaCount);
  574. end;
  575. procedure TTestSchema.TestFindChild;
  576. // Find direct child schema with given name
  577. // function FindChild(const aName: String): TJSONSchema;
  578. var
  579. S,S2 : TJSONSchema;
  580. begin
  581. // Create child schema with given name
  582. // function CreateChildSchema(aName : string): TJsonSchema; overload;
  583. S2:=nil;
  584. S:=Schema.CreateChildSchema('x');
  585. try
  586. S2:=Schema.CreateChildSchema('y');
  587. AssertEquals('Count',2,Schema.ChildSchemaCount);
  588. AssertSame('Index',S,Schema.FindChild('x'));
  589. AssertSame('Index',S2,Schema.FindChild('y'));
  590. finally
  591. S.Free;
  592. S2.Free;
  593. end;
  594. AssertEquals('Count',0,Schema.ChildSchemaCount);
  595. end;
  596. procedure TTestSchema.TestPath;
  597. // Path till root schema.
  598. var
  599. S,S2 : TJSONSchema;
  600. begin
  601. // Create child schema with given name
  602. // function CreateChildSchema(aName : string): TJsonSchema; overload;
  603. S:=Schema.CreateChildSchema('x');
  604. try
  605. S2:=S.CreateChildSchema('y');
  606. AssertEquals('Path','#/x/y',S2.Path);
  607. finally
  608. S.Free;
  609. S2.Free;
  610. end;
  611. end;
  612. procedure TTestSchema.TestValidation;
  613. begin
  614. AssertNotNull('Have validation',Schema.Validations);
  615. AssertSame('Schema correct',Schema,Schema.Validations.Schema);
  616. Schema.Validations.Format:='uri';
  617. AssertTrue('Keyword passes through',Schema.HasKeywordData(jskFormat));
  618. end;
  619. procedure TTestSchema.TestMetaData;
  620. begin
  621. AssertNotNull('Have validation',Schema.Metadata);
  622. AssertSame('Schema correct',Schema,Schema.Metadata.Schema);
  623. Schema.Metadata.ReadOnly:=True;
  624. AssertTrue('Keyword passes through',Schema.HasKeywordData(jskReadOnly));
  625. end;
  626. procedure TTestSchema.CheckKeyword(aKeyword : TJSONSchemaKeyword);
  627. begin
  628. AssertTrue('Have Keyword '+aKeyword.AsString,Schema.HasKeywordData(aKeyword));
  629. AssertTrue('Schema constrained',Schema.MatchType=smConstrained);
  630. end;
  631. procedure TTestSchema.TestID;
  632. begin
  633. // ID of this schema
  634. Schema.ID:='https://json-schema.org/draft/2020-12/schema';
  635. CheckKeyword(jskID);
  636. end;
  637. procedure TTestSchema.TestSchema;
  638. begin
  639. // Identifier of used JSON schema
  640. Schema.Schema:='https://json-schema.org/draft/2020-12/schema';
  641. CheckKeyword(jskSchema);
  642. end;
  643. procedure TTestSchema.TestRef;
  644. begin
  645. // $ref
  646. Schema.Ref:='#/solo';
  647. CheckKeyword(jskRef);
  648. end;
  649. procedure TTestSchema.TestComment;
  650. begin
  651. // $comment
  652. Schema.Comment:=' A comment';
  653. CheckKeyword(jskComment);
  654. end;
  655. procedure TTestSchema.TestAnchor;
  656. begin
  657. // $anchor
  658. Schema.anchor:='#/ref/two';
  659. CheckKeyword(jskAnchor);
  660. end;
  661. procedure TTestSchema.TestDefs;
  662. begin
  663. // $defs
  664. // property Defs: TJSONSchemaList read FDefs;
  665. end;
  666. procedure TTestSchema.TestDynamicAnchor;
  667. begin
  668. // $dynamicAnchor
  669. Schema.DynamicAnchor:='#/ref/two';
  670. CheckKeyword(jskDynamicAnchor);
  671. end;
  672. procedure TTestSchema.TestDynamicRef;
  673. begin
  674. // $dynamicRef
  675. Schema.DynamicRef:='#/ref/two';
  676. CheckKeyword(jskDynamicRef);
  677. end;
  678. procedure TTestSchema.TestVocabulary;
  679. begin
  680. // $vocabulary
  681. Schema.Vocabulary.AddVocabulary('https://www.freepascal.org/').Enabled:=True;
  682. CheckKeyword(jskVocabulary);
  683. AssertEquals('Count',1,Schema.Vocabulary.Count);
  684. AssertEquals('URL','https://www.freepascal.org/',Schema.Vocabulary[0].URL);
  685. AssertEquals('Enabled',True,Schema.Vocabulary[0].Enabled);
  686. end;
  687. procedure TTestSchema.TestAllof;
  688. var
  689. S1,S2 : TJSONSchema;
  690. begin
  691. // allOf keyword
  692. S1:=Schema.AllOf.Add('x');
  693. CheckKeyword(jskAllOf);
  694. S2:=Schema.AllOf.Add('y');
  695. AssertEquals('Count',2,Schema.AllOf.Count);
  696. AssertSame('Item 0',S1,Schema.AllOf[0]);
  697. AssertSame('Item 1',S2,Schema.AllOf[1]);
  698. end;
  699. procedure TTestSchema.TestAnyOf;
  700. var
  701. S1,S2 : TJSONSchema;
  702. begin
  703. // anyOf keyword
  704. S1:=Schema.AnyOf.Add('x');
  705. CheckKeyword(jskAnyOf);
  706. S2:=Schema.AnyOf.Add('y');
  707. AssertEquals('Count',2,Schema.AnyOf.Count);
  708. AssertSame('Item 0',S1,Schema.AnyOf[0]);
  709. AssertSame('Item 1',S2,Schema.AnyOf[1]);
  710. end;
  711. procedure TTestSchema.TestOneOf;
  712. var
  713. S1,S2 : TJSONSchema;
  714. begin
  715. // oneOf keyword
  716. S1:=Schema.OneOf.Add('x');
  717. CheckKeyword(jskOneOf);
  718. S2:=Schema.oneOf.Add('y');
  719. AssertEquals('Count',2,Schema.OneOf.Count);
  720. AssertSame('Item 0',S1,Schema.OneOf[0]);
  721. AssertSame('Item 1',S2,Schema.OneOf[1]);
  722. end;
  723. procedure TTestSchema.TestNotSchema;
  724. begin
  725. // not keyword
  726. Schema.NotSchema.MatchType:=smAny;
  727. CheckKeyword(jskNot);
  728. end;
  729. procedure TTestSchema.TestIfSchema;
  730. begin
  731. // If keyword
  732. Schema.IfSchema.MatchType:=smAny;
  733. CheckKeyword(jskIf);
  734. end;
  735. procedure TTestSchema.TestThenSchema;
  736. begin
  737. // then keyword
  738. Schema.ThenSchema.MatchType:=smAny;
  739. CheckKeyword(jskThen);
  740. end;
  741. procedure TTestSchema.TestElseSchema;
  742. begin
  743. // else keyword
  744. Schema.ElseSchema.MatchType:=smAny;
  745. CheckKeyword(jskElse);
  746. end;
  747. procedure TTestSchema.TestProperties;
  748. begin
  749. // properties keyword
  750. // property Properties: TJsonSchemaList read FProperties;
  751. Schema.Properties.Add('name');
  752. CheckKeyword(jskProperties);
  753. end;
  754. procedure TTestSchema.TestItems;
  755. begin
  756. // Declared in draft 2020-12 as schema, but we keep it a List, so we can handle earlier drafts.
  757. Schema.Items.Add('name');
  758. CheckKeyword(jskItems);
  759. end;
  760. procedure TTestSchema.TestPrefixItems;
  761. begin
  762. // prefixItems keyword.
  763. Schema.prefixItems.Add('name');
  764. CheckKeyword(jskPrefixItems);
  765. end;
  766. procedure TTestSchema.TestPatternProperties;
  767. begin
  768. // patternProperties keyword
  769. Schema.PatternProperties.Add('ok').MatchType:=smAny;
  770. CheckKeyword(jskPatternProperties);
  771. end;
  772. procedure TTestSchema.TestPropertyNames;
  773. begin
  774. // propertyNames keyword
  775. Schema.PropertyNames.MatchType:=smAny;
  776. CheckKeyword(jskPropertyNames);
  777. end;
  778. procedure TTestSchema.TestAdditionalProperties;
  779. begin
  780. // additionalProperties keyword
  781. Schema.additionalProperties.MatchType:=smAny;
  782. CheckKeyword(jskAdditionalProperties);
  783. end;
  784. procedure TTestSchema.TestDependentSchemas;
  785. begin
  786. // dependentSchemas keyword
  787. Schema.dependentSchemas.Add('name');
  788. CheckKeyword(jskDependentSchemas);
  789. end;
  790. procedure TTestSchema.TestContains;
  791. begin
  792. // contains keyword
  793. Schema.PropertyNames.MatchType:=smAny;
  794. CheckKeyword(jskPropertyNames);
  795. end;
  796. procedure TTestSchema.TestUnevaluatedItems;
  797. begin
  798. // unevaluatedItems keyword
  799. Schema.unevaluatedItems.MatchType:=smAny;
  800. CheckKeyword(jskunevaluatedItems);
  801. end;
  802. procedure TTestSchema.TestUnevaluatedProperties;
  803. begin
  804. // unevaluatedProperties keyword
  805. Schema.unevaluatedProperties.MatchType:=smAny;
  806. CheckKeyword(jskUnevaluatedProperties);
  807. end;
  808. initialization
  809. RegisterTests([{TTestSchemaValue,}TTestMetadata,TTestSchemaValidations,TTestSchema]);
  810. end.