utSchemaValidator.pp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. {
  2. This file is part of the Free Component Library
  3. Testsuite for JSONSchema validator
  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 utSchemaValidator;
  12. {$mode ObjFPC}{$H+}
  13. interface
  14. uses
  15. Classes, SysUtils, fpcunit, testregistry, fpjson, fpjson.schema.types, fpjson.schema.schema, fpjson.schema.validator,
  16. fpjson.schema.testutils;
  17. Type
  18. { TTestSchemaValidator }
  19. TTestSchemaValidator = Class(TSchemaTestCase)
  20. private
  21. FSchema: TJSONSchema;
  22. FValidator: TJSONSchemaValidator;
  23. function AddPrefixItem(aType: TSchemaSimpleType): TJSONSchema;
  24. Public
  25. Procedure SetUp; override;
  26. Procedure TearDown; override;
  27. Procedure AssertValid(const Msg : String;aJSON : TJSONData);
  28. Procedure AssertValid(const Msg : String;aJSON : TJSONStringType);
  29. Procedure AssertInValid(const Msg : String;aJSON : TJSONData);
  30. Procedure AssertInValid(const Msg : String;aJSON : TJSONStringType);
  31. Procedure SetSchemaJSON(const aJSON : TJSONStringType);
  32. Property Validator : TJSONSchemaValidator Read FValidator;
  33. Property Schema : TJSONSchema Read FSchema;
  34. Published
  35. Procedure TestHookup;
  36. Procedure TestAny;
  37. Procedure TestNone;
  38. procedure TestTypeString;
  39. procedure TestTypeInteger;
  40. procedure TestTypeBoolean;
  41. procedure TestTypeNumber;
  42. procedure TestTypeNull;
  43. procedure TestTypeObject;
  44. procedure TestTypeArray;
  45. procedure TestTypes;
  46. procedure TestConstString;
  47. procedure TestConstBoolean;
  48. procedure TestConstInteger;
  49. procedure TestConstArray;
  50. procedure TestConstObject;
  51. Procedure TestNumericMinimum;
  52. Procedure TestNumericExclusiveMinimum;
  53. Procedure TestNumericMaximum;
  54. Procedure TestNumericExclusiveMaximum;
  55. Procedure TestNumericMultipleOf;
  56. Procedure TestStringMinLength;
  57. Procedure TestStringMaxLength;
  58. Procedure TestStringPattern;
  59. procedure TestEnum;
  60. Procedure TestArrayMinItems;
  61. Procedure TestArrayMaxItems;
  62. Procedure TestArrayContains;
  63. Procedure TestArrayMinContains;
  64. Procedure TestArrayMaxContains;
  65. Procedure TestArrayPrefixItems;
  66. procedure TestArrayItems;
  67. procedure TestArrayItemsPrefixItems;
  68. procedure TestArrayUniqueItems;
  69. procedure TestObjectMinProperties;
  70. procedure TestObjectMaxProperties;
  71. procedure TestObjectRequired;
  72. procedure TestObjectDependentRequired;
  73. procedure TestObjectProperties;
  74. Procedure TestIfThen;
  75. Procedure TestIfElse;
  76. Procedure TestAnyOf;
  77. Procedure TestAllOf;
  78. Procedure TestOneOf;
  79. Procedure TestNot;
  80. Procedure TestRef;
  81. end;
  82. implementation
  83. uses fpjson.schema.reader;
  84. Const
  85. SJSONNull = 'null';
  86. SJSONString1 = '"foo"';
  87. SJSONString2 = '"bar"';
  88. SJSONInteger = '42';
  89. SJSONFloat = '3.1415';
  90. SJSONBool = 'true';
  91. SJSONBoolFalse = 'false';
  92. SJSONArray1 = '['+SJSONString1+']';
  93. SJSONArray1a = '['+SJSONString1+','+SJSONString2+']';
  94. SJSONArray2 = '['+SJSONString1+','+SJSONInteger+']';
  95. SJSONArray3 = '['+SJSONString1+','+SJSONInteger+','+SJSONFloat+']';
  96. SJSONArrayNull = '['+SJSONString1+','+SJSONInteger+','+SJSONNull+']';
  97. SJSONArrayOnlyNull3 = '['+SJSONNull+','+SJSONNull+','+SJSONNull+']';
  98. SJSONArrayOnlyNull2 = '['+SJSONNull+','+SJSONNull+']';
  99. SJSONArrayOnlyNull1 = '['+SJSONNull+']';
  100. SJSONArrayEmpty = '[]';
  101. SJSONArray2Nulls = '['+SJSONString1+','+SJSONInteger+','+SJSONNull+','+SJSONNull+']';
  102. SJSONArray3Nulls = '['+SJSONString1+','+SJSONInteger+','+SJSONNull+','+SJSONNull+','+SJSONNull+']';
  103. SJSONArray2NullsA = '['+SJSONString1+','+SJSONInteger+','+SJSONNull+','+SJSONNull+','+SJSONInteger+']';
  104. SJSONObjectEmpty = '{}';
  105. SJSONObject1 = '{"one":"foo"}';
  106. SJSONObject2 = '{"one":"foo","two":"bar"}';
  107. SJSONObject3 = '{"one":"foo","two":"bar","count":42}';
  108. SEmailPattern = '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$';
  109. { TTestSchemaValidator }
  110. procedure TTestSchemaValidator.SetUp;
  111. begin
  112. inherited SetUp;
  113. FValidator:=TJSONSchemaValidator.Create(Nil);
  114. FSchema:=TJSONSchema.Create;
  115. end;
  116. procedure TTestSchemaValidator.TearDown;
  117. begin
  118. FreeAndNil(FValidator);
  119. FreeAndNil(FSchema);
  120. inherited TearDown;
  121. end;
  122. procedure TTestSchemaValidator.AssertValid(const Msg : String;aJSON: TJSONStringType);
  123. var
  124. D : TJSONData;
  125. begin
  126. D:=GetJSON(aJSON,True);
  127. try
  128. AssertValid(Msg,D);
  129. finally
  130. D.Free;
  131. end;
  132. end;
  133. procedure TTestSchemaValidator.AssertInValid(const Msg: String; aJSON: TJSONStringType);
  134. var
  135. D : TJSONData;
  136. begin
  137. D:=GetJSON(aJSON,True);
  138. try
  139. AssertInValid(Msg,D);
  140. finally
  141. D.Free;
  142. end;
  143. end;
  144. procedure TTestSchemaValidator.SetSchemaJSON(const aJSON: TJSONStringType);
  145. var
  146. aReader : TJsonSchemaReader;
  147. begin
  148. aReader:=TJsonSchemaReader.Create(Nil);
  149. try
  150. aReader.ReadFromString(Schema,aJSON);
  151. finally
  152. aReader.Free;
  153. end;
  154. end;
  155. procedure TTestSchemaValidator.AssertInValid(const Msg: String; aJSON: TJSONData);
  156. begin
  157. FValidator.Reset;
  158. AssertFalse(Msg,FValidator.ValidateJSON(aJSON,Schema));
  159. end;
  160. procedure TTestSchemaValidator.TestHookup;
  161. begin
  162. AssertNotNull('Schema',Schema);
  163. AssertNotNull('Validator',Validator);
  164. AssertEquals('Validator empty',0,Validator.Messages.Count);
  165. end;
  166. procedure TTestSchemaValidator.TestAny;
  167. begin
  168. Schema.MatchType:=smAny;
  169. AssertValid('String',SJSONString1);
  170. AssertValid('Integer',SJSONInteger);
  171. AssertValid('Float',SJSONFloat);
  172. AssertValid('Boolean',SJSONBool);
  173. AssertValid('Boolean',SJSONBoolFalse);
  174. AssertValid('Null',SJSONNull);
  175. AssertValid('Array',SJSONArray1);
  176. AssertValid('Array3',SJSONArray3);
  177. AssertValid('Object',SJSONObject1);
  178. end;
  179. procedure TTestSchemaValidator.TestNone;
  180. begin
  181. Schema.MatchType:=smNone;
  182. AssertInvalid('String',SJSONString1);
  183. AssertInvalid('Integer',SJSONInteger);
  184. AssertInvalid('Float',SJSONFloat);
  185. AssertInvalid('Boolean',SJSONBool);
  186. AssertInvalid('Null',SJSONNull);
  187. AssertInvalid('Array',SJSONArray2);
  188. AssertInvalid('Object',SJSONObject2);
  189. end;
  190. procedure TTestSchemaValidator.TestTypeString;
  191. begin
  192. Schema.Validations.Types:=[sstString];
  193. AssertValid('String',SJSONString1);
  194. AssertInvalid('Integer',SJSONInteger);
  195. AssertInvalid('Float',SJSONFloat);
  196. AssertInvalid('Boolean',SJSONBool);
  197. AssertInvalid('Null',SJSONNull);
  198. AssertInvalid('Array',SJSONArray2);
  199. AssertInvalid('Object',SJSONObject2);
  200. end;
  201. procedure TTestSchemaValidator.TestTypeInteger;
  202. begin
  203. Schema.Validations.Types:=[sstInteger];
  204. Assertvalid('Integer',SJSONInteger);
  205. AssertInValid('String',SJSONString1);
  206. AssertInvalid('Float',SJSONFloat);
  207. AssertInvalid('Boolean',SJSONBool);
  208. AssertInvalid('Null',SJSONNull);
  209. AssertInvalid('Array',SJSONArray2);
  210. AssertInvalid('Object',SJSONObject2);
  211. end;
  212. procedure TTestSchemaValidator.TestTypeBoolean;
  213. begin
  214. Schema.Validations.Types:=[sstBoolean];
  215. AssertValid('Boolean',SJSONBool);
  216. AssertValid('False Boolean',SJSONBoolFalse);
  217. AssertInvalid('Integer',SJSONInteger);
  218. AssertInValid('String',SJSONString1);
  219. AssertInvalid('Float',SJSONFloat);
  220. AssertInvalid('Null',SJSONNull);
  221. AssertInvalid('Array',SJSONArray2);
  222. AssertInvalid('Object',SJSONObject2);
  223. end;
  224. procedure TTestSchemaValidator.TestTypeNumber;
  225. begin
  226. Schema.Validations.Types:=[sstNumber];
  227. AssertValid('Integer',SJSONInteger);
  228. AssertValid('Float',SJSONFloat);
  229. AssertInvalid('Boolean',SJSONBool);
  230. AssertInValid('String',SJSONString1);
  231. AssertInvalid('Null',SJSONNull);
  232. AssertInvalid('Array',SJSONArray2);
  233. AssertInvalid('Object',SJSONObject2);
  234. end;
  235. procedure TTestSchemaValidator.TestTypeNull;
  236. begin
  237. Schema.Validations.Types:=[sstNull];
  238. AssertValid('Null',SJSONNull);
  239. AssertInvalid('Integer',SJSONInteger);
  240. AssertInvalid('Float',SJSONFloat);
  241. AssertInvalid('Boolean',SJSONBool);
  242. AssertInValid('String',SJSONString1);
  243. AssertInvalid('Array',SJSONArray2);
  244. AssertInvalid('Object',SJSONObject2);
  245. end;
  246. procedure TTestSchemaValidator.TestTypeObject;
  247. begin
  248. Schema.Validations.Types:=[sstObject];
  249. AssertValid('Object',SJSONObject2);
  250. AssertValid('Object 1',SJSONObject1);
  251. AssertInvalid('Null',SJSONNull);
  252. AssertInvalid('Integer',SJSONInteger);
  253. AssertInvalid('Float',SJSONFloat);
  254. AssertInvalid('Boolean',SJSONBool);
  255. AssertInValid('String',SJSONString1);
  256. AssertInvalid('Array',SJSONArray2);
  257. end;
  258. procedure TTestSchemaValidator.TestTypeArray;
  259. begin
  260. Schema.Validations.Types:=[sstArray];
  261. AssertValid('Array 1',SJSONArray1);
  262. AssertValid('Array 2',SJSONArray2);
  263. AssertInvalid('Object',SJSONObject1);
  264. AssertInvalid('Null',SJSONNull);
  265. AssertInvalid('Integer',SJSONInteger);
  266. AssertInvalid('Float',SJSONFloat);
  267. AssertInvalid('Boolean',SJSONBool);
  268. AssertInValid('String',SJSONString1);
  269. end;
  270. procedure TTestSchemaValidator.TestTypes;
  271. begin
  272. Schema.Validations.Types:=[sstArray,sstObject];
  273. AssertValid('Array1',SJSONArray1);
  274. Assertvalid('Object',SJSONObject1);
  275. end;
  276. procedure TTestSchemaValidator.TestConstString;
  277. begin
  278. Schema.Validations.constValue:=TJSONString.Create('foo');
  279. AssertValid('Same String',SJSONString1);
  280. AssertInValid('Different String',SJSONString2);
  281. AssertInValid('Different type','1');
  282. end;
  283. procedure TTestSchemaValidator.TestConstBoolean;
  284. begin
  285. Schema.Validations.constValue:=TJSONBoolean.Create(true);
  286. AssertValid('Same value',SJSONBool);
  287. AssertInValid('Different value',SJSONBoolFalse);
  288. AssertInValid('Different type','1');
  289. end;
  290. procedure TTestSchemaValidator.TestConstInteger;
  291. begin
  292. Schema.Validations.constValue:=TJSONBoolean.Create(true);
  293. AssertValid('Same value',SJSONBool);
  294. AssertInValid('Different value',SJSONBoolFalse);
  295. AssertInValid('Different type','1');
  296. AssertInValid('String with correct value','"true"');
  297. end;
  298. procedure TTestSchemaValidator.TestConstArray;
  299. begin
  300. Schema.Validations.constValue:=TJSONArray.Create([1,2,3]);
  301. AssertValid('Same value','[1,2,3]');
  302. AssertInValid('Different value','[1,3,2]');
  303. AssertInValid('Different type','1');
  304. AssertInValid('String with correct value','"[1,2,3]"');
  305. end;
  306. procedure TTestSchemaValidator.TestConstObject;
  307. begin
  308. Schema.Validations.constValue:=TJSONObject.Create(['one',1,'two',2,'three',3]);
  309. AssertValid('Same value',Schema.Validations.constValue.AsJson);
  310. AssertInValid('Different value','{"one":1,"two":3,"three":2}');
  311. AssertInValid('Different type','1');
  312. AssertInValid('String with correct value','"{\"one\":1,\"two\":3,\"three\":2}"');
  313. end;
  314. procedure TTestSchemaValidator.TestNumericMinimum;
  315. begin
  316. Schema.Validations.Types:=[sstNumber];
  317. Schema.Validations.Minimum:=1;
  318. AssertValid('OK',SJSONFloat);
  319. AssertInValid('NOK','0.5');
  320. AssertValid('Limit OK','1');
  321. end;
  322. procedure TTestSchemaValidator.TestNumericExclusiveMinimum;
  323. begin
  324. Schema.Validations.Types:=[sstNumber];
  325. Schema.Validations.ExclusiveMinimum:=1;
  326. AssertValid('OK',SJSONFloat);
  327. AssertInValid('NOK','0.5');
  328. AssertInValid('Limit NOK','1');
  329. end;
  330. procedure TTestSchemaValidator.TestNumericMaximum;
  331. begin
  332. Schema.Validations.Types:=[sstNumber];
  333. Schema.Validations.Maximum:=10;
  334. AssertValid('OK',SJSONFloat);
  335. AssertInValid('NOK','15');
  336. AssertValid('Limit OK','10');
  337. end;
  338. procedure TTestSchemaValidator.TestNumericExclusiveMaximum;
  339. begin
  340. Schema.Validations.Types:=[sstNumber];
  341. Schema.Validations.ExclusiveMaximum:=10;
  342. AssertValid('OK',SJSONFloat);
  343. AssertInValid('NOK','15');
  344. AssertInValid('Limit OK','10');
  345. end;
  346. procedure TTestSchemaValidator.TestNumericMultipleOf;
  347. begin
  348. Schema.Validations.Types:=[sstNumber];
  349. Schema.Validations.MultipleOf:=10;
  350. AssertValid('OK','100');
  351. AssertInValid('NOK','15');
  352. AssertValid('Limit OK','10');
  353. AssertValid('0','0');
  354. AssertValid('Float integer','10.000');
  355. end;
  356. procedure TTestSchemaValidator.TestStringMinLength;
  357. begin
  358. Schema.Validations.Types:=[sstString];
  359. Schema.Validations.MinLength:=10;
  360. AssertValid('Limit OK','"0123456789"');
  361. AssertInValid('NOK','"123456789"');
  362. AssertValid('OK','"01234567890"');
  363. end;
  364. procedure TTestSchemaValidator.TestStringMaxLength;
  365. begin
  366. Schema.Validations.Types:=[sstString];
  367. Schema.Validations.MaxLength:=10;
  368. AssertValid('Limit OK','"0123456789"');
  369. AssertInValid('NOK','"01234567890"');
  370. AssertValid('OK','"123456789"');
  371. end;
  372. procedure TTestSchemaValidator.TestStringPattern;
  373. begin
  374. Schema.Validations.Types:=[sstString];
  375. Schema.Validations.Pattern:=SEmailPattern;
  376. AssertValid('Email','"[email protected]"');
  377. AssertInValid('Email 2','"michael@freepascal"');
  378. end;
  379. procedure TTestSchemaValidator.TestEnum;
  380. begin
  381. Schema.Validations.Enum:=TJSONArray.Create([True,'something']);
  382. AssertValid('Boolean','true');
  383. AssertValid('String','"something"');
  384. AssertInValid('String with boolean','"true"');
  385. AssertInValid('Numerical','123');
  386. end;
  387. procedure TTestSchemaValidator.TestArrayMinItems;
  388. begin
  389. Schema.Validations.Types:=[sstArray];
  390. Schema.Validations.MinItems:=2;
  391. AssertValid('2',SJSONArray1a);
  392. AssertValid('2a',SJSONArray2);
  393. AssertValid('3',SJSONArray2);
  394. AssertInValid('1',SJSONArray1);
  395. end;
  396. procedure TTestSchemaValidator.TestArrayMaxItems;
  397. begin
  398. Schema.Validations.Types:=[sstArray];
  399. Schema.Validations.MaxItems:=2;
  400. AssertValid('1',SJSONArray1);
  401. AssertValid('2',SJSONArray1a);
  402. AssertValid('2a',SJSONArray2);
  403. AssertInValid('3',SJSONArray3);
  404. end;
  405. procedure TTestSchemaValidator.TestArrayContains;
  406. begin
  407. Schema.Validations.Types:=[sstArray];
  408. Schema.Contains.Validations.Types:=[sstNull];
  409. AssertValid('1',SJSONArrayNull);
  410. end;
  411. procedure TTestSchemaValidator.TestArrayMinContains;
  412. begin
  413. Schema.Validations.Types:=[sstArray];
  414. Schema.Validations.MinContains:=2;
  415. Schema.Contains.Validations.Types:=[sstNull];
  416. AssertValid('2',SJSONArray2Nulls);
  417. AssertValid('3',SJSONArray3Nulls);
  418. AssertInValid('1',SJSONArrayNull);
  419. end;
  420. procedure TTestSchemaValidator.TestArrayMaxContains;
  421. begin
  422. Schema.Validations.Types:=[sstArray];
  423. Schema.Validations.MaxContains:=2;
  424. Schema.Contains.Validations.Types:=[sstNull];
  425. AssertValid('2',SJSONArray2Nulls);
  426. AssertValid('1',SJSONArrayNull);
  427. AssertInValid('3',SJSONArray3Nulls);
  428. end;
  429. function TTestSchemaValidator.AddPrefixItem(aType : TSchemaSimpleType) : TJSONSchema;
  430. begin
  431. Result:=Schema.CreateChildSchema;
  432. Result.Validations.Types:=[aType];
  433. Schema.PrefixItems.Add(Result);
  434. end;
  435. procedure TTestSchemaValidator.TestArrayPrefixItems;
  436. begin
  437. Schema.Validations.Types:=[sstArray];
  438. AddPrefixItem(sstString);
  439. AddPrefixItem(sstInteger);
  440. AssertValid('Less elements OK',SJSONArray1);
  441. AssertValid('Exact elements OK',SJSONArray2);
  442. AssertValid('More elements OK',SJSONArrayNull);
  443. AssertInValid('2nd element not OK',SJSONArray1a);
  444. end;
  445. procedure TTestSchemaValidator.TestArrayItems;
  446. var
  447. SS : TJSONSchema;
  448. begin
  449. Schema.Validations.Types:=[sstArray];
  450. SS:=Schema.CreateChildSchema;
  451. SS.Validations.Types:=[sstNull];
  452. Schema.Items.Add(SS);
  453. AssertValid('Empty OK',SJSONArrayEmpty);
  454. AssertValid('One OK',SJSONArrayOnlyNull1);
  455. AssertValid('Two OK',SJSONArrayOnlyNull2);
  456. AssertValid('Three OK',SJSONArrayOnlyNull3);
  457. AssertInValid('None NOK',SJSONArray1a);
  458. AssertInValid('One with others NOK',SJSONArrayNull);
  459. end;
  460. procedure TTestSchemaValidator.TestArrayItemsPrefixItems;
  461. var
  462. SS : TJSONSchema;
  463. begin
  464. Schema.Validations.Types:=[sstArray];
  465. AddPrefixItem(sstString);
  466. AddPrefixItem(sstInteger);
  467. SS:=Schema.CreateChildSchema;
  468. SS.Validations.Types:=[sstNull];
  469. Schema.Items.Add(SS);
  470. AssertValid('Empty OK',SJSONArrayEmpty);
  471. AssertValid('Less elements OK',SJSONArray1);
  472. AssertValid('Exact elements OK',SJSONArray2);
  473. AssertValid('More Prefix elements OK',SJSONArrayNull);
  474. AssertInValid('Has some but then again not',SJSONArray2NullsA);
  475. AssertInValid('Immediate NOK',SJSONArray3);
  476. AssertInValid('Two OK',SJSONArrayOnlyNull2);
  477. AssertInValid('Three OK',SJSONArrayOnlyNull3);
  478. AssertInValid('One OK',SJSONArrayOnlyNull1);
  479. AssertInValid('None NOK',SJSONArray1a);
  480. end;
  481. procedure TTestSchemaValidator.TestArrayUniqueItems;
  482. begin
  483. Schema.Validations.Types:=[sstArray];
  484. Schema.Validations.UniqueItems:=True;
  485. AssertValid('Empty OK',SJSONArrayEmpty);
  486. AssertValid('One element OK',SJSONArrayOnlyNull1);
  487. AssertValid('Different elements OK',SJSONArray3);
  488. AssertInValid('2 elements OK',SJSONArrayOnlyNull2);
  489. AssertInValid('3 elements OK',SJSONArrayOnlyNull3);
  490. end;
  491. procedure TTestSchemaValidator.TestObjectMinProperties;
  492. begin
  493. Schema.Validations.Types:=[sstObject];
  494. Schema.Validations.MinProperties:=1;
  495. AssertValid('1 ok',SJSONObject1);
  496. AssertValid('2 ok',SJSONObject2);
  497. AssertValid('3 ok',SJSONObject3);
  498. AssertInvalid('0 not ok',SJSONObjectEmpty);
  499. Schema.Validations.MinProperties:=3;
  500. AssertInValid('Min 3, 2 not ok',SJSONObject2);
  501. end;
  502. procedure TTestSchemaValidator.TestObjectMaxProperties;
  503. begin
  504. Schema.Validations.Types:=[sstObject];
  505. Schema.Validations.MaxProperties:=1;
  506. Assertvalid('0 not ok',SJSONObjectEmpty);
  507. AssertValid('1 ok',SJSONObject1);
  508. AssertInValid('2 not ok',SJSONObject2);
  509. AssertInValid('3 not ok',SJSONObject3);
  510. Schema.Validations.MaxProperties:=2;
  511. AssertInValid('Max 2, 3 not ok',SJSONObject3);
  512. end;
  513. procedure TTestSchemaValidator.TestObjectRequired;
  514. begin
  515. Schema.Validations.Types:=[sstObject];
  516. Schema.Validations.Required.Add('one');
  517. AssertValid('1 ok',SJSONObject1);
  518. AssertValid('2 ok',SJSONObject2);
  519. AssertInValid('0 nok',SJSONObjectEmpty);
  520. Schema.Validations.Required.Add('two');
  521. AssertValid('2 ok',SJSONObject2);
  522. AssertValid('3 ok',SJSONObject3);
  523. AssertInValid('1 ok',SJSONObject1);
  524. end;
  525. procedure TTestSchemaValidator.TestObjectDependentRequired;
  526. begin
  527. Schema.Validations.Types:=[sstObject];
  528. Schema.Validations.DependentRequired.AddDependent('one').Required.Add('two');
  529. AssertValid('Empty ok',SJSONObjectEmpty);
  530. AssertValid('Req ok',SJSONObject2);
  531. AssertValid('Extra ok',SJSONObject3);
  532. AssertInvalid('Missing not ok',SJSONObject1);
  533. Schema.Validations.DependentRequired.AddDependent('two').Required.Add('count');
  534. AssertValid('Extra ok',SJSONObject3);
  535. AssertInValid('Req missin nok',SJSONObject2);
  536. end;
  537. procedure TTestSchemaValidator.TestObjectProperties;
  538. var
  539. SS : TJSONSchema;
  540. begin
  541. Schema.Validations.Types:=[sstObject];
  542. SS:=Schema.CreateChildSchema('one');
  543. SS.Validations.types:=[sstString];
  544. Schema.Properties.Add(SS);
  545. SS:=Schema.CreateChildSchema('two');
  546. SS.Validations.types:=[sstString];
  547. Schema.Properties.Add(SS);
  548. end;
  549. procedure TTestSchemaValidator.TestIfThen;
  550. begin
  551. Schema.IfSchema.Validations.Types:=[sstString];
  552. Schema.ThenSchema.Validations.constValue:=TJSONString.Create('something');
  553. AssertValid('Correct then','"something"');
  554. AssertValid('no else OK','true');
  555. AssertInValid('Incorrect then','"solo"');
  556. end;
  557. procedure TTestSchemaValidator.TestIfElse;
  558. begin
  559. Schema.IfSchema.Validations.Types:=[sstString];
  560. Schema.ElseSchema.Validations.constValue:=TJSONIntegerNumber.Create(12);
  561. AssertValid('No then OK','"something"');
  562. AssertValid('Correct else','12');
  563. AssertInValid('Incorrect else','24');
  564. end;
  565. procedure TTestSchemaValidator.TestAnyOf;
  566. var
  567. SS : TJSONSchema;
  568. begin
  569. SS:=Schema.CreateChildSchema;
  570. SS.Validations.Types:=[sstString];
  571. Schema.AnyOf.Add(SS);
  572. SS:=Schema.CreateChildSchema;
  573. SS.Validations.Types:=[sstNumber];
  574. Schema.AnyOf.Add(SS);
  575. AssertValid('String ','"something"');
  576. AssertValid('Number','12');
  577. AssertInValid('Boolean','false');
  578. end;
  579. procedure TTestSchemaValidator.TestAllOf;
  580. var
  581. SS : TJSONSchema;
  582. begin
  583. SS:=Schema.CreateChildSchema;
  584. SS.Validations.Types:=[sstString];
  585. Schema.AllOf.Add(SS);
  586. SS:=Schema.CreateChildSchema;
  587. SS.Validations.constValue:=TJSONString.Create('something');
  588. Schema.AllOf.Add(SS);
  589. AssertValid('String ','"something"');
  590. AssertInvalid('String ','"else"');
  591. AssertInValid('Number','12');
  592. AssertInValid('Boolean','false');
  593. end;
  594. procedure TTestSchemaValidator.TestOneOf;
  595. var
  596. SS : TJSONSchema;
  597. begin
  598. SS:=Schema.CreateChildSchema;
  599. SS.Validations.Types:=[sstString];
  600. Schema.OneOf.Add(SS);
  601. SS:=Schema.CreateChildSchema;
  602. SS.Validations.constValue:=TJSONString.Create('something');
  603. Schema.OneOf.Add(SS);
  604. AssertValid('Different String ','"else"'); //
  605. AssertInValid('String ','"something"');
  606. AssertInValid('Number','12');
  607. AssertInValid('Boolean','false');
  608. end;
  609. procedure TTestSchemaValidator.TestNot;
  610. begin
  611. Schema.NotSchema.Validations.Types:=[sstString];
  612. AssertInValid('String not OK','"something"');
  613. AssertValid('Number Correct','12');
  614. AssertValid('Boolean Correct','false');
  615. end;
  616. procedure TTestSchemaValidator.TestRef;
  617. begin
  618. Schema.Validations.Types:=[sstObject];
  619. Schema.Properties.Add('productId').Validations.Types:=[sstInteger];
  620. Schema.Properties.Add('name').Ref:='#/$defs/string';
  621. with Schema.Defs.Add('string') do
  622. begin
  623. id:='string';
  624. Validations.types:=[sstString];
  625. end;
  626. AssertValid('Correct ref','{ "productId": 123, "name" : "Widget" }');
  627. end;
  628. procedure TTestSchemaValidator.AssertValid(const Msg: String; aJSON: TJSONData);
  629. begin
  630. FValidator.Reset;
  631. AssertTrue(Msg,FValidator.ValidateJSON(aJSON,Schema));
  632. end;
  633. initialization
  634. RegisterTest(TTestSchemaValidator);
  635. end.