JsonTest.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. #include "json.h"
  2. #include <cppunit/extensions/HelperMacros.h>
  3. #include "RecoverableException.h"
  4. #include "util.h"
  5. #include "array_fun.h"
  6. #include "Base64.h"
  7. namespace aria2 {
  8. class JsonTest:public CppUnit::TestFixture {
  9. CPPUNIT_TEST_SUITE(JsonTest);
  10. CPPUNIT_TEST(testDecode);
  11. CPPUNIT_TEST(testDecode_error);
  12. CPPUNIT_TEST(testEncode);
  13. CPPUNIT_TEST(testDecodeGetParams);
  14. CPPUNIT_TEST_SUITE_END();
  15. private:
  16. public:
  17. void testDecode();
  18. void testDecode_error();
  19. void testEncode();
  20. void testDecodeGetParams();
  21. };
  22. CPPUNIT_TEST_SUITE_REGISTRATION( JsonTest );
  23. void JsonTest::testDecode()
  24. {
  25. {
  26. // empty object
  27. SharedHandle<ValueBase> r = json::decode("{}");
  28. const Dict* dict = asDict(r);
  29. CPPUNIT_ASSERT(dict);
  30. }
  31. {
  32. // empty object
  33. SharedHandle<ValueBase> r = json::decode("{ }");
  34. const Dict* dict = asDict(r);
  35. CPPUNIT_ASSERT(dict);
  36. }
  37. {
  38. // empty array
  39. SharedHandle<ValueBase> r = json::decode("[]");
  40. const List* list = asList(r);
  41. CPPUNIT_ASSERT(list);
  42. }
  43. {
  44. // empty array
  45. SharedHandle<ValueBase> r = json::decode("[ ]");
  46. const List* list = asList(r);
  47. CPPUNIT_ASSERT(list);
  48. }
  49. {
  50. // empty string
  51. SharedHandle<ValueBase> r = json::decode("[\"\"]");
  52. const List* list = asList(r);
  53. CPPUNIT_ASSERT(list);
  54. const String* s = asString(list->get(0));
  55. CPPUNIT_ASSERT_EQUAL(std::string(), s->s());
  56. }
  57. {
  58. // string
  59. SharedHandle<ValueBase> r = json::decode("[\"foobar\"]");
  60. const List* list = asList(r);
  61. CPPUNIT_ASSERT(list);
  62. const String* s = asString(list->get(0));
  63. CPPUNIT_ASSERT_EQUAL(std::string("foobar"), s->s());
  64. }
  65. {
  66. // string with escape
  67. SharedHandle<ValueBase> r = json::decode("[\"\\\\foo\\\"\\\"bar\"]");
  68. const List* list = asList(r);
  69. CPPUNIT_ASSERT(list);
  70. const String* s = asString(list->get(0));
  71. CPPUNIT_ASSERT_EQUAL(std::string("\\foo\"\"bar"), s->s());
  72. }
  73. {
  74. // string with escape
  75. SharedHandle<ValueBase> r = json::decode("[\"foo\\\"\"]");
  76. const List* list = asList(r);
  77. CPPUNIT_ASSERT(list);
  78. const String* s = asString(list->get(0));
  79. CPPUNIT_ASSERT_EQUAL(std::string("foo\""), s->s());
  80. }
  81. {
  82. // string: utf-8 1 to 3 bytes.
  83. SharedHandle<ValueBase> r = json::decode("[\"\\u0024\\u00A2\\u20AC\"]");
  84. const List* list = asList(r);
  85. CPPUNIT_ASSERT(list);
  86. const String* s = asString(list->get(0));
  87. CPPUNIT_ASSERT_EQUAL(std::string("$¢€"), s->s());
  88. }
  89. {
  90. // string: utf-8 4 bytes
  91. SharedHandle<ValueBase> r = json::decode("[\"\\uD852\\uDF62\"]");
  92. const List* list = asList(r);
  93. CPPUNIT_ASSERT(list);
  94. const String* s = asString(list->get(0));
  95. const char arr[] = { 0xF0u, 0xA4u, 0xADu, 0xA2u };
  96. CPPUNIT_ASSERT_EQUAL(std::string(vbegin(arr), vend(arr)), s->s());
  97. }
  98. {
  99. // null
  100. SharedHandle<ValueBase> r = json::decode("[null]");
  101. const List* list = asList(r);
  102. CPPUNIT_ASSERT(list);
  103. const Null* s = asNull(list->get(0));
  104. CPPUNIT_ASSERT(s);
  105. }
  106. {
  107. // true, false
  108. SharedHandle<ValueBase> r = json::decode("[true, false]");
  109. const List* list = asList(r);
  110. CPPUNIT_ASSERT(list);
  111. const Bool* trueValue = asBool(list->get(0));
  112. CPPUNIT_ASSERT(trueValue);
  113. CPPUNIT_ASSERT(trueValue->val());
  114. const Bool* falseValue = asBool(list->get(1));
  115. CPPUNIT_ASSERT(falseValue);
  116. CPPUNIT_ASSERT(!falseValue->val());
  117. }
  118. {
  119. // object: 1 member
  120. SharedHandle<ValueBase> r = json::decode("{\"foo\":[\"bar\"]}");
  121. const Dict* dict = asDict(r);
  122. CPPUNIT_ASSERT(dict);
  123. const List* list = asList(dict->get("foo"));
  124. CPPUNIT_ASSERT(list);
  125. const String* s = asString(list->get(0));
  126. CPPUNIT_ASSERT_EQUAL(std::string("bar"), s->s());
  127. }
  128. {
  129. // object: 2 members
  130. SharedHandle<ValueBase> r = json::decode("{\"\":[\"bar\"], "
  131. "\"alpha\" : \"bravo\"}");
  132. const Dict* dict = asDict(r);
  133. CPPUNIT_ASSERT(dict);
  134. const List* list = asList(dict->get(""));
  135. CPPUNIT_ASSERT(list);
  136. const String* s = asString(list->get(0));
  137. CPPUNIT_ASSERT_EQUAL(std::string("bar"), s->s());
  138. const String* str = asString(dict->get("alpha"));
  139. CPPUNIT_ASSERT_EQUAL(std::string("bravo"), str->s());
  140. }
  141. {
  142. // array: 2 values
  143. SharedHandle<ValueBase> r = json::decode("[\"foo\", {}]");
  144. const List* list = asList(r);
  145. CPPUNIT_ASSERT(list);
  146. const String* s = asString(list->get(0));
  147. CPPUNIT_ASSERT_EQUAL(std::string("foo"), s->s());
  148. const Dict* dict = asDict(list->get(1));
  149. CPPUNIT_ASSERT(dict);
  150. }
  151. {
  152. // Number: currently we handle floating point number as string
  153. SharedHandle<ValueBase> r = json::decode("[0,-1,1.2,-1.2e-10,-1e10]");
  154. const List* list = asList(r);
  155. CPPUNIT_ASSERT(list);
  156. const Integer* i = asInteger(list->get(0));
  157. CPPUNIT_ASSERT_EQUAL((Integer::ValueType)0, i->i());
  158. const Integer* i1 = asInteger(list->get(1));
  159. CPPUNIT_ASSERT_EQUAL((Integer::ValueType)-1, i1->i());
  160. const String* s2 = asString(list->get(2));
  161. CPPUNIT_ASSERT_EQUAL(std::string("1.2"), s2->s());
  162. const String* s3 = asString(list->get(3));
  163. CPPUNIT_ASSERT_EQUAL(std::string("-1.2e-10"), s3->s());
  164. const String* s4 = asString(list->get(4));
  165. CPPUNIT_ASSERT_EQUAL(std::string("-1e10"), s4->s());
  166. }
  167. }
  168. void JsonTest::testDecode_error()
  169. {
  170. {
  171. try {
  172. // object
  173. SharedHandle<ValueBase> r = json::decode("{");
  174. CPPUNIT_FAIL("exception must be thrown.");
  175. } catch(RecoverableException& e) {
  176. // success
  177. }
  178. }
  179. {
  180. try {
  181. // object
  182. SharedHandle<ValueBase> r = json::decode("}");
  183. CPPUNIT_FAIL("exception must be thrown.");
  184. } catch(RecoverableException& e) {
  185. // success
  186. }
  187. }
  188. {
  189. try {
  190. // object
  191. SharedHandle<ValueBase> r = json::decode("{\"\":");
  192. CPPUNIT_FAIL("exception must be thrown.");
  193. } catch(RecoverableException& e) {
  194. // success
  195. }
  196. }
  197. {
  198. try {
  199. // object
  200. SharedHandle<ValueBase> r = json::decode("{\"\":\"\",");
  201. CPPUNIT_FAIL("exception must be thrown.");
  202. } catch(RecoverableException& e) {
  203. // success
  204. }
  205. }
  206. {
  207. try {
  208. // array
  209. SharedHandle<ValueBase> r = json::decode("[");
  210. CPPUNIT_FAIL("exception must be thrown.");
  211. } catch(RecoverableException& e) {
  212. // success
  213. }
  214. }
  215. {
  216. try {
  217. // array
  218. SharedHandle<ValueBase> r = json::decode("]");
  219. CPPUNIT_FAIL("exception must be thrown.");
  220. } catch(RecoverableException& e) {
  221. // success
  222. }
  223. }
  224. {
  225. try {
  226. // array
  227. SharedHandle<ValueBase> r = json::decode("[\"\"");
  228. CPPUNIT_FAIL("exception must be thrown.");
  229. } catch(RecoverableException& e) {
  230. // success
  231. }
  232. }
  233. {
  234. try {
  235. // array
  236. SharedHandle<ValueBase> r = json::decode("[\"\",");
  237. CPPUNIT_FAIL("exception must be thrown.");
  238. } catch(RecoverableException& e) {
  239. // success
  240. }
  241. }
  242. {
  243. try {
  244. // string
  245. SharedHandle<ValueBase> r = json::decode("[\"foo]");
  246. CPPUNIT_FAIL("exception must be thrown.");
  247. } catch(RecoverableException& e) {
  248. // success
  249. }
  250. }
  251. {
  252. try {
  253. // string
  254. SharedHandle<ValueBase> r = json::decode("[\"\\u\"]");
  255. CPPUNIT_FAIL("exception must be thrown.");
  256. } catch(RecoverableException& e) {
  257. // success
  258. }
  259. }
  260. {
  261. try {
  262. // string
  263. SharedHandle<ValueBase> r = json::decode("[\"\\u");
  264. CPPUNIT_FAIL("exception must be thrown.");
  265. } catch(RecoverableException& e) {
  266. // success
  267. }
  268. }
  269. {
  270. try {
  271. // string
  272. SharedHandle<ValueBase> r = json::decode("[\"\\u000\"]");
  273. CPPUNIT_FAIL("exception must be thrown.");
  274. } catch(RecoverableException& e) {
  275. // success
  276. }
  277. }
  278. {
  279. try {
  280. // string
  281. SharedHandle<ValueBase> r = json::decode("[\"\\u000");
  282. CPPUNIT_FAIL("exception must be thrown.");
  283. } catch(RecoverableException& e) {
  284. // success
  285. }
  286. }
  287. {
  288. try {
  289. // string
  290. SharedHandle<ValueBase> r = json::decode("[\"\\uD852foo\"]");
  291. CPPUNIT_FAIL("exception must be thrown.");
  292. } catch(RecoverableException& e) {
  293. // success
  294. }
  295. }
  296. {
  297. try {
  298. // string
  299. SharedHandle<ValueBase> r = json::decode("[\"\\uD852");
  300. CPPUNIT_FAIL("exception must be thrown.");
  301. } catch(RecoverableException& e) {
  302. // success
  303. }
  304. }
  305. {
  306. try {
  307. // string
  308. SharedHandle<ValueBase> r = json::decode("[\"\\uD852\\u\"]");
  309. CPPUNIT_FAIL("exception must be thrown.");
  310. } catch(RecoverableException& e) {
  311. // success
  312. }
  313. }
  314. {
  315. try {
  316. // string
  317. SharedHandle<ValueBase> r = json::decode("[\"\\uD852\\u");
  318. CPPUNIT_FAIL("exception must be thrown.");
  319. } catch(RecoverableException& e) {
  320. // success
  321. }
  322. }
  323. {
  324. try {
  325. // string
  326. SharedHandle<ValueBase> r = json::decode("[\"\\uD852\\u0000\"]");
  327. CPPUNIT_FAIL("exception must be thrown.");
  328. } catch(RecoverableException& e) {
  329. // success
  330. }
  331. }
  332. {
  333. try {
  334. // string
  335. SharedHandle<ValueBase> r = json::decode("[\"\\uD852\\uDF62");
  336. CPPUNIT_FAIL("exception must be thrown.");
  337. } catch(RecoverableException& e) {
  338. // success
  339. }
  340. }
  341. {
  342. try {
  343. // object
  344. SharedHandle<ValueBase> r = json::decode("{:\"\"}");
  345. CPPUNIT_FAIL("exception must be thrown.");
  346. } catch(RecoverableException& e) {
  347. // success
  348. }
  349. }
  350. {
  351. try {
  352. // object
  353. SharedHandle<ValueBase> r = json::decode("{\"foo\":}");
  354. CPPUNIT_FAIL("exception must be thrown.");
  355. } catch(RecoverableException& e) {
  356. // success
  357. }
  358. }
  359. {
  360. try {
  361. // number
  362. SharedHandle<ValueBase> r = json::decode("{00}");
  363. CPPUNIT_FAIL("exception must be thrown.");
  364. } catch(RecoverableException& e) {
  365. // success
  366. }
  367. }
  368. {
  369. try {
  370. // number
  371. SharedHandle<ValueBase> r = json::decode("{1.}");
  372. CPPUNIT_FAIL("exception must be thrown.");
  373. } catch(RecoverableException& e) {
  374. // success
  375. }
  376. }
  377. {
  378. try {
  379. // number
  380. SharedHandle<ValueBase> r = json::decode("{1.1e}");
  381. CPPUNIT_FAIL("exception must be thrown.");
  382. } catch(RecoverableException& e) {
  383. // success
  384. }
  385. }
  386. {
  387. try {
  388. // bool
  389. SharedHandle<ValueBase> r = json::decode("{t");
  390. CPPUNIT_FAIL("exception must be thrown.");
  391. } catch(RecoverableException& e) {
  392. // success
  393. }
  394. }
  395. }
  396. void JsonTest::testEncode()
  397. {
  398. {
  399. Dict dict;
  400. dict["name"] = String::g("aria2");
  401. dict["loc"] = Integer::g(80000);
  402. SharedHandle<List> files = List::g();
  403. files->append(String::g("aria2c"));
  404. dict["files"] = files;
  405. SharedHandle<Dict> attrs = Dict::g();
  406. attrs->put("license", String::g("GPL"));
  407. dict["attrs"] = attrs;
  408. CPPUNIT_ASSERT_EQUAL(std::string("{\"attrs\":{\"license\":\"GPL\"},"
  409. "\"files\":[\"aria2c\"],"
  410. "\"loc\":80000,"
  411. "\"name\":\"aria2\"}"),
  412. json::encode(&dict));
  413. }
  414. {
  415. List list;
  416. list.append("\"\\/\b\f\n\r\t");
  417. CPPUNIT_ASSERT_EQUAL(std::string("[\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"]"),
  418. json::encode(&list));
  419. }
  420. {
  421. List list;
  422. std::string s;
  423. s += 0x1Fu;
  424. list.append(s);
  425. CPPUNIT_ASSERT_EQUAL(std::string("[\"\\u001F\"]"),
  426. json::encode(&list));
  427. }
  428. {
  429. List list;
  430. list.append(Bool::gTrue());
  431. list.append(Bool::gFalse());
  432. list.append(Null::g());
  433. CPPUNIT_ASSERT_EQUAL(std::string("[true,false,null]"),
  434. json::encode(&list));
  435. }
  436. }
  437. void JsonTest::testDecodeGetParams()
  438. {
  439. {
  440. std::string param = util::percentEncode(Base64::encode("[1,2,3]"));
  441. std::string query = "?params=";
  442. query += param;
  443. query += '&';
  444. query += "method=sum&";
  445. query += "id=300&";
  446. query += "jsoncallback=cb";
  447. json::JsonGetParam gparam = json::decodeGetParams(query);
  448. CPPUNIT_ASSERT_EQUAL(std::string("{\"method\":\"sum\","
  449. "\"id\":\"300\","
  450. "\"params\":[1,2,3]}"),
  451. gparam.request);
  452. CPPUNIT_ASSERT_EQUAL(std::string("cb"), gparam.callback);
  453. }
  454. {
  455. std::string query = "?params=";
  456. query += util::percentEncode(Base64::encode("[{}]"));
  457. query += '&';
  458. query += "jsoncallback=cb";
  459. json::JsonGetParam gparam = json::decodeGetParams(query);
  460. CPPUNIT_ASSERT_EQUAL(std::string("[{}]"), gparam.request);
  461. CPPUNIT_ASSERT_EQUAL(std::string("cb"), gparam.callback);
  462. }
  463. }
  464. } // namespace aria2