data_unittests.cc 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340
  1. // Copyright (C) 2009-2017 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #include <gtest/gtest.h>
  7. #include <boost/foreach.hpp>
  8. #include <boost/pointer_cast.hpp>
  9. #include <boost/assign/std/vector.hpp>
  10. #include <climits>
  11. #include <cc/data.h>
  12. #include <util/unittests/check_valgrind.h>
  13. using namespace isc::data;
  14. #include <sstream>
  15. #include <iostream>
  16. using std::oct;
  17. #include <iomanip>
  18. using std::setfill;
  19. using std::setw;
  20. using std::string;
  21. namespace {
  22. TEST(Position, str) {
  23. Element::Position position("kea.conf", 30, 20);
  24. EXPECT_EQ("kea.conf:30:20", position.str());
  25. Element::Position position2("another.conf", 123, 24);
  26. EXPECT_EQ("another.conf:123:24", position2.str());
  27. }
  28. TEST(Element, type) {
  29. // this tests checks whether the getType() function returns the
  30. // correct type
  31. IntElement int_el = IntElement(1);
  32. EXPECT_EQ(int_el.getType(), Element::integer);
  33. DoubleElement double_el = DoubleElement(1.0);
  34. EXPECT_EQ(double_el.getType(), Element::real);
  35. BoolElement bool_el = BoolElement(true);
  36. EXPECT_EQ(bool_el.getType(), Element::boolean);
  37. StringElement str_el = StringElement("foo");
  38. EXPECT_EQ(str_el.getType(), Element::string);
  39. ListElement list_el = ListElement();
  40. EXPECT_EQ(list_el.getType(), Element::list);
  41. MapElement map_el = MapElement();
  42. EXPECT_EQ(map_el.getType(), Element::map);
  43. }
  44. TEST(Element, TypeNameConversion) {
  45. EXPECT_EQ(Element::integer, Element::nameToType("integer"));
  46. EXPECT_EQ(Element::real, Element::nameToType("real"));
  47. EXPECT_EQ(Element::boolean, Element::nameToType("boolean"));
  48. EXPECT_EQ(Element::string, Element::nameToType("string"));
  49. EXPECT_EQ(Element::list, Element::nameToType("list"));
  50. EXPECT_EQ(Element::map, Element::nameToType("map"));
  51. EXPECT_EQ(Element::null, Element::nameToType("null"));
  52. EXPECT_EQ(Element::any, Element::nameToType("any"));
  53. EXPECT_THROW(Element::nameToType("somethingunknown"), TypeError);
  54. EXPECT_EQ("integer", Element::typeToName(Element::integer));
  55. EXPECT_EQ("real", Element::typeToName(Element::real));
  56. EXPECT_EQ("boolean", Element::typeToName(Element::boolean));
  57. EXPECT_EQ("string", Element::typeToName(Element::string));
  58. EXPECT_EQ("list", Element::typeToName(Element::list));
  59. EXPECT_EQ("map", Element::typeToName(Element::map));
  60. EXPECT_EQ("null", Element::typeToName(Element::null));
  61. EXPECT_EQ("any", Element::typeToName(Element::any));
  62. EXPECT_EQ("unknown", Element::typeToName((Element::types)123));
  63. }
  64. TEST(Element, from_and_to_json) {
  65. // a set of inputs that are the same when converted to json and
  66. // back to a string (tests for inputs that have equivalent, but
  67. // different string representations when converted back are below)
  68. ConstElementPtr el;
  69. std::vector<std::string> sv;
  70. sv.push_back("12");
  71. sv.push_back("1.1");
  72. sv.push_back("true");
  73. sv.push_back("false");
  74. sv.push_back("\"asdf\"");
  75. sv.push_back("null");
  76. sv.push_back("[ 1, 2, 3, 4 ]");
  77. sv.push_back("{ \"name\": \"foo\", \"value\": 56176 }");
  78. sv.push_back("[ { \"a\": 1, \"b\": \"c\" }, { \"a\": 2, \"b\": \"d\" } ]");
  79. sv.push_back("8.23");
  80. sv.push_back("123.456");
  81. sv.push_back("null");
  82. sv.push_back("-1");
  83. sv.push_back("-1.234");
  84. sv.push_back("-123.456");
  85. // We should confirm that our string handling is 8-bit clean.
  86. // At one point we were using char-length data and comparing to EOF,
  87. // which means that character '\xFF' would not parse properly.
  88. sv.push_back("\"\xFF\"");
  89. BOOST_FOREACH(const std::string& s, sv) {
  90. // Test two types of fromJSON(): with string and istream.
  91. for (unsigned i = 0; i < 2; ++i) {
  92. // test << operator, which uses Element::str()
  93. if (i == 0) {
  94. el = Element::fromJSON(s);
  95. } else {
  96. std::istringstream iss(s);
  97. el = Element::fromJSON(iss);
  98. }
  99. std::ostringstream stream;
  100. stream << *el;
  101. EXPECT_EQ(s, stream.str());
  102. // test toWire(ostream), which should also be the same now
  103. std::ostringstream wire_stream;
  104. el->toWire(wire_stream);
  105. EXPECT_EQ(s, wire_stream.str());
  106. }
  107. }
  108. // some parse errors
  109. try {
  110. Element::fromJSON("{1}");
  111. } catch (const isc::data::JSONError& pe) {
  112. std::string s = std::string(pe.what());
  113. EXPECT_EQ("String expected in <string>:1:3", s);
  114. }
  115. sv.clear();
  116. sv.push_back("{1}");
  117. //ElementPtr ep = Element::fromJSON("\"aaa\nbbb\"err");
  118. //std::cout << ep << std::endl;
  119. sv.push_back("\n\nTrue");
  120. sv.push_back("\n\ntru");
  121. sv.push_back("{ \n \"aaa\nbbb\"err:");
  122. sv.push_back("{ \t\n \"aaa\nbbb\"\t\n\n:\n true, \"\\\"");
  123. sv.push_back("{ \"a\": None}");
  124. sv.push_back("");
  125. sv.push_back("NULL");
  126. sv.push_back("nul");
  127. sv.push_back("hello\"foobar\"");
  128. sv.push_back("\"foobar\"hello");
  129. sv.push_back("[]hello");
  130. sv.push_back("{}hello");
  131. // String not delimited correctly
  132. sv.push_back("\"hello");
  133. sv.push_back("hello\"");
  134. BOOST_FOREACH(std::string s, sv) {
  135. EXPECT_THROW(el = Element::fromJSON(s), isc::data::JSONError);
  136. }
  137. // some json specific format tests, here the str() output is
  138. // different from the string input
  139. EXPECT_EQ("100", Element::fromJSON("+100")->str());
  140. EXPECT_EQ("100", Element::fromJSON("1e2")->str());
  141. EXPECT_EQ("100", Element::fromJSON("+1e2")->str());
  142. EXPECT_EQ("-100", Element::fromJSON("-1e2")->str());
  143. EXPECT_NO_THROW({
  144. EXPECT_EQ("9223372036854775807", Element::fromJSON("9223372036854775807")->str());
  145. });
  146. EXPECT_NO_THROW({
  147. EXPECT_EQ("-9223372036854775808", Element::fromJSON("-9223372036854775808")->str());
  148. });
  149. EXPECT_THROW({
  150. EXPECT_NE("9223372036854775808", Element::fromJSON("9223372036854775808")->str());
  151. }, JSONError);
  152. EXPECT_EQ("0.01", Element::fromJSON("1e-2")->str());
  153. EXPECT_EQ("0.01", Element::fromJSON(".01")->str());
  154. EXPECT_EQ("-0.01", Element::fromJSON("-1e-2")->str());
  155. EXPECT_EQ("1.2", Element::fromJSON("1.2")->str());
  156. EXPECT_EQ("1", Element::fromJSON("1.0")->str());
  157. EXPECT_EQ("120", Element::fromJSON("1.2e2")->str());
  158. EXPECT_EQ("100", Element::fromJSON("1.0e2")->str());
  159. EXPECT_EQ("100", Element::fromJSON("1.0E2")->str());
  160. EXPECT_EQ("0.01", Element::fromJSON("1.0e-2")->str());
  161. EXPECT_EQ("0.012", Element::fromJSON("1.2e-2")->str());
  162. EXPECT_EQ("0.012", Element::fromJSON("1.2E-2")->str());
  163. EXPECT_EQ("\"\"", Element::fromJSON(" \n \t \r \f \b \"\" \n \f \t \r \b")->str());
  164. EXPECT_EQ("{ }", Element::fromJSON("{ \n \r \t \b \f }")->str());
  165. EXPECT_EQ("[ ]", Element::fromJSON("[ \n \r \f \t \b ]")->str());
  166. // number overflows
  167. EXPECT_THROW(Element::fromJSON("12345678901234567890")->str(), JSONError);
  168. EXPECT_THROW(Element::fromJSON("1.1e12345678901234567890")->str(), JSONError);
  169. EXPECT_THROW(Element::fromJSON("-1.1e12345678901234567890")->str(), JSONError);
  170. EXPECT_THROW(Element::fromJSON("1e12345678901234567890")->str(), JSONError);
  171. EXPECT_THROW(Element::fromJSON("1e50000")->str(), JSONError);
  172. // number underflow
  173. // EXPECT_THROW(Element::fromJSON("1.1e-12345678901234567890")->str(), JSONError);
  174. }
  175. template <typename T>
  176. void
  177. testGetValueInt() {
  178. T el;
  179. int64_t i;
  180. int32_t i32;
  181. long l;
  182. long long ll;
  183. double d;
  184. bool b;
  185. std::string s;
  186. std::vector<ElementPtr> v;
  187. std::map<std::string, ConstElementPtr> m;
  188. el = Element::create(1);
  189. EXPECT_NO_THROW({
  190. EXPECT_EQ(1, el->intValue());
  191. });
  192. EXPECT_THROW(el->doubleValue(), TypeError);
  193. EXPECT_THROW(el->boolValue(), TypeError);
  194. EXPECT_THROW(el->stringValue(), TypeError);
  195. EXPECT_THROW(el->listValue(), TypeError);
  196. EXPECT_THROW(el->mapValue(), TypeError);
  197. EXPECT_TRUE(el->getValue(i));
  198. EXPECT_FALSE(el->getValue(d));
  199. EXPECT_FALSE(el->getValue(b));
  200. EXPECT_FALSE(el->getValue(s));
  201. EXPECT_FALSE(el->getValue(v));
  202. EXPECT_FALSE(el->getValue(m));
  203. EXPECT_EQ(1, i);
  204. el = Element::create(9223372036854775807LL);
  205. EXPECT_NO_THROW({
  206. EXPECT_EQ(9223372036854775807LL, el->intValue());
  207. });
  208. EXPECT_TRUE(el->getValue(i));
  209. EXPECT_EQ(9223372036854775807LL, i);
  210. ll = 9223372036854775807LL;
  211. el = Element::create(ll);
  212. EXPECT_NO_THROW({
  213. EXPECT_EQ(ll, el->intValue());
  214. });
  215. EXPECT_TRUE(el->getValue(i));
  216. EXPECT_EQ(ll, i);
  217. i32 = 2147483647L;
  218. el = Element::create(i32);
  219. EXPECT_NO_THROW({
  220. EXPECT_EQ(i32, el->intValue());
  221. });
  222. EXPECT_TRUE(el->getValue(i));
  223. EXPECT_EQ(i32, i);
  224. l = 2147483647L;
  225. el = Element::create(l);
  226. EXPECT_NO_THROW({
  227. EXPECT_EQ(l, el->intValue());
  228. });
  229. EXPECT_TRUE(el->getValue(i));
  230. EXPECT_EQ(l, i);
  231. }
  232. template <typename T>
  233. void
  234. testGetValueDouble() {
  235. T el;
  236. int64_t i;
  237. double d;
  238. bool b;
  239. std::string s;
  240. std::vector<ElementPtr> v;
  241. std::map<std::string, ConstElementPtr> m;
  242. el = Element::create(1.1);
  243. EXPECT_THROW(el->intValue(), TypeError);
  244. EXPECT_NO_THROW(el->doubleValue());
  245. EXPECT_THROW(el->boolValue(), TypeError);
  246. EXPECT_THROW(el->stringValue(), TypeError);
  247. EXPECT_THROW(el->listValue(), TypeError);
  248. EXPECT_THROW(el->mapValue(), TypeError);
  249. EXPECT_FALSE(el->getValue(i));
  250. EXPECT_TRUE(el->getValue(d));
  251. EXPECT_FALSE(el->getValue(b));
  252. EXPECT_FALSE(el->getValue(s));
  253. EXPECT_FALSE(el->getValue(v));
  254. EXPECT_FALSE(el->getValue(m));
  255. EXPECT_EQ(1.1, d);
  256. }
  257. template <typename T>
  258. void
  259. testGetValueBool() {
  260. T el;
  261. int64_t i;
  262. double d;
  263. bool b;
  264. std::string s;
  265. std::vector<ElementPtr> v;
  266. std::map<std::string, ConstElementPtr> m;
  267. el = Element::create(true);
  268. EXPECT_THROW(el->intValue(), TypeError);
  269. EXPECT_THROW(el->doubleValue(), TypeError);
  270. EXPECT_NO_THROW(el->boolValue());
  271. EXPECT_THROW(el->stringValue(), TypeError);
  272. EXPECT_THROW(el->listValue(), TypeError);
  273. EXPECT_THROW(el->mapValue(), TypeError);
  274. EXPECT_FALSE(el->getValue(i));
  275. EXPECT_FALSE(el->getValue(d));
  276. EXPECT_TRUE(el->getValue(b));
  277. EXPECT_FALSE(el->getValue(s));
  278. EXPECT_FALSE(el->getValue(v));
  279. EXPECT_FALSE(el->getValue(m));
  280. EXPECT_EQ(true, b);
  281. }
  282. template <typename T>
  283. void
  284. testGetValueString() {
  285. T el;
  286. int64_t i;
  287. double d;
  288. bool b;
  289. std::string s;
  290. std::vector<ElementPtr> v;
  291. std::map<std::string, ConstElementPtr> m;
  292. el = Element::create("foo");
  293. EXPECT_THROW(el->intValue(), TypeError);
  294. EXPECT_THROW(el->doubleValue(), TypeError);
  295. EXPECT_THROW(el->boolValue(), TypeError);
  296. EXPECT_NO_THROW(el->stringValue());
  297. EXPECT_THROW(el->listValue(), TypeError);
  298. EXPECT_THROW(el->mapValue(), TypeError);
  299. EXPECT_FALSE(el->getValue(i));
  300. EXPECT_FALSE(el->getValue(d));
  301. EXPECT_FALSE(el->getValue(b));
  302. EXPECT_TRUE(el->getValue(s));
  303. EXPECT_FALSE(el->getValue(v));
  304. EXPECT_FALSE(el->getValue(m));
  305. EXPECT_EQ("foo", s);
  306. }
  307. template <typename T>
  308. void
  309. testGetValueList() {
  310. T el;
  311. int64_t i;
  312. double d;
  313. bool b;
  314. std::string s;
  315. std::vector<ElementPtr> v;
  316. std::map<std::string, ConstElementPtr> m;
  317. el = Element::createList();
  318. EXPECT_THROW(el->intValue(), TypeError);
  319. EXPECT_THROW(el->doubleValue(), TypeError);
  320. EXPECT_THROW(el->boolValue(), TypeError);
  321. EXPECT_THROW(el->stringValue(), TypeError);
  322. EXPECT_NO_THROW(el->listValue());
  323. EXPECT_THROW(el->mapValue(), TypeError);
  324. EXPECT_FALSE(el->getValue(i));
  325. EXPECT_FALSE(el->getValue(d));
  326. EXPECT_FALSE(el->getValue(b));
  327. EXPECT_FALSE(el->getValue(s));
  328. EXPECT_TRUE(el->getValue(v));
  329. EXPECT_FALSE(el->getValue(m));
  330. EXPECT_EQ("[ ]", el->str());
  331. }
  332. template <typename T>
  333. void
  334. testGetValueMap() {
  335. T el;
  336. int64_t i;
  337. double d;
  338. bool b;
  339. std::string s;
  340. std::vector<ElementPtr> v;
  341. std::map<std::string, ConstElementPtr> m;
  342. el = Element::createMap();
  343. EXPECT_THROW(el->intValue(), TypeError);
  344. EXPECT_THROW(el->doubleValue(), TypeError);
  345. EXPECT_THROW(el->boolValue(), TypeError);
  346. EXPECT_THROW(el->stringValue(), TypeError);
  347. EXPECT_THROW(el->listValue(), TypeError);
  348. EXPECT_NO_THROW(el->mapValue());
  349. EXPECT_FALSE(el->getValue(i));
  350. EXPECT_FALSE(el->getValue(d));
  351. EXPECT_FALSE(el->getValue(b));
  352. EXPECT_FALSE(el->getValue(s));
  353. EXPECT_FALSE(el->getValue(v));
  354. EXPECT_TRUE(el->getValue(m));
  355. EXPECT_EQ("{ }", el->str());
  356. }
  357. TEST(Element, create_and_value_throws) {
  358. // this test checks whether elements throw exceptions if the
  359. // incorrect type is requested
  360. ElementPtr el;
  361. ConstElementPtr cel;
  362. int64_t i = 0;
  363. double d = 0.0;
  364. bool b = false;
  365. std::string s("asdf");
  366. std::vector<ElementPtr> v;
  367. std::map<std::string, ConstElementPtr> m;
  368. ConstElementPtr tmp;
  369. testGetValueInt<ElementPtr>();
  370. testGetValueInt<ConstElementPtr>();
  371. el = Element::create(1);
  372. i = 2;
  373. EXPECT_TRUE(el->setValue(i));
  374. EXPECT_EQ(2, el->intValue());
  375. EXPECT_FALSE(el->setValue(d));
  376. EXPECT_FALSE(el->setValue(b));
  377. EXPECT_FALSE(el->setValue(s));
  378. EXPECT_FALSE(el->setValue(v));
  379. EXPECT_FALSE(el->setValue(m));
  380. EXPECT_THROW(el->get(1), TypeError);
  381. EXPECT_THROW(el->set(1, el), TypeError);
  382. EXPECT_THROW(el->add(el), TypeError);
  383. EXPECT_THROW(el->remove(1), TypeError);
  384. EXPECT_THROW(el->size(), TypeError);
  385. EXPECT_THROW(el->empty(), TypeError);
  386. EXPECT_THROW(el->get("foo"), TypeError);
  387. EXPECT_THROW(el->set("foo", el), TypeError);
  388. EXPECT_THROW(el->remove("foo"), TypeError);
  389. EXPECT_THROW(el->contains("foo"), TypeError);
  390. EXPECT_FALSE(el->find("foo", tmp));
  391. testGetValueDouble<ElementPtr>();
  392. testGetValueDouble<ConstElementPtr>();
  393. el = Element::create(1.1);
  394. d = 2.2;
  395. EXPECT_TRUE(el->setValue(d));
  396. EXPECT_EQ(2.2, el->doubleValue());
  397. EXPECT_FALSE(el->setValue(i));
  398. EXPECT_FALSE(el->setValue(b));
  399. EXPECT_FALSE(el->setValue(s));
  400. EXPECT_FALSE(el->setValue(v));
  401. EXPECT_FALSE(el->setValue(m));
  402. EXPECT_THROW(el->get(1), TypeError);
  403. EXPECT_THROW(el->set(1, el), TypeError);
  404. EXPECT_THROW(el->add(el), TypeError);
  405. EXPECT_THROW(el->remove(1), TypeError);
  406. EXPECT_THROW(el->size(), TypeError);
  407. EXPECT_THROW(el->empty(), TypeError);
  408. EXPECT_THROW(el->get("foo"), TypeError);
  409. EXPECT_THROW(el->set("foo", el), TypeError);
  410. EXPECT_THROW(el->remove("foo"), TypeError);
  411. EXPECT_THROW(el->contains("foo"), TypeError);
  412. EXPECT_FALSE(el->find("foo", tmp));
  413. testGetValueBool<ElementPtr>();
  414. testGetValueBool<ConstElementPtr>();
  415. el = Element::create(true);
  416. b = false;
  417. EXPECT_TRUE(el->setValue(b));
  418. EXPECT_FALSE(el->boolValue());
  419. EXPECT_FALSE(el->setValue(i));
  420. EXPECT_FALSE(el->setValue(d));
  421. EXPECT_FALSE(el->setValue(s));
  422. EXPECT_FALSE(el->setValue(v));
  423. EXPECT_FALSE(el->setValue(m));
  424. EXPECT_THROW(el->get(1), TypeError);
  425. EXPECT_THROW(el->set(1, el), TypeError);
  426. EXPECT_THROW(el->add(el), TypeError);
  427. EXPECT_THROW(el->remove(1), TypeError);
  428. EXPECT_THROW(el->size(), TypeError);
  429. EXPECT_THROW(el->empty(), TypeError);
  430. EXPECT_THROW(el->get("foo"), TypeError);
  431. EXPECT_THROW(el->set("foo", el), TypeError);
  432. EXPECT_THROW(el->remove("foo"), TypeError);
  433. EXPECT_THROW(el->contains("foo"), TypeError);
  434. EXPECT_FALSE(el->find("foo", tmp));
  435. testGetValueString<ElementPtr>();
  436. testGetValueString<ConstElementPtr>();
  437. el = Element::create("foo");
  438. s = "bar";
  439. EXPECT_TRUE(el->setValue(s));
  440. EXPECT_EQ("bar", el->stringValue());
  441. EXPECT_FALSE(el->setValue(i));
  442. EXPECT_FALSE(el->setValue(b));
  443. EXPECT_FALSE(el->setValue(d));
  444. EXPECT_FALSE(el->setValue(v));
  445. EXPECT_FALSE(el->setValue(m));
  446. EXPECT_THROW(el->get(1), TypeError);
  447. EXPECT_THROW(el->set(1, el), TypeError);
  448. EXPECT_THROW(el->add(el), TypeError);
  449. EXPECT_THROW(el->remove(1), TypeError);
  450. EXPECT_THROW(el->size(), TypeError);
  451. EXPECT_THROW(el->empty(), TypeError);
  452. EXPECT_THROW(el->get("foo"), TypeError);
  453. EXPECT_THROW(el->set("foo", el), TypeError);
  454. EXPECT_THROW(el->remove("foo"), TypeError);
  455. EXPECT_THROW(el->contains("foo"), TypeError);
  456. EXPECT_FALSE(el->find("foo", tmp));
  457. testGetValueList<ElementPtr>();
  458. testGetValueList<ConstElementPtr>();
  459. el = Element::createList();
  460. EXPECT_TRUE(el->empty());
  461. v.push_back(Element::create(1));
  462. EXPECT_TRUE(el->setValue(v));
  463. EXPECT_FALSE(el->empty());
  464. EXPECT_EQ("[ 1 ]", el->str());
  465. testGetValueMap<ElementPtr>();
  466. testGetValueMap<ConstElementPtr>();
  467. el = Element::createMap();
  468. EXPECT_NO_THROW(el->set("foo", Element::create("bar")));
  469. EXPECT_EQ("{ \"foo\": \"bar\" }", el->str());
  470. }
  471. // Helper for escape check; it puts the given string in a StringElement,
  472. // then checks for the following conditions:
  473. // stringValue() must be same as input
  474. // toJSON() output must be escaped
  475. // fromJSON() on the previous output must result in original input
  476. void
  477. escapeHelper(const std::string& input, const std::string& expected) {
  478. StringElement str_element = StringElement(input);
  479. EXPECT_EQ(input, str_element.stringValue());
  480. std::stringstream os;
  481. str_element.toJSON(os);
  482. EXPECT_EQ(expected, os.str());
  483. ElementPtr str_element2 = Element::fromJSON(os.str());
  484. EXPECT_EQ(str_element.stringValue(), str_element2->stringValue());
  485. }
  486. TEST(Element, escape) {
  487. // Test whether quotes are escaped correctly when creating direct
  488. // String elements.
  489. escapeHelper("foo\"bar", "\"foo\\\"bar\"");
  490. escapeHelper("foo\\bar", "\"foo\\\\bar\"");
  491. escapeHelper("foo\bbar", "\"foo\\bbar\"");
  492. escapeHelper("foo\fbar", "\"foo\\fbar\"");
  493. escapeHelper("foo\nbar", "\"foo\\nbar\"");
  494. escapeHelper("foo\rbar", "\"foo\\rbar\"");
  495. escapeHelper("foo\tbar", "\"foo\\tbar\"");
  496. // Bad escapes
  497. EXPECT_THROW(Element::fromJSON("\\a"), JSONError);
  498. EXPECT_THROW(Element::fromJSON("\\"), JSONError);
  499. // Can't have escaped quotes outside strings
  500. EXPECT_THROW(Element::fromJSON("\\\"\\\""), JSONError);
  501. // Inside strings is OK
  502. EXPECT_NO_THROW(Element::fromJSON("\"\\\"\\\"\""));
  503. // A whitespace test
  504. EXPECT_NO_THROW(Element::fromJSON("\" \n \r \t \f \n \n \t\""));
  505. // Escape for forward slash is optional
  506. ASSERT_NO_THROW(Element::fromJSON("\"foo\\/bar\""));
  507. EXPECT_EQ("foo/bar", Element::fromJSON("\"foo\\/bar\"")->stringValue());
  508. // Control characters
  509. StringElement bell("foo\abar");
  510. EXPECT_EQ("\"foo\\u0007bar\"", bell.str());
  511. }
  512. // This test verifies that strings are copied.
  513. TEST(Element, stringCopy) {
  514. // StringElement constructor copies its string argument.
  515. std::string foo = "foo";
  516. ElementPtr elem = ElementPtr(new StringElement(foo));
  517. EXPECT_EQ(foo, elem->stringValue());
  518. foo[1] = 'O';
  519. EXPECT_EQ("fOo", foo);
  520. EXPECT_NE(foo, elem->stringValue());
  521. // Map keys are copied too.
  522. ElementPtr map = ElementPtr(new MapElement());
  523. std::string bar = "bar";
  524. map->set(bar, ElementPtr(new IntElement(1)));
  525. ConstElementPtr item = map->get("bar");
  526. ASSERT_TRUE(item);
  527. EXPECT_EQ(1, item->intValue());
  528. bar[0] = 'B';
  529. EXPECT_EQ("Bar", bar);
  530. EXPECT_TRUE(map->get("bar"));
  531. EXPECT_FALSE(map->get(bar));
  532. }
  533. // This test verifies that a backslash can be used in element content
  534. // when the element is created using constructor.
  535. TEST(Element, backslash1) {
  536. string input = "SMSBoot\\x64";// One slash passed to elem constructor...
  537. string exp = "SMSBoot\\x64"; // ... should result in one slash in the actual option.
  538. StringElement elem(input);
  539. EXPECT_EQ(exp, elem.stringValue());
  540. }
  541. // This test verifies that a backslash can be used in element content
  542. // when the element is created using fromJSON.
  543. TEST(Element, backslash2) {
  544. string input = "\"SMSBoot\\\\x64\""; // Two slashes put in the config file...
  545. string exp = "SMSBoot\\x64"; // ... should result in one slash in the actual option.
  546. ElementPtr elem = Element::fromJSON(input);
  547. EXPECT_EQ(exp, elem->stringValue());
  548. }
  549. TEST(Element, ListElement) {
  550. // this function checks the specific functions for ListElements
  551. ElementPtr el = Element::fromJSON("[ 1, \"bar\", 3 ]");
  552. EXPECT_EQ(el->get(0)->intValue(), 1);
  553. EXPECT_EQ(el->get(1)->stringValue(), "bar");
  554. EXPECT_EQ(el->get(2)->intValue(), 3);
  555. el->set(0, Element::fromJSON("\"foo\""));
  556. EXPECT_EQ(el->get(0)->stringValue(), "foo");
  557. el->add(Element::create(56176));
  558. EXPECT_EQ(el->get(3)->intValue(), 56176);
  559. el->remove(1);
  560. el->remove(1);
  561. EXPECT_EQ(el->str(), "[ \"foo\", 56176 ]");
  562. // hmm, it errors on EXPECT_THROW(el->get(3), std::out_of_range)
  563. EXPECT_ANY_THROW(el->get(3));
  564. el->add(Element::create(32));
  565. EXPECT_EQ(32, el->get(2)->intValue());
  566. // boundary condition tests for set()
  567. el->set(2, Element::create(0)); // update the last entry of the list
  568. EXPECT_EQ(0, el->get(2)->intValue());
  569. // attempt of set beyond the range of list should trigger an exception.
  570. EXPECT_ANY_THROW(el->set(3, Element::create(0)));
  571. }
  572. TEST(Element, MapElement) {
  573. // this function checks the specific functions for ListElements
  574. ElementPtr el = Element::fromJSON("{ \"name\": \"foo\", \"value1\": \"bar\", \"value2\": { \"number\": 42 } }");
  575. ConstElementPtr el2;
  576. EXPECT_EQ(el->get("name")->stringValue(), "foo");
  577. EXPECT_EQ(el->get("value2")->getType(), Element::map);
  578. EXPECT_TRUE(isNull(el->get("value3")));
  579. el->set("value3", Element::create(56176));
  580. EXPECT_EQ(el->get("value3")->intValue(), 56176);
  581. el->remove("value3");
  582. EXPECT_TRUE(isNull(el->get("value3")));
  583. EXPECT_EQ(el->find("value2/number")->intValue(), 42);
  584. EXPECT_TRUE(isNull(el->find("value2/nothing/")));
  585. EXPECT_EQ(el->find("value1")->stringValue(), "bar");
  586. EXPECT_EQ(el->find("value1/")->stringValue(), "bar");
  587. EXPECT_TRUE(el->find("value1", el2));
  588. EXPECT_EQ("bar", el2->stringValue());
  589. EXPECT_FALSE(el->find("name/error", el2));
  590. // A map element whose (only) element has the maximum length of tag.
  591. string long_maptag("0123456789abcdef1123456789abcdef2123456789abcdef"
  592. "3123456789abcdef4123456789abcdef5123456789abcdef"
  593. "6123456789abcdef7123456789abcdef8123456789abcdef"
  594. "9123456789abcdefa123456789abcdefb123456789abcdef"
  595. "c123456789abcdefd123456789abcdefe123456789abcdef"
  596. "f123456789abcde");
  597. EXPECT_EQ(255, long_maptag.length()); // check prerequisite
  598. el = Element::fromJSON("{ \"" + long_maptag + "\": \"bar\"}");
  599. EXPECT_EQ("bar", el->find(long_maptag)->stringValue());
  600. el = Element::createMap();
  601. el->set(long_maptag, Element::create("bar"));
  602. EXPECT_EQ("bar", el->find(long_maptag)->stringValue());
  603. // A one-byte longer tag should still be allowed
  604. long_maptag.push_back('f');
  605. el = Element::fromJSON("{ \"" + long_maptag + "\": \"bar\"}");
  606. el->set(long_maptag, Element::create("bar"));
  607. EXPECT_EQ("bar", el->find(long_maptag)->stringValue());
  608. // Null pointer value
  609. el.reset(new MapElement());
  610. ConstElementPtr null_ptr;
  611. el->set("value", null_ptr);
  612. EXPECT_FALSE(el->get("value"));
  613. EXPECT_EQ("{ \"value\": None }", el->str());
  614. }
  615. TEST(Element, to_and_from_wire) {
  616. // Wire format is now plain JSON.
  617. EXPECT_EQ("1", Element::create(1)->toWire());
  618. EXPECT_EQ("1.1", Element::create(1.1)->toWire());
  619. EXPECT_EQ("true", Element::create(true)->toWire());
  620. EXPECT_EQ("false", Element::create(false)->toWire());
  621. EXPECT_EQ("null", Element::create()->toWire());
  622. EXPECT_EQ("\"a string\"", Element::create("a string")->toWire());
  623. EXPECT_EQ("[ \"a\", \"list\" ]", Element::fromJSON("[ \"a\", \"list\" ]")->toWire());
  624. EXPECT_EQ("{ \"a\": \"map\" }", Element::fromJSON("{ \"a\": \"map\" }")->toWire());
  625. EXPECT_EQ("1", Element::fromWire("1")->str());
  626. std::stringstream ss;
  627. ss << "1";
  628. EXPECT_EQ("1", Element::fromWire(ss, 1)->str());
  629. // Some malformed JSON input
  630. EXPECT_THROW(Element::fromJSON("{ "), isc::data::JSONError);
  631. EXPECT_THROW(Element::fromJSON("{ \"a\" "), isc::data::JSONError);
  632. EXPECT_THROW(Element::fromJSON("{ \"a\": "), isc::data::JSONError);
  633. EXPECT_THROW(Element::fromJSON("{ \"a\": \"b\""), isc::data::JSONError);
  634. EXPECT_THROW(Element::fromJSON("{ \"a\": {"), isc::data::JSONError);
  635. EXPECT_THROW(Element::fromJSON("{ \"a\": {}"), isc::data::JSONError);
  636. EXPECT_THROW(Element::fromJSON("{ \"a\": []"), isc::data::JSONError);
  637. EXPECT_THROW(Element::fromJSON("{ \"a\": [ }"), isc::data::JSONError);
  638. EXPECT_THROW(Element::fromJSON("{\":"), isc::data::JSONError);
  639. EXPECT_THROW(Element::fromJSON("]"), isc::data::JSONError);
  640. EXPECT_THROW(Element::fromJSON("[ 1, 2, }"), isc::data::JSONError);
  641. EXPECT_THROW(Element::fromJSON("[ 1, 2, {}"), isc::data::JSONError);
  642. EXPECT_THROW(Element::fromJSON("[ 1, 2, { ]"), isc::data::JSONError);
  643. EXPECT_THROW(Element::fromJSON("[ "), isc::data::JSONError);
  644. EXPECT_THROW(Element::fromJSON("{{}}"), isc::data::JSONError);
  645. EXPECT_THROW(Element::fromJSON("{[]}"), isc::data::JSONError);
  646. EXPECT_THROW(Element::fromJSON("{ \"a\", \"b\" }"), isc::data::JSONError);
  647. EXPECT_THROW(Element::fromJSON("[ \"a\": \"b\" ]"), isc::data::JSONError);
  648. }
  649. ConstElementPtr
  650. efs(const std::string& str) {
  651. return (Element::fromJSON(str));
  652. }
  653. TEST(Element, equals) {
  654. EXPECT_EQ(*efs("1"), *efs("1"));
  655. EXPECT_NE(*efs("1"), *efs("2"));
  656. EXPECT_NE(*efs("1"), *efs("\"1\""));
  657. EXPECT_NE(*efs("1"), *efs("[]"));
  658. EXPECT_NE(*efs("1"), *efs("true"));
  659. EXPECT_NE(*efs("1"), *efs("{}"));
  660. EXPECT_EQ(*efs("1.1"), *efs("1.1"));
  661. EXPECT_NE(*efs("1.0"), *efs("1"));
  662. EXPECT_NE(*efs("1.1"), *efs("\"1\""));
  663. EXPECT_NE(*efs("1.1"), *efs("[]"));
  664. EXPECT_NE(*efs("1.1"), *efs("true"));
  665. EXPECT_NE(*efs("1.1"), *efs("{}"));
  666. EXPECT_EQ(*efs("true"), *efs("true"));
  667. EXPECT_NE(*efs("true"), *efs("false"));
  668. EXPECT_NE(*efs("true"), *efs("1"));
  669. EXPECT_NE(*efs("true"), *efs("\"1\""));
  670. EXPECT_NE(*efs("true"), *efs("[]"));
  671. EXPECT_NE(*efs("true"), *efs("{}"));
  672. EXPECT_EQ(*efs("\"foo\""), *efs("\"foo\""));
  673. EXPECT_NE(*efs("\"foo\""), *efs("\"bar\""));
  674. EXPECT_NE(*efs("\"foo\""), *efs("1"));
  675. EXPECT_NE(*efs("\"foo\""), *efs("\"1\""));
  676. EXPECT_NE(*efs("\"foo\""), *efs("true"));
  677. EXPECT_NE(*efs("\"foo\""), *efs("[]"));
  678. EXPECT_NE(*efs("\"foo\""), *efs("{}"));
  679. EXPECT_EQ(*efs("[]"), *efs("[]"));
  680. EXPECT_EQ(*efs("[ 1, 2, 3 ]"), *efs("[ 1, 2, 3 ]"));
  681. EXPECT_EQ(*efs("[ \"a\", [ true, 1], 2.2 ]"), *efs("[ \"a\", [ true, 1], 2.2 ]"));
  682. EXPECT_NE(*efs("[ \"a\", [ true, 1], 2.2 ]"), *efs("[ \"a\", [ true, 2], 2.2 ]"));
  683. EXPECT_NE(*efs("[]"), *efs("[1]"));
  684. EXPECT_NE(*efs("[]"), *efs("1"));
  685. EXPECT_NE(*efs("[]"), *efs("\"1\""));
  686. EXPECT_NE(*efs("[]"), *efs("{}"));
  687. EXPECT_EQ(*efs("{}"), *efs("{}"));
  688. EXPECT_EQ(*efs("{ \"foo\": \"bar\" }"), *efs("{ \"foo\": \"bar\" }"));
  689. EXPECT_EQ(*efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\" ], \"item3\": { \"foo\": \"bar\" } }"), *efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\" ], \"item3\": { \"foo\": \"bar\" } }"));
  690. EXPECT_NE(*efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\" ], \"item3\": { \"foo\": \"bar\" } }"), *efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\" ], \"item3\": { \"foo\": \"bar2\" } }"));
  691. EXPECT_NE(*efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\" ], \"item3\": { \"foo\": \"bar\" } }"), *efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\", 1 ], \"item3\": { \"foo\": \"bar\" } }"));
  692. EXPECT_NE(*efs("{ \"foo\": \"bar\" }"), *efs("1"));
  693. EXPECT_NE(*efs("{ \"foo\": \"bar\" }"), *efs("\"1\""));
  694. EXPECT_NE(*efs("{ \"foo\": \"bar\" }"), *efs("[]"));
  695. EXPECT_NE(*efs("{ \"foo\": \"bar\" }"), *efs("{}"));
  696. EXPECT_NE(*efs("{ \"foo\": \"bar\" }"), *efs("{ \"something\": \"different\" }"));
  697. EXPECT_EQ(*efs("null"), *Element::create());
  698. }
  699. TEST(Element, removeIdentical) {
  700. ElementPtr a = Element::createMap();
  701. ConstElementPtr b = Element::createMap();
  702. ConstElementPtr c = Element::createMap();
  703. removeIdentical(a, b);
  704. EXPECT_EQ(*a, *c);
  705. a = Element::fromJSON("{ \"a\": 1 }");
  706. b = Element::fromJSON("{ \"a\": 1 }");
  707. c = Element::createMap();
  708. removeIdentical(a, b);
  709. EXPECT_EQ(*a, *c);
  710. a = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
  711. b = Element::createMap();
  712. c = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
  713. removeIdentical(a, b);
  714. EXPECT_EQ(*a, *c);
  715. a = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
  716. b = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
  717. c = Element::createMap();
  718. removeIdentical(a, b);
  719. EXPECT_EQ(*a, *c);
  720. a = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
  721. b = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 3 ] }");
  722. c = Element::fromJSON("{ \"b\": [ 1, 2 ] }");
  723. removeIdentical(a, b);
  724. EXPECT_EQ(*a, *c);
  725. a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  726. b = Element::createMap();
  727. c = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  728. removeIdentical(a, b);
  729. EXPECT_EQ(*a, *c);
  730. a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  731. b = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  732. c = Element::createMap();
  733. removeIdentical(a, b);
  734. EXPECT_EQ(*a, *c);
  735. a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  736. b = Element::fromJSON("{ \"a\": { \"b\": \"d\" } }");
  737. c = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  738. removeIdentical(a, b);
  739. EXPECT_EQ(*a, *c);
  740. a = Element::fromJSON("{ \"a\": 1, \"b\": 2, \"c\": 3 }");
  741. b = Element::fromJSON("{ \"c\": 3, \"b\": 2 }");
  742. c = Element::fromJSON("{ \"a\": 1 }");
  743. removeIdentical(a, b);
  744. EXPECT_EQ(*a, *c);
  745. EXPECT_THROW(removeIdentical(Element::create(1), Element::create(2)), TypeError);
  746. }
  747. TEST(Element, constRemoveIdentical) {
  748. ConstElementPtr a = Element::createMap();
  749. ConstElementPtr b = Element::createMap();
  750. ConstElementPtr c = Element::createMap();
  751. EXPECT_EQ(*removeIdentical(a, b), *c);
  752. a = Element::fromJSON("{ \"a\": 1 }");
  753. b = Element::fromJSON("{ \"a\": 1 }");
  754. c = Element::createMap();
  755. EXPECT_EQ(*removeIdentical(a, b), *c);
  756. a = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
  757. b = Element::createMap();
  758. c = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
  759. EXPECT_EQ(*removeIdentical(a, b), *c);
  760. a = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
  761. b = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
  762. c = Element::createMap();
  763. EXPECT_EQ(*removeIdentical(a, b), *c);
  764. a = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
  765. b = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 3 ] }");
  766. c = Element::fromJSON("{ \"b\": [ 1, 2 ] }");
  767. EXPECT_EQ(*removeIdentical(a, b), *c);
  768. a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  769. b = Element::createMap();
  770. c = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  771. EXPECT_EQ(*removeIdentical(a, b), *c);
  772. a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  773. b = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  774. c = Element::createMap();
  775. EXPECT_EQ(*removeIdentical(a, b), *c);
  776. a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  777. b = Element::fromJSON("{ \"a\": { \"b\": \"d\" } }");
  778. c = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  779. EXPECT_EQ(*removeIdentical(a, b), *c);
  780. a = Element::fromJSON("{ \"a\": 1, \"b\": 2, \"c\": 3 }");
  781. b = Element::fromJSON("{ \"c\": 3, \"b\": 2 }");
  782. c = Element::fromJSON("{ \"a\": 1 }");
  783. EXPECT_EQ(*removeIdentical(a, b), *c);
  784. // removeIdentical() is overloaded so force the first argument to const
  785. ConstElementPtr bad = Element::create(1);
  786. EXPECT_THROW(removeIdentical(bad, Element::create(2)), TypeError);
  787. }
  788. TEST(Element, merge) {
  789. ElementPtr a = Element::createMap();
  790. ElementPtr b = Element::createMap();
  791. ConstElementPtr c = Element::createMap();
  792. merge(a, b);
  793. EXPECT_EQ(*a, *c);
  794. a = Element::fromJSON("1");
  795. b = Element::createMap();
  796. EXPECT_THROW(merge(a, b), TypeError);
  797. a = Element::createMap();
  798. b = Element::fromJSON("{ \"a\": 1 }");
  799. c = Element::fromJSON("{ \"a\": 1 }");
  800. merge(a, b);
  801. EXPECT_EQ(*a, *c);
  802. a = Element::createMap();
  803. b = Element::fromJSON("{ \"a\": 1 }");
  804. c = Element::fromJSON("{ \"a\": 1 }");
  805. merge(b, a);
  806. EXPECT_EQ(*b, *c);
  807. a = Element::fromJSON("{ \"a\": 1 }");
  808. b = Element::fromJSON("{ \"a\": 2 }");
  809. c = Element::fromJSON("{ \"a\": 2 }");
  810. merge(a, b);
  811. EXPECT_EQ(*a, *c);
  812. a = Element::fromJSON("{ \"a\": 1 }");
  813. b = Element::fromJSON("{ \"a\": 2 }");
  814. c = Element::fromJSON("{ \"a\": 1 }");
  815. merge(b, a);
  816. EXPECT_EQ(*b, *c);
  817. a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  818. b = Element::fromJSON("{ \"a\": { \"b\": \"d\" } }");
  819. c = Element::fromJSON("{ \"a\": { \"b\": \"d\" } }");
  820. merge(a, b);
  821. EXPECT_EQ(*a, *c);
  822. a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  823. b = Element::fromJSON("{ \"a\": { \"b\": \"d\" } }");
  824. c = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  825. merge(b, a);
  826. EXPECT_EQ(*b, *c);
  827. a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  828. b = Element::fromJSON("{ \"a\": null }");
  829. c = Element::fromJSON("{ }");
  830. merge(a, b);
  831. EXPECT_EQ(*a, *c);
  832. a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  833. b = Element::fromJSON("{ \"a\": null }");
  834. c = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
  835. merge(b, a);
  836. EXPECT_EQ(*b, *c);
  837. // And some tests with multiple values
  838. a = Element::fromJSON("{ \"a\": 1, \"b\": true, \"c\": null }");
  839. b = Element::fromJSON("{ \"a\": 1, \"b\": null, \"c\": \"a string\" }");
  840. c = Element::fromJSON("{ \"a\": 1, \"c\": \"a string\" }");
  841. merge(a, b);
  842. EXPECT_EQ(*a, *c);
  843. a = Element::fromJSON("{ \"a\": 1, \"b\": true, \"c\": null }");
  844. b = Element::fromJSON("{ \"a\": 1, \"b\": null, \"c\": \"a string\" }");
  845. c = Element::fromJSON("{ \"a\": 1, \"b\": true }");
  846. merge(b, a);
  847. EXPECT_EQ(*b, *c);
  848. a = Element::fromJSON("{ \"a\": 1, \"b\": 2, \"c\": 3 }");
  849. b = Element::fromJSON("{ \"a\": 3, \"b\": 2, \"c\": 1 }");
  850. c = Element::fromJSON("{ \"a\": 3, \"b\": 2, \"c\": 1 }");
  851. merge(a, b);
  852. EXPECT_EQ(*a, *c);
  853. a = Element::fromJSON("{ \"a\": 1, \"b\": 2, \"c\": 3 }");
  854. b = Element::fromJSON("{ \"a\": 3, \"b\": 2, \"c\": 1 }");
  855. c = Element::fromJSON("{ \"a\": 1, \"b\": 2, \"c\": 3 }");
  856. merge(b, a);
  857. EXPECT_EQ(*b, *c);
  858. }
  859. // This test checks copy.
  860. TEST(Element, copy) {
  861. // Null pointer
  862. ElementPtr elem;
  863. EXPECT_THROW(copy(elem, 0), isc::BadValue);
  864. EXPECT_THROW(copy(elem), isc::BadValue);
  865. EXPECT_THROW(copy(elem, -1), isc::BadValue);
  866. // Basic types
  867. elem.reset(new IntElement(1));
  868. EXPECT_TRUE(elem->equals(*Element::fromJSON("1")));
  869. EXPECT_EQ("1", elem->str());
  870. ElementPtr copied;
  871. ASSERT_NO_THROW(copied = copy(elem, 0));
  872. EXPECT_TRUE(elem->equals(*copied));
  873. elem.reset(new DoubleElement(1.0));
  874. EXPECT_TRUE(elem->equals(*Element::fromJSON("1.0")));
  875. ASSERT_NO_THROW(copied = copy(elem, 0));
  876. EXPECT_TRUE(elem->equals(*copied));
  877. elem.reset(new BoolElement(true));
  878. EXPECT_TRUE(elem->equals(*Element::fromJSON("true")));
  879. ASSERT_NO_THROW(copied = copy(elem, 0));
  880. EXPECT_TRUE(elem->equals(*copied));
  881. elem.reset(new NullElement());
  882. EXPECT_TRUE(elem->equals(*Element::fromJSON("null")));
  883. ASSERT_NO_THROW(copied = copy(elem, 0));
  884. EXPECT_TRUE(elem->equals(*copied));
  885. elem.reset(new StringElement("foo"));
  886. EXPECT_TRUE(elem->equals(*Element::fromJSON("\"foo\"")));
  887. ASSERT_NO_THROW(copied = copy(elem, 0));
  888. EXPECT_TRUE(elem->equals(*copied));
  889. ASSERT_NO_THROW(elem->setValue(std::string("bar")));
  890. EXPECT_TRUE(elem->equals(*Element::fromJSON("\"bar\"")));
  891. EXPECT_FALSE(elem->equals(*copied));
  892. elem.reset(new ListElement());
  893. ElementPtr item = ElementPtr(new IntElement(1));
  894. elem->add(item);
  895. EXPECT_TRUE(elem->equals(*Element::fromJSON("[ 1 ]")));
  896. ASSERT_NO_THROW(copied = copy(elem, 0));
  897. EXPECT_TRUE(elem->equals(*copied));
  898. ElementPtr deep;
  899. ASSERT_NO_THROW(deep = copy(elem));
  900. EXPECT_TRUE(elem->equals(*deep));
  901. ASSERT_NO_THROW(item = elem->getNonConst(0));
  902. ASSERT_NO_THROW(item->setValue(2));
  903. EXPECT_TRUE(elem->equals(*Element::fromJSON("[ 2 ]")));
  904. EXPECT_TRUE(elem->equals(*copied));
  905. EXPECT_FALSE(elem->equals(*deep));
  906. elem.reset(new MapElement());
  907. item.reset(new StringElement("bar"));
  908. elem->set("foo", item);
  909. EXPECT_TRUE(elem->equals(*Element::fromJSON("{ \"foo\": \"bar\" }")));
  910. ASSERT_NO_THROW(copied = copy(elem, 0));
  911. EXPECT_TRUE(elem->equals(*copied));
  912. ASSERT_NO_THROW(deep = copy(elem));
  913. EXPECT_TRUE(elem->equals(*deep));
  914. ASSERT_NO_THROW(item->setValue(std::string("Bar")));
  915. EXPECT_TRUE(elem->equals(*Element::fromJSON("{ \"foo\": \"Bar\" }")));
  916. EXPECT_TRUE(elem->equals(*copied));
  917. EXPECT_FALSE(elem->equals(*deep));
  918. // Complex example
  919. std::string input = "{ \n"
  920. "\"integer\": 1,\n"
  921. "\"double\": 1.0,\n"
  922. "\"boolean\": true,\n"
  923. "\"null\": null,\n"
  924. "\"string\": \"foobar\",\n"
  925. "\"list\": [ 1, 2 ],\n"
  926. "\"map\": { \"foo\": \"bar\" } }\n";
  927. ConstElementPtr complex;
  928. ASSERT_NO_THROW(complex = Element::fromJSON(input));
  929. ASSERT_NO_THROW(copied = copy(complex, 0));
  930. EXPECT_TRUE(copied->equals(*complex));
  931. ASSERT_NO_THROW(deep = copy(complex));
  932. EXPECT_TRUE(deep->equals(*complex));
  933. ElementPtr shallow;
  934. ASSERT_NO_THROW(shallow = copy(complex, 1));
  935. EXPECT_TRUE(shallow->equals(*complex));
  936. // Try to modify copies
  937. ASSERT_NO_THROW(item = deep->get("list")->getNonConst(1));
  938. ASSERT_NO_THROW(item->setValue(3));
  939. EXPECT_FALSE(deep->equals(*complex));
  940. EXPECT_TRUE(shallow->equals(*complex));
  941. ASSERT_NO_THROW(item = boost::const_pointer_cast<Element>(shallow->get("string")));
  942. ASSERT_NO_THROW(item->setValue(std::string("FooBar")));
  943. EXPECT_FALSE(shallow->equals(*complex));
  944. EXPECT_TRUE(copied->equals(*complex));
  945. }
  946. // This test checks the isEquivalent function.
  947. TEST(Element, isEquivalent) {
  948. // All are different but a is equivalent to b
  949. string texta = "{ \"a\": 1, \"b\": [ ], \"c\": [ 1, 1, 2 ] }";
  950. string textb = "{ \"b\": [ ], \"a\": 1, \"c\": [ 1, 2, 1 ] }";
  951. string textc = "{ \"a\": 2, \"b\": [ ], \"c\": [ 1, 1, 2 ] }";
  952. string textd = "{ \"a\": 1, \"c\": [ ], \"b\": [ 1, 1, 2 ] }";
  953. string texte = "{ \"a\": 1, \"b\": [ ], \"c\": [ 1, 2, 2 ] }";
  954. ElementPtr a = Element::fromJSON(texta);
  955. ElementPtr b = Element::fromJSON(textb);
  956. ElementPtr c = Element::fromJSON(textc);
  957. ElementPtr d = Element::fromJSON(textd);
  958. ElementPtr e = Element::fromJSON(texte);
  959. EXPECT_TRUE(isEquivalent(a, b));
  960. EXPECT_NE(a, b);
  961. EXPECT_FALSE(isEquivalent(a, c));
  962. EXPECT_FALSE(isEquivalent(a, d));
  963. EXPECT_FALSE(isEquivalent(a, e));
  964. // Verifies isEquivalent handles cycles
  965. if (isc::util::unittests::runningOnValgrind()) {
  966. ElementPtr l = Element::createList();
  967. l->add(l);
  968. EXPECT_THROW(isEquivalent(l, l), isc::BadValue);
  969. }
  970. }
  971. // This test checks the pretty print function.
  972. TEST(Element, prettyPrint) {
  973. // default step is 2, order is alphabetic, no \n at the end
  974. string text = "{\n"
  975. " \"boolean\": true,\n"
  976. " \"empty-list\": [ ],\n"
  977. " \"empty-map\": { },\n"
  978. " \"integer\": 1,\n"
  979. " \"list\": [ 1, 2, 3 ],\n"
  980. " \"map\": {\n"
  981. " \"item\": null\n"
  982. " },\n"
  983. " \"string\": \"foobar\"\n"
  984. "}";
  985. ElementPtr json = Element::fromJSON(text);
  986. string pprinted = prettyPrint(json);
  987. EXPECT_EQ(text, pprinted);
  988. }
  989. // This test checks whether it is possible to ignore comments. It also checks
  990. // that the comments are ignored only when told to.
  991. TEST(Element, preprocessor) {
  992. string no_comment = "{ \"a\": 1,\n"
  993. " \"b\": 2}";
  994. string head_comment = "# this is a comment, ignore me\n"
  995. "{ \"a\": 1,\n"
  996. " \"b\": 2}";
  997. string mid_comment = "{ \"a\": 1,\n"
  998. "# this is a comment, ignore me\n"
  999. " \"b\": 2}";
  1000. string tail_comment = "{ \"a\": 1,\n"
  1001. " \"b\": 2}"
  1002. "# this is a comment, ignore me\n";
  1003. string dbl_head_comment = "# this is a comment, ignore me\n"
  1004. "# second line, still ignored\n"
  1005. "{ \"a\": 1,\n"
  1006. " \"b\": 2}";
  1007. string dbl_mid_comment = "{ \"a\": 1,\n"
  1008. "# this is a comment, ignore me\n"
  1009. "# second line, still ignored\n"
  1010. " \"b\": 2}";
  1011. string dbl_tail_comment = "{ \"a\": 1,\n"
  1012. " \"b\": 2}"
  1013. "# this is a comment, ignore me\n"
  1014. "# second line, still ignored\n";
  1015. // This is what we expect in all cases.
  1016. ElementPtr exp = Element::fromJSON(no_comment);
  1017. // Let's convert them all and see that the result it the same every time
  1018. EXPECT_TRUE(exp->equals(*Element::fromJSON(head_comment, true)));
  1019. EXPECT_TRUE(exp->equals(*Element::fromJSON(mid_comment, true)));
  1020. EXPECT_TRUE(exp->equals(*Element::fromJSON(tail_comment, true)));
  1021. EXPECT_TRUE(exp->equals(*Element::fromJSON(dbl_head_comment, true)));
  1022. EXPECT_TRUE(exp->equals(*Element::fromJSON(dbl_mid_comment, true)));
  1023. EXPECT_TRUE(exp->equals(*Element::fromJSON(dbl_tail_comment, true)));
  1024. // With preprocessing disabled, it should fail all around
  1025. EXPECT_THROW(Element::fromJSON(head_comment), JSONError);
  1026. EXPECT_THROW(Element::fromJSON(mid_comment), JSONError);
  1027. EXPECT_THROW(Element::fromJSON(tail_comment), JSONError);
  1028. EXPECT_THROW(Element::fromJSON(dbl_head_comment), JSONError);
  1029. EXPECT_THROW(Element::fromJSON(dbl_mid_comment), JSONError);
  1030. EXPECT_THROW(Element::fromJSON(dbl_tail_comment), JSONError);
  1031. // For coverage
  1032. std::istringstream iss(no_comment);
  1033. EXPECT_TRUE(exp->equals(*Element::fromJSON(iss, true)));
  1034. }
  1035. TEST(Element, getPosition) {
  1036. std::istringstream ss("{\n"
  1037. " \"a\": 2,\n"
  1038. " \"b\":true,\n"
  1039. " \"cy\": \"a string\",\n"
  1040. " \"dyz\": {\n"
  1041. "\n"
  1042. " \"e\": 3,\n"
  1043. " \"f\": null\n"
  1044. "\n"
  1045. " },\n"
  1046. " \"g\": [ 5, 6,\n"
  1047. " 7 ]\n"
  1048. "}\n");
  1049. // Create a JSON string holding different type of values. Some of the
  1050. // values in the config string are not aligned, so as we can check that
  1051. // the position is set correctly for the elements.
  1052. ElementPtr top = Element::fromJSON(ss, string("kea.conf"));
  1053. ASSERT_TRUE(top);
  1054. // Element "a"
  1055. ConstElementPtr level1_el = top->get("a");
  1056. ASSERT_TRUE(level1_el);
  1057. EXPECT_EQ(2, level1_el->getPosition().line_);
  1058. EXPECT_EQ(11, level1_el->getPosition().pos_);
  1059. EXPECT_EQ("kea.conf", level1_el->getPosition().file_);
  1060. // Element "b"
  1061. level1_el = top->get("b");
  1062. ASSERT_TRUE(level1_el);
  1063. EXPECT_EQ(3, level1_el->getPosition().line_);
  1064. EXPECT_EQ(9, level1_el->getPosition().pos_);
  1065. EXPECT_EQ("kea.conf", level1_el->getPosition().file_);
  1066. // Element "cy"
  1067. level1_el = top->get("cy");
  1068. ASSERT_TRUE(level1_el);
  1069. EXPECT_EQ(4, level1_el->getPosition().line_);
  1070. EXPECT_EQ(11, level1_el->getPosition().pos_);
  1071. EXPECT_EQ("kea.conf", level1_el->getPosition().file_);
  1072. // Element "dyz"
  1073. level1_el = top->get("dyz");
  1074. ASSERT_TRUE(level1_el);
  1075. EXPECT_EQ(5, level1_el->getPosition().line_);
  1076. EXPECT_EQ(13, level1_el->getPosition().pos_);
  1077. EXPECT_EQ("kea.conf", level1_el->getPosition().file_);
  1078. // Element "e" is a sub element of "dyz".
  1079. ConstElementPtr level2_el = level1_el->get("e");
  1080. ASSERT_TRUE(level2_el);
  1081. EXPECT_EQ(7, level2_el->getPosition().line_);
  1082. EXPECT_EQ(12, level2_el->getPosition().pos_);
  1083. EXPECT_EQ("kea.conf", level2_el->getPosition().file_);
  1084. // Element "f" is also a sub element of "dyz"
  1085. level2_el = level1_el->get("f");
  1086. ASSERT_TRUE(level2_el);
  1087. EXPECT_EQ(8, level2_el->getPosition().line_);
  1088. EXPECT_EQ(14, level2_el->getPosition().pos_);
  1089. EXPECT_EQ("kea.conf", level2_el->getPosition().file_);
  1090. // Element "g" is a list.
  1091. level1_el = top->get("g");
  1092. ASSERT_TRUE(level1_el);
  1093. EXPECT_EQ(11, level1_el->getPosition().line_);
  1094. // Position indicates where the values start (excluding the "[" character)"
  1095. EXPECT_EQ(11, level1_el->getPosition().pos_);
  1096. EXPECT_EQ("kea.conf", level1_el->getPosition().file_);
  1097. // First element from the list.
  1098. level2_el = level1_el->get(0);
  1099. ASSERT_TRUE(level2_el);
  1100. EXPECT_EQ(11, level2_el->getPosition().line_);
  1101. EXPECT_EQ(12, level2_el->getPosition().pos_);
  1102. EXPECT_EQ("kea.conf", level2_el->getPosition().file_);
  1103. // Second element from the list.
  1104. level2_el = level1_el->get(1);
  1105. ASSERT_TRUE(level2_el);
  1106. EXPECT_EQ(11, level2_el->getPosition().line_);
  1107. EXPECT_EQ(15, level2_el->getPosition().pos_);
  1108. EXPECT_EQ("kea.conf", level2_el->getPosition().file_);
  1109. // Third element from the list.
  1110. level2_el = level1_el->get(2);
  1111. ASSERT_TRUE(level2_el);
  1112. EXPECT_EQ(12, level2_el->getPosition().line_);
  1113. EXPECT_EQ(14, level2_el->getPosition().pos_);
  1114. EXPECT_EQ("kea.conf", level2_el->getPosition().file_);
  1115. }
  1116. // Tests whether position is returned properly for a commented input JSON text.
  1117. TEST(Element, getPositionCommented) {
  1118. std::istringstream ss("{\n"
  1119. " \"a\": 2,\n"
  1120. "# comment\n"
  1121. " \"cy\": \"a string\",\n"
  1122. " \"dyz\": {\n"
  1123. "# another comment\n"
  1124. " \"e\": 3,\n"
  1125. " \"f\": null\n"
  1126. "\n"
  1127. " } }\n");
  1128. // Create a JSON string holding different type of values. Some of the
  1129. // values in the config string are not aligned, so as we can check that
  1130. // the position is set correctly for the elements.
  1131. ElementPtr top = Element::fromJSON(ss, string("kea.conf"), true);
  1132. ASSERT_TRUE(top);
  1133. // Element "a"
  1134. ConstElementPtr level1_el = top->get("a");
  1135. ASSERT_TRUE(level1_el);
  1136. EXPECT_EQ(2, level1_el->getPosition().line_);
  1137. EXPECT_EQ(11, level1_el->getPosition().pos_);
  1138. EXPECT_EQ("kea.conf", level1_el->getPosition().file_);
  1139. // Element "cy"
  1140. level1_el = top->get("cy");
  1141. ASSERT_TRUE(level1_el);
  1142. EXPECT_EQ(4, level1_el->getPosition().line_);
  1143. EXPECT_EQ(11, level1_el->getPosition().pos_);
  1144. EXPECT_EQ("kea.conf", level1_el->getPosition().file_);
  1145. // Element "dyz"
  1146. level1_el = top->get("dyz");
  1147. ASSERT_TRUE(level1_el);
  1148. EXPECT_EQ(5, level1_el->getPosition().line_);
  1149. EXPECT_EQ(13, level1_el->getPosition().pos_);
  1150. EXPECT_EQ("kea.conf", level1_el->getPosition().file_);
  1151. // Element "e" is a sub element of "dyz".
  1152. ConstElementPtr level2_el = level1_el->get("e");
  1153. ASSERT_TRUE(level2_el);
  1154. EXPECT_EQ(7, level2_el->getPosition().line_);
  1155. EXPECT_EQ(12, level2_el->getPosition().pos_);
  1156. EXPECT_EQ("kea.conf", level2_el->getPosition().file_);
  1157. // Element "f" is also a sub element of "dyz"
  1158. level2_el = level1_el->get("f");
  1159. ASSERT_TRUE(level2_el);
  1160. EXPECT_EQ(8, level2_el->getPosition().line_);
  1161. EXPECT_EQ(14, level2_el->getPosition().pos_);
  1162. EXPECT_EQ("kea.conf", level2_el->getPosition().file_);
  1163. }
  1164. }