utcjson.pas 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. unit utcjson;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, fpcunit, testutils, testregistry, System.JSON;
  6. type
  7. { TTestJSONObject }
  8. TTestJSONObject= class(TTestCase)
  9. private
  10. FPair: TJSONPair;
  11. FValue: TJSONValue;
  12. protected
  13. procedure SetUp; override;
  14. procedure TearDown; override;
  15. Property Value : TJSONValue Read FValue Write FValue;
  16. Property Pair : TJSONPair Read FPair Write FPair;
  17. published
  18. procedure TestHookUp;
  19. Procedure TestNull;
  20. Procedure TestParseNull;
  21. Procedure TestBoolean;
  22. Procedure TestParseBoolean;
  23. Procedure TestBoolTrue;
  24. Procedure TestParseBoolTrue;
  25. Procedure TestBoolFalse;
  26. Procedure TestParseBoolFalse;
  27. Procedure TestString;
  28. Procedure TestStringNull;
  29. Procedure TestParseString;
  30. Procedure TestNumberInt;
  31. Procedure TestParseNumberInt;
  32. Procedure TestNumberInt64;
  33. Procedure TestParseNumberInt64;
  34. Procedure TestNumberFloat;
  35. Procedure TestParseNumberFloat;
  36. Procedure TestJSONPairPair;
  37. Procedure TestJSONPairStringString;
  38. Procedure TestJSONPairStringValue;
  39. Procedure TestJSONPairStringInt;
  40. Procedure TestJSONPairStringBool;
  41. Procedure TestJSONPairStringFloat;
  42. Procedure TestJSONPairStringInt64;
  43. Procedure TestJSONObjectEmpty;
  44. Procedure TestJSONObjectOneElement;
  45. Procedure TestJSONObjectTwoElements;
  46. Procedure TestJSONParseObjectEmpty;
  47. Procedure TestJSONParseObjectOneElement;
  48. Procedure TestJSONParseObjectTwoElements;
  49. Procedure TestJSONArrayEmpty;
  50. Procedure TestJSONArrayOneElement;
  51. Procedure TestJSONArrayTwoElements;
  52. Procedure TestFindEmptyValue;
  53. Procedure TestFindObjectName;
  54. Procedure TestFindObjectIndexName;
  55. Procedure TestFindObjectNameRecurse;
  56. Procedure TestFindArrayIndex;
  57. Procedure TestFindArrayName;
  58. Procedure TestAsType;
  59. procedure TestGetValue;
  60. procedure TestTryGetValue;
  61. end;
  62. { TTestJSONPathParser }
  63. TTestJSONPathParser = class(TTestCase)
  64. private
  65. FParser: TJSONPathParser;
  66. protected
  67. procedure SetUp; override;
  68. procedure TearDown; override;
  69. Procedure AssertEquals(Msg : string; aExpected, aActual : TJSONPathToken); overload;
  70. Property Parser : TJSONPathParser Read FParser;
  71. published
  72. Procedure TestHookup;
  73. Procedure TestEof;
  74. Procedure TestName;
  75. Procedure TestIndexNumeric;
  76. Procedure TestIndexName;
  77. Procedure TestDotName;
  78. end;
  79. implementation
  80. uses typinfo;
  81. procedure TTestJSONObject.TestHookUp;
  82. begin
  83. AssertNull('No value',value);
  84. end;
  85. procedure TTestJSONObject.TestNull;
  86. begin
  87. Value:=TJSONNull.Create;
  88. AssertEquals('ToString','null',Value.ToString);
  89. AssertEquals('ToJSON','null',Value.ToJSON);
  90. AssertEquals('Format','null',Value.Format);
  91. AssertEquals('Null',True,Value.Null);
  92. end;
  93. procedure TTestJSONObject.TestParseNull;
  94. begin
  95. Value:=TJSONValue.ParseJSONValue('null');
  96. AssertEquals('Class',TJSONNull,Value.ClassType);
  97. end;
  98. procedure TTestJSONObject.TestBoolean;
  99. begin
  100. Value:=TJSONBool.Create(True);
  101. AssertEquals('ToString','true',Value.ToString);
  102. AssertEquals('ToJSON','true',Value.ToJSON);
  103. AssertEquals('Format','true',Value.Format);
  104. AssertEquals('Null',False,Value.Null);
  105. end;
  106. procedure TTestJSONObject.TestParseBoolean;
  107. begin
  108. Value:=TJSONValue.ParseJSONValue('true',False);
  109. AssertEquals('Class',TJSONBool,Value.ClassType);
  110. AssertEquals('ToString','true',Value.ToString);
  111. end;
  112. procedure TTestJSONObject.TestBoolTrue;
  113. begin
  114. Value:=TJSONTrue.Create;
  115. AssertEquals('ToString','true',Value.ToString);
  116. AssertEquals('ToJSON','true',Value.ToJSON);
  117. AssertEquals('Format','true',Value.Format);
  118. AssertEquals('Null',False,Value.Null);
  119. end;
  120. procedure TTestJSONObject.TestParseBoolTrue;
  121. begin
  122. Value:=TJSONValue.ParseJSONValue('true',True);
  123. AssertEquals('Class',TJSONTrue,Value.ClassType);
  124. AssertEquals('ToString','true',Value.ToString);
  125. end;
  126. procedure TTestJSONObject.TestBoolFalse;
  127. begin
  128. Value:=TJSONfalse.Create;
  129. AssertEquals('ToString','false',Value.ToString);
  130. AssertEquals('ToJSON','false',Value.ToJSON);
  131. AssertEquals('Format','false',Value.Format);
  132. AssertEquals('Null',False,Value.Null);
  133. end;
  134. procedure TTestJSONObject.TestParseBoolFalse;
  135. begin
  136. Value:=TJSONValue.ParseJSONValue('false',True);
  137. AssertEquals('Class',TJSONFalse,Value.ClassType);
  138. AssertEquals('ToString','false',Value.ToString);
  139. end;
  140. procedure TTestJSONObject.TestString;
  141. begin
  142. Value:=TJSONString.Create('string');
  143. AssertEquals('ToString','"string"',Value.ToString);
  144. AssertEquals('ToJSON','"string"',Value.ToJSON);
  145. AssertEquals('Format','"string"',Value.Format);
  146. AssertEquals('Null',False,Value.Null);
  147. end;
  148. procedure TTestJSONObject.TestStringNull;
  149. begin
  150. Value:=TJSONString.Create();
  151. AssertEquals('ToString','null',Value.ToString);
  152. AssertEquals('Null',True,Value.Null);
  153. end;
  154. procedure TTestJSONObject.TestParseString;
  155. begin
  156. Value:=TJSONValue.ParseJSONValue('"string"',True);
  157. AssertEquals('Class',TJSONString,Value.ClassType);
  158. AssertEquals('ToString','"string"',Value.ToString);
  159. end;
  160. procedure TTestJSONObject.TestNumberInt;
  161. begin
  162. Value:=TJSONNumber.Create(12);
  163. AssertEquals('ToString','12',Value.ToString);
  164. AssertEquals('ToJSON','12',Value.ToJSON);
  165. AssertEquals('Format','12',Value.Format);
  166. AssertEquals('Null',False,Value.Null);
  167. end;
  168. procedure TTestJSONObject.TestParseNumberInt;
  169. begin
  170. Value:=TJSONValue.ParseJSONValue('12',True);
  171. AssertEquals('Class',TJSONNumber,Value.ClassType);
  172. AssertEquals('ToString','12',Value.ToString);
  173. end;
  174. procedure TTestJSONObject.TestNumberInt64;
  175. begin
  176. Value:=TJSONNumber.Create(Int64(12));
  177. AssertEquals('ToString','12',Value.ToString);
  178. AssertEquals('ToJSON','12',Value.ToJSON);
  179. AssertEquals('Format','12',Value.Format);
  180. AssertEquals('Null',False,Value.Null);
  181. end;
  182. procedure TTestJSONObject.TestParseNumberInt64;
  183. begin
  184. Value:=TJSONValue.ParseJSONValue('1221212121111',True);
  185. AssertEquals('Class',TJSONNumber,Value.ClassType);
  186. AssertEquals('ToString','1221212121111',Value.ToString);
  187. end;
  188. procedure TTestJSONObject.TestNumberFloat;
  189. var
  190. V : String;
  191. begin
  192. V:=FloatToStr(12.34,TFormatSettings.Invariant);
  193. Value:=TJSONNumber.Create(12.34);
  194. AssertEquals('ToString',V,Value.ToString);
  195. AssertEquals('ToJSON',V,Value.ToJSON);
  196. AssertEquals('Format',V,Value.Format);
  197. AssertEquals('Null',False,Value.Null);
  198. end;
  199. procedure TTestJSONObject.TestParseNumberFloat;
  200. var
  201. V : String;
  202. begin
  203. V:=FloatToStr(12.34,TFormatSettings.Invariant);
  204. Value:=TJSONValue.ParseJSONValue('12.34',True);
  205. AssertEquals('Class',TJSONNumber,Value.ClassType);
  206. AssertEquals('ToString',V,Value.ToString);
  207. end;
  208. procedure TTestJSONObject.TestJSONPairPair;
  209. begin
  210. Pair:=TJSONPair.Create(TJSONString.Create('a'),TJSONNumber.Create('12'));
  211. AssertEquals('ToString','"a":12',Pair.ToString);
  212. AssertEquals('ToJSON','"a":12',Pair.ToJSON);
  213. AssertEquals('Format','"a":12',Pair.Format);
  214. AssertEquals('Null',False,Pair.Null);
  215. end;
  216. procedure TTestJSONObject.TestJSONPairStringString;
  217. begin
  218. Pair:=TJSONPair.Create('a','b');
  219. AssertEquals('ToString','"a":"b"',Pair.ToString);
  220. AssertEquals('ToJSON','"a":"b"',Pair.ToJSON);
  221. AssertEquals('Format','"a":"b"',Pair.Format);
  222. AssertEquals('Null',False,Pair.Null);
  223. end;
  224. procedure TTestJSONObject.TestJSONPairStringValue;
  225. begin
  226. Pair:=TJSONPair.Create('a',TJSONString.Create('b'));
  227. AssertEquals('ToString','"a":"b"',Pair.ToString);
  228. AssertEquals('ToJSON','"a":"b"',Pair.ToJSON);
  229. AssertEquals('Format','"a":"b"',Pair.Format);
  230. AssertEquals('Null',False,Pair.Null);
  231. end;
  232. procedure TTestJSONObject.TestJSONPairStringInt;
  233. begin
  234. Pair:=TJSONPair.Create('a',1);
  235. AssertEquals('ToString','"a":1',Pair.ToString);
  236. AssertEquals('ToJSON','"a":1',Pair.ToJSON);
  237. AssertEquals('Format','"a":1',Pair.Format);
  238. AssertEquals('Null',False,Pair.Null);
  239. end;
  240. procedure TTestJSONObject.TestJSONPairStringBool;
  241. begin
  242. Pair:=TJSONPair.Create('a',True);
  243. AssertEquals('ToString','"a":true',Pair.ToString);
  244. AssertEquals('ToJSON','"a":true',Pair.ToJSON);
  245. AssertEquals('Format','"a":true',Pair.Format);
  246. AssertEquals('Null',False,Pair.Null);
  247. end;
  248. procedure TTestJSONObject.TestJSONPairStringFloat;
  249. var
  250. V : String;
  251. begin
  252. V:=FloatToStr(12.34,TFormatSettings.Invariant);
  253. Pair:=TJSONPair.Create('a',12.34);
  254. AssertEquals('ToString','"a":'+V,Pair.ToString);
  255. AssertEquals('ToJSON','"a":'+V,Pair.ToJSON);
  256. AssertEquals('Format','"a":'+V,Pair.Format);
  257. AssertEquals('Null',False,Pair.Null);
  258. end;
  259. procedure TTestJSONObject.TestJSONPairStringInt64;
  260. begin
  261. Pair:=TJSONPair.Create('a',1221212121111);
  262. AssertEquals('ToString','"a":1221212121111',Pair.ToString);
  263. AssertEquals('ToJSON','"a":1221212121111',Pair.ToJSON);
  264. AssertEquals('Format','"a":1221212121111',Pair.Format);
  265. AssertEquals('Null',False,Pair.Null);
  266. end;
  267. procedure TTestJSONObject.TestJSONObjectEmpty;
  268. begin
  269. Value:=TJSONObject.Create;
  270. AssertEquals('ToString','{}',Value.ToString);
  271. AssertEquals('ToJSON','{}',Value.ToJSON);
  272. AssertEquals('Format','{'+sLineBreak+'}',Value.Format);
  273. AssertEquals('Null',False,Value.Null);
  274. end;
  275. procedure TTestJSONObject.TestJSONObjectOneElement;
  276. begin
  277. Value:=TJSONObject.Create(TJSONPair.Create('a','b'));
  278. AssertEquals('ToString','{"a":"b"}',Value.ToString);
  279. AssertEquals('ToJSON','{"a":"b"}',Value.ToJSON);
  280. AssertEquals('Format','{'+sLineBreak+' "a":"b"'+sLineBreak+'}',Value.Format);
  281. AssertEquals('Null',False,Value.Null);
  282. end;
  283. procedure TTestJSONObject.TestJSONObjectTwoElements;
  284. var
  285. O : TJSONObject;
  286. begin
  287. O:=TJSONObject.Create(TJSONPair.Create('a','b'));
  288. O.AddPair('c','d');
  289. AssertEquals('Count',2,O.Count);
  290. Value:=O;
  291. AssertEquals('ToString','{"a":"b","c":"d"}',Value.ToString);
  292. AssertEquals('ToJSON','{"a":"b","c":"d"}',Value.ToJSON);
  293. AssertEquals('Format','{'+sLineBreak+
  294. ' "a":"b",'+sLineBreak+
  295. ' "c":"d"'+sLineBreak+'}',Value.Format);
  296. AssertEquals('Null',False,Value.Null);
  297. end;
  298. procedure TTestJSONObject.TestJSONParseObjectEmpty;
  299. begin
  300. Value:=TJSONValue.ParseJSONValue('{}',True);
  301. AssertEquals('Class',TJSONObject,Value.ClassType);
  302. AssertEquals('ToString','{}',Value.ToString);
  303. end;
  304. procedure TTestJSONObject.TestJSONParseObjectOneElement;
  305. begin
  306. Value:=TJSONValue.ParseJSONValue('{"a":"b"}',True);
  307. AssertEquals('Class',TJSONObject,Value.ClassType);
  308. AssertEquals('ToString','{"a":"b"}',Value.ToString);
  309. end;
  310. procedure TTestJSONObject.TestJSONParseObjectTwoElements;
  311. begin
  312. Value:=TJSONValue.ParseJSONValue('{"a":"b","c":"d"}',True);
  313. AssertEquals('Class',TJSONObject,Value.ClassType);
  314. AssertEquals('ToString','{"a":"b","c":"d"}',Value.ToString);
  315. end;
  316. procedure TTestJSONObject.TestJSONArrayEmpty;
  317. begin
  318. Value:=TJSONArray.Create;
  319. AssertEquals('ToString','[]',Value.ToString);
  320. AssertEquals('ToJSON','[]',Value.ToJSON);
  321. AssertEquals('Format','['+sLineBreak+']',Value.Format);
  322. AssertEquals('Null',False,Value.Null);
  323. end;
  324. procedure TTestJSONObject.TestJSONArrayOneElement;
  325. begin
  326. Value:=TJSONArray.Create(TJSONNumber.Create(1));
  327. AssertEquals('ToString','[1]',Value.ToString);
  328. AssertEquals('ToJSON','[1]',Value.ToJSON);
  329. AssertEquals('Format','['+sLineBreak+' 1'+sLineBreak+']',Value.Format);
  330. AssertEquals('Null',False,Value.Null);
  331. end;
  332. procedure TTestJSONObject.TestJSONArrayTwoElements;
  333. begin
  334. Value:=TJSONArray.Create(TJSONNumber.Create(1),TJSONNumber.Create(2));
  335. AssertEquals('ToString','[1,2]',Value.ToString);
  336. AssertEquals('ToJSON','[1,2]',Value.ToJSON);
  337. AssertEquals('Format','['+sLineBreak+
  338. ' 1,'+sLineBreak+
  339. ' 2'+sLineBreak+
  340. ']',Value.Format);
  341. AssertEquals('Null',False,Value.Null);
  342. end;
  343. procedure TTestJSONObject.TestFindEmptyValue;
  344. begin
  345. FValue:=TJSONString.Create('Name');
  346. AssertSame('Empty returns same',FValue,FValue.FindValue(''));
  347. end;
  348. procedure TTestJSONObject.TestFindObjectName;
  349. var
  350. V : TJSONValue;
  351. begin
  352. FValue:=TJSONObject.Create(TJSONPair.Create('a','b'));
  353. V:=FValue.FindValue('a');
  354. AssertNotNull('Have JSON value',V);
  355. AssertEquals('Have correct value','b',V.Value);
  356. V:=FValue.FindValue('c');
  357. AssertNull('Have no JSON value',V);
  358. end;
  359. procedure TTestJSONObject.TestFindObjectIndexName;
  360. var
  361. V : TJSONValue;
  362. begin
  363. FValue:=TJSONObject.Create(TJSONPair.Create('a','b'));
  364. V:=FValue.FindValue('["a"]');
  365. AssertNotNull('Have JSON value',V);
  366. AssertEquals('Have correct value','b',V.Value);
  367. V:=FValue.FindValue('c');
  368. AssertNull('Have no JSON value',V);
  369. end;
  370. procedure TTestJSONObject.TestFindObjectNameRecurse;
  371. var
  372. V : TJSONValue;
  373. begin
  374. V:=TJSONObject.Create(TJSONPair.Create('b','c'));
  375. FValue:=TJSONObject.Create(TJSONPair.Create('a',v));
  376. V:=FValue.FindValue('a.b');
  377. AssertNotNull('Have JSON value',V);
  378. AssertEquals('Have correct value','c',V.Value);
  379. V:=FValue.FindValue('a.c');
  380. AssertNull('Have no JSON value',V);
  381. end;
  382. procedure TTestJSONObject.TestFindArrayIndex;
  383. var
  384. V : TJSONValue;
  385. begin
  386. FValue:=TJSONArray.Create('a','b');
  387. V:=FValue.FindValue('[0]');
  388. AssertNotNull('Have JSON value',V);
  389. AssertEquals('Have correct value','a',V.Value);
  390. V:=FValue.FindValue('[1]');
  391. AssertNotNull('Have JSON value',V);
  392. AssertEquals('Have correct value','b',V.Value);
  393. V:=FValue.FindValue('[-1]');
  394. AssertNull('Have no JSON value -1',V);
  395. V:=FValue.FindValue('[2]');
  396. AssertNull('Have no JSON value 2',V);
  397. end;
  398. procedure TTestJSONObject.TestFindArrayName;
  399. var
  400. V : TJSONValue;
  401. begin
  402. FValue:=TJSONArray.Create('a','b');
  403. V:=FValue.FindValue('a');
  404. AssertNull('Have no JSON value',V);
  405. end;
  406. procedure TTestJSONObject.TestAsType;
  407. begin
  408. Value:=TJSONObject.ParseJSONValue('{ "a" : "b" }');
  409. AssertEquals('Correct class',TJSONObject.ClassName,(Value.specialize AsType<TJSONObject>()).ClassName);
  410. end;
  411. procedure TTestJSONObject.TestGetValue;
  412. begin
  413. Value:=TJSONObject.ParseJSONValue('{ "a" : "b" }');
  414. AssertEquals('Correct value','b',Value. specialize GetValue<String>('a'));
  415. end;
  416. procedure TTestJSONObject.TestTryGetValue;
  417. var
  418. S : String;
  419. begin
  420. Value:=TJSONObject.ParseJSONValue('{ "a" : "b" }');
  421. AssertTrue('Can get value', Value. specialize TryGetValue<String>('a',S));
  422. AssertEquals('Correct value','b',S);
  423. end;
  424. (*
  425. {$mode objfpc}
  426. {$h+}
  427. var
  428. V : TJSONValue;
  429. S : String;
  430. begin
  431. V:=TJSONObject.ParseJSONValue('{ "a" : "b" }');
  432. Writeln(V.specialize TryGetValue<String>('a',S));
  433. Writeln(S);
  434. Writeln(V.specialize GetValue<String>('a'));
  435. *)
  436. procedure TTestJSONObject.SetUp;
  437. begin
  438. FreeAndNil(Fvalue);
  439. FreeAndNil(FPair);
  440. end;
  441. procedure TTestJSONObject.TearDown;
  442. begin
  443. FreeAndNil(FPair);
  444. FreeAndNil(Fvalue);
  445. end;
  446. { TTestJSONPathParser }
  447. procedure TTestJSONPathParser.SetUp;
  448. begin
  449. inherited SetUp;
  450. FParser:=Default(TJSONPathParser);
  451. end;
  452. procedure TTestJSONPathParser.TearDown;
  453. begin
  454. FParser:=Default(TJSONPathParser);
  455. inherited TearDown;
  456. end;
  457. procedure TTestJSONPathParser.AssertEquals(Msg: string; aExpected, aActual: TJSONPathToken);
  458. begin
  459. AssertEquals(Msg,GetEnumName(TypeInfo(TJSONPathParser.TToken),Ord(aExpected)),
  460. GetEnumName(TypeInfo(TJSONPathParser.TToken),Ord(aActual)));
  461. end;
  462. procedure TTestJSONPathParser.TestHookup;
  463. begin
  464. AssertEquals('Default', TJSONPathToken.UnDefined, FParser.Token);
  465. end;
  466. procedure TTestJSONPathParser.TestEof;
  467. begin
  468. FParser:=TJSONPathParser.Create('');
  469. AssertEquals('Empty is eof ',TJSONPathToken.Eof,FParser.NextToken);
  470. AssertTrue('eof',FParser.IsEOF);
  471. end;
  472. procedure TTestJSONPathParser.TestName;
  473. begin
  474. FParser:=TJSONPathParser.Create('name');
  475. AssertEquals('Type',TJSONPathToken.Name,FParser.NextToken);
  476. AssertEquals('Value','name',FParser.TokenName);
  477. AssertTrue('eof',FParser.IsEOF);
  478. end;
  479. procedure TTestJSONPathParser.TestIndexNumeric;
  480. begin
  481. FParser:=TJSONPathParser.Create('[12]');
  482. AssertEquals('Type',TJSONPathToken.ArrayIndex,FParser.NextToken);
  483. AssertEquals('Value',12,FParser.TokenArrayIndex);
  484. AssertTrue('eof',FParser.IsEOF);
  485. end;
  486. procedure TTestJSONPathParser.TestIndexName;
  487. begin
  488. FParser:=TJSONPathParser.Create('["name"]');
  489. AssertEquals('Type',TJSONPathToken.name,FParser.NextToken);
  490. AssertEquals('Value','name',FParser.TokenName);
  491. AssertTrue('eof',FParser.IsEOF);
  492. end;
  493. procedure TTestJSONPathParser.TestDotName;
  494. begin
  495. FParser:=TJSONPathParser.Create('.name');
  496. AssertEquals('Type',TJSONPathToken.Name,FParser.NextToken);
  497. AssertEquals('Value','name',FParser.TokenName);
  498. AssertTrue('eof',FParser.IsEOF);
  499. end;
  500. initialization
  501. RegisterTests([TTestJSONObject,TTestJSONPathParser]);
  502. end.