node_ut.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. #include "node.h"
  2. #include "node_io.h"
  3. #include <library/cpp/testing/unittest/registar.h>
  4. #include <util/ysaveload.h>
  5. using namespace NYT;
  6. template<>
  7. void Out<NYT::TNode>(IOutputStream& s, const NYT::TNode& node)
  8. {
  9. s << "TNode:" << NodeToYsonString(node);
  10. }
  11. Y_UNIT_TEST_SUITE(YtNodeTest) {
  12. Y_UNIT_TEST(TestConstsructors) {
  13. TNode nodeEmpty;
  14. UNIT_ASSERT_EQUAL(nodeEmpty.GetType(), TNode::Undefined);
  15. TNode nodeString("foobar");
  16. UNIT_ASSERT_EQUAL(nodeString.GetType(), TNode::String);
  17. UNIT_ASSERT(nodeString.IsString());
  18. UNIT_ASSERT_VALUES_EQUAL(nodeString.AsString(), "foobar");
  19. TNode nodeInt(int(54));
  20. UNIT_ASSERT_EQUAL(nodeInt.GetType(), TNode::Int64);
  21. UNIT_ASSERT(nodeInt.IsInt64());
  22. UNIT_ASSERT(!nodeInt.IsUint64());
  23. UNIT_ASSERT_VALUES_EQUAL(nodeInt.AsInt64(), 54ull);
  24. TNode nodeUint(ui64(42));
  25. UNIT_ASSERT_EQUAL(nodeUint.GetType(), TNode::Uint64);
  26. UNIT_ASSERT(nodeUint.IsUint64());
  27. UNIT_ASSERT(!nodeUint.IsInt64());
  28. UNIT_ASSERT_VALUES_EQUAL(nodeUint.AsUint64(), 42ull);
  29. TNode nodeDouble(double(2.3));
  30. UNIT_ASSERT_EQUAL(nodeDouble.GetType(), TNode::Double);
  31. UNIT_ASSERT(nodeDouble.IsDouble());
  32. UNIT_ASSERT_VALUES_EQUAL(nodeDouble.AsDouble(), double(2.3));
  33. TNode nodeBool(true);
  34. UNIT_ASSERT_EQUAL(nodeBool.GetType(), TNode::Bool);
  35. UNIT_ASSERT(nodeBool.IsBool());
  36. UNIT_ASSERT_VALUES_EQUAL(nodeBool.AsBool(), true);
  37. TNode nodeEntity = TNode::CreateEntity();
  38. UNIT_ASSERT_EQUAL(nodeEntity.GetType(), TNode::Null);
  39. UNIT_ASSERT(nodeEntity.IsEntity());
  40. }
  41. Y_UNIT_TEST(TestPredicates) {
  42. const TNode undefinedNode;
  43. UNIT_ASSERT(undefinedNode.IsUndefined());
  44. UNIT_ASSERT(!undefinedNode.IsNull());
  45. UNIT_ASSERT(!undefinedNode.HasValue());
  46. const TNode nullNode = TNode::CreateEntity();
  47. UNIT_ASSERT(!nullNode.IsUndefined());
  48. UNIT_ASSERT(nullNode.IsNull());
  49. UNIT_ASSERT(!nullNode.HasValue());
  50. const TNode intNode(int(64));
  51. UNIT_ASSERT(!intNode.IsUndefined());
  52. UNIT_ASSERT(!intNode.IsNull());
  53. UNIT_ASSERT(intNode.HasValue());
  54. const TNode stringNode("blah");
  55. UNIT_ASSERT(!stringNode.IsUndefined());
  56. UNIT_ASSERT(!stringNode.IsNull());
  57. UNIT_ASSERT(stringNode.HasValue());
  58. }
  59. Y_UNIT_TEST(TestComplexConstructors) {
  60. const TNode listNode = TNode::CreateList({"one", 2, "tree"});
  61. const auto expectedListValue = std::vector<TNode>({"one", 2, "tree"});
  62. UNIT_ASSERT_VALUES_EQUAL(listNode.AsList(), expectedListValue);
  63. const TNode mapNode = TNode::CreateMap({{"one", 1}, {"two", 2u}});
  64. const auto expectedMapValue = THashMap<TString, TNode>({{"one", 1}, {"two", 2u}});
  65. UNIT_ASSERT_VALUES_EQUAL(mapNode.AsMap(), expectedMapValue);
  66. }
  67. Y_UNIT_TEST(TestNodeMap) {
  68. TNode nodeMap = TNode()("foo", "bar")("bar", "baz");
  69. UNIT_ASSERT(nodeMap.IsMap());
  70. UNIT_ASSERT_EQUAL(nodeMap.GetType(), TNode::Map);
  71. UNIT_ASSERT_VALUES_EQUAL(nodeMap.Size(), 2);
  72. UNIT_ASSERT(nodeMap.HasKey("foo"));
  73. UNIT_ASSERT(!nodeMap.HasKey("42"));
  74. UNIT_ASSERT_EQUAL(nodeMap["foo"], TNode("bar"));
  75. UNIT_ASSERT_EQUAL(nodeMap["bar"], TNode("baz"));
  76. // const version of operator[]
  77. UNIT_ASSERT_EQUAL(static_cast<const TNode&>(nodeMap)["42"].GetType(), TNode::Undefined);
  78. UNIT_ASSERT(!nodeMap.HasKey("42"));
  79. // nonconst version of operator[]
  80. UNIT_ASSERT_EQUAL(nodeMap["42"].GetType(), TNode::Undefined);
  81. UNIT_ASSERT(nodeMap.HasKey("42"));
  82. nodeMap("rock!!!", TNode()
  83. ("Pink", "Floyd")
  84. ("Purple", "Deep"));
  85. TNode copyNode;
  86. copyNode = nodeMap;
  87. UNIT_ASSERT_EQUAL(copyNode["foo"], TNode("bar"));
  88. UNIT_ASSERT_EQUAL(copyNode["bar"], TNode("baz"));
  89. UNIT_ASSERT(copyNode["42"].GetType() == TNode::Undefined);
  90. UNIT_ASSERT_EQUAL(copyNode["rock!!!"]["Purple"], TNode("Deep"));
  91. }
  92. Y_UNIT_TEST(TestNodeList) {
  93. TNode nodeList = TNode().Add("foo").Add(42).Add(3.14);
  94. UNIT_ASSERT(nodeList.IsList());
  95. UNIT_ASSERT_EQUAL(nodeList.GetType(), TNode::List);
  96. UNIT_ASSERT_VALUES_EQUAL(nodeList.Size(), 3);
  97. UNIT_ASSERT_EQUAL(nodeList[1], TNode(42));
  98. nodeList.Add(TNode().Add("ls").Add("pwd"));
  99. TNode copyNode;
  100. copyNode = nodeList;
  101. UNIT_ASSERT_EQUAL(copyNode[0], TNode("foo"));
  102. UNIT_ASSERT_EQUAL(copyNode[3][1], TNode("pwd"));
  103. }
  104. Y_UNIT_TEST(TestInsertingMethodsFromTemporaryObjects) {
  105. // check that .Add(...) doesn't return lvalue reference to temporary object
  106. {
  107. const TNode& nodeList = TNode().Add(0).Add("pass").Add(0);
  108. UNIT_ASSERT_EQUAL(nodeList[1], TNode("pass"));
  109. }
  110. // check that .operator()(...) doesn't return lvalue reference to temporary object
  111. {
  112. const TNode& nodeMap = TNode()("1", 0)("2", "pass")("3", 0);
  113. UNIT_ASSERT_EQUAL(nodeMap["2"], TNode("pass"));
  114. }
  115. }
  116. Y_UNIT_TEST(TestAttributes) {
  117. TNode node = TNode()("lee", 42)("faa", 54);
  118. UNIT_ASSERT(!node.HasAttributes());
  119. node.Attributes()("foo", true)("bar", false);
  120. UNIT_ASSERT(node.HasAttributes());
  121. {
  122. TNode copyNode;
  123. UNIT_ASSERT(!copyNode.HasAttributes());
  124. copyNode = node;
  125. UNIT_ASSERT(copyNode.HasAttributes());
  126. UNIT_ASSERT_EQUAL(copyNode.GetAttributes()["foo"], TNode(true));
  127. }
  128. {
  129. TNode movedWithoutAttributes(42);
  130. movedWithoutAttributes.Attributes()("one", 1)("two", 2);
  131. movedWithoutAttributes.MoveWithoutAttributes(TNode(node));
  132. UNIT_ASSERT(movedWithoutAttributes.IsMap());
  133. UNIT_ASSERT_EQUAL(movedWithoutAttributes["lee"], TNode(42));
  134. UNIT_ASSERT_EQUAL(movedWithoutAttributes.GetAttributes()["one"], TNode(1));
  135. UNIT_ASSERT(!movedWithoutAttributes.GetAttributes().HasKey("foo"));
  136. }
  137. {
  138. TNode copyNode = node;
  139. UNIT_ASSERT(copyNode.HasAttributes());
  140. UNIT_ASSERT(copyNode.GetAttributes().HasKey("foo"));
  141. copyNode.ClearAttributes();
  142. UNIT_ASSERT(!copyNode.HasAttributes());
  143. UNIT_ASSERT(!copyNode.GetAttributes().HasKey("foo"));
  144. }
  145. {
  146. TNode copyNode = node;
  147. UNIT_ASSERT(copyNode.HasAttributes());
  148. UNIT_ASSERT(copyNode.GetAttributes().HasKey("foo"));
  149. copyNode.Clear();
  150. UNIT_ASSERT(!copyNode.HasAttributes());
  151. UNIT_ASSERT(!copyNode.GetAttributes().HasKey("foo"));
  152. }
  153. }
  154. Y_UNIT_TEST(TestEq) {
  155. TNode nodeNoAttributes = TNode()("lee", 42)("faa", 54);
  156. TNode node = nodeNoAttributes;
  157. node.Attributes()("foo", true)("bar", false);
  158. UNIT_ASSERT(node != nodeNoAttributes);
  159. UNIT_ASSERT(nodeNoAttributes != node);
  160. TNode copyNode = node;
  161. UNIT_ASSERT(copyNode == node);
  162. UNIT_ASSERT(node == copyNode);
  163. }
  164. Y_UNIT_TEST(TestComparison) {
  165. using namespace NYT::NNodeCmp;
  166. {
  167. TNode nodeNoAttributes = TNode()("lee", 42)("faa", 54);
  168. TNode node = nodeNoAttributes;
  169. node.Attributes()("foo", true)("bar", false);
  170. UNIT_ASSERT_EXCEPTION(node > nodeNoAttributes, TNode::TTypeError);
  171. UNIT_ASSERT_EXCEPTION(node >= nodeNoAttributes, TNode::TTypeError);
  172. UNIT_ASSERT_EXCEPTION(nodeNoAttributes < node, TNode::TTypeError);
  173. UNIT_ASSERT_EXCEPTION(nodeNoAttributes <= node, TNode::TTypeError);
  174. }
  175. {
  176. TNode nodeMap = TNode()("map", 23);
  177. TNode nodeList = TNode::CreateList();
  178. UNIT_ASSERT_EXCEPTION(nodeList > nodeMap, TNode::TTypeError);
  179. UNIT_ASSERT_EXCEPTION(nodeMap < nodeList, TNode::TTypeError);
  180. UNIT_ASSERT_EXCEPTION(nodeMap >= nodeMap, TNode::TTypeError);
  181. UNIT_ASSERT_EXCEPTION(nodeList <= nodeList, TNode::TTypeError);
  182. }
  183. {
  184. TNode node1("aaa");
  185. TNode node2("bbb");
  186. TNode node3("ccc");
  187. UNIT_ASSERT(node1 < node2);
  188. UNIT_ASSERT(node1 <= node2);
  189. UNIT_ASSERT(node1 < node3);
  190. UNIT_ASSERT(node1 <= node3);
  191. UNIT_ASSERT(!(node3 < node1));
  192. UNIT_ASSERT(!(node1 > node3));
  193. UNIT_ASSERT(!(node3 <= node1));
  194. UNIT_ASSERT(!(node1 >= node3));
  195. UNIT_ASSERT(node3 > node2);
  196. UNIT_ASSERT(node3 >= node2);
  197. UNIT_ASSERT(node3 > node1);
  198. UNIT_ASSERT(node3 >= node1);
  199. UNIT_ASSERT(node1 <= node1);
  200. UNIT_ASSERT(node1 >= node1);
  201. }
  202. {
  203. TNode node1(23);
  204. TNode node2("bbb");
  205. TNode node3 = TNode::CreateEntity();
  206. UNIT_ASSERT(node1 > node2);
  207. UNIT_ASSERT(node1 >= node2);
  208. UNIT_ASSERT(node2 < node1);
  209. UNIT_ASSERT(node2 <= node1);
  210. UNIT_ASSERT(!(node1 < node2));
  211. UNIT_ASSERT(!(node1 <= node2));
  212. UNIT_ASSERT(!(node2 > node1));
  213. UNIT_ASSERT(!(node2 >= node1));
  214. UNIT_ASSERT(node1 < node3);
  215. UNIT_ASSERT(node2 < node3);
  216. UNIT_ASSERT(node3 <= node3);
  217. UNIT_ASSERT(!(node3 < node3));
  218. UNIT_ASSERT(!(node3 > node3));
  219. UNIT_ASSERT(!(node2 >= node3));
  220. }
  221. }
  222. Y_UNIT_TEST(TestSaveLoad) {
  223. TNode node = TNode()("foo", "bar")("baz", 42);
  224. node.Attributes()["attr_name"] = "attr_value";
  225. TString bytes;
  226. {
  227. TStringOutput s(bytes);
  228. ::Save(&s, node);
  229. }
  230. TNode nodeCopy;
  231. {
  232. TStringInput s(bytes);
  233. ::Load(&s, nodeCopy);
  234. }
  235. UNIT_ASSERT_VALUES_EQUAL(node, nodeCopy);
  236. }
  237. Y_UNIT_TEST(TestIntCast) {
  238. TNode node = 1ull << 31;
  239. UNIT_ASSERT(node.IsUint64());
  240. UNIT_ASSERT_EXCEPTION(node.IntCast<i32>(), TNode::TTypeError);
  241. UNIT_ASSERT(node.IntCast<ui32>() == static_cast<ui32>(node.AsUint64()));
  242. UNIT_ASSERT(node.IntCast<i64>() == static_cast<i64>(node.AsUint64()));
  243. UNIT_ASSERT(node.IntCast<ui64>() == node.AsUint64());
  244. node = 1ull << 63;
  245. UNIT_ASSERT(node.IsUint64());
  246. UNIT_ASSERT_EXCEPTION(node.IntCast<i64>(), TNode::TTypeError);
  247. UNIT_ASSERT(node.IntCast<ui64>() == node.AsUint64());
  248. node = 12345;
  249. UNIT_ASSERT(node.IsInt64());
  250. UNIT_ASSERT_EXCEPTION(node.IntCast<i8>(), TNode::TTypeError);
  251. UNIT_ASSERT_EXCEPTION(node.IntCast<ui8>(), TNode::TTypeError);
  252. UNIT_ASSERT(node.IntCast<i16>() == static_cast<i16>(node.AsInt64()));
  253. UNIT_ASSERT(node.IntCast<ui16>() == static_cast<ui16>(node.AsInt64()));
  254. UNIT_ASSERT(node.IntCast<i32>() == static_cast<i32>(node.AsInt64()));
  255. UNIT_ASSERT(node.IntCast<ui32>() == static_cast<ui32>(node.AsInt64()));
  256. UNIT_ASSERT(node.IntCast<i64>() == node.AsInt64());
  257. UNIT_ASSERT(node.IntCast<ui64>() == static_cast<ui64>(node.AsInt64()));
  258. node = -5;
  259. UNIT_ASSERT(node.IsInt64());
  260. UNIT_ASSERT(node.IntCast<i8>() == static_cast<i8>(node.AsInt64()));
  261. UNIT_ASSERT(node.IntCast<i16>() == static_cast<i16>(node.AsInt64()));
  262. UNIT_ASSERT(node.IntCast<i32>() == static_cast<i32>(node.AsInt64()));
  263. UNIT_ASSERT(node.IntCast<i64>() == node.AsInt64());
  264. UNIT_ASSERT_EXCEPTION(node.IntCast<ui8>(), TNode::TTypeError);
  265. UNIT_ASSERT_EXCEPTION(node.IntCast<ui16>(), TNode::TTypeError);
  266. UNIT_ASSERT_EXCEPTION(node.IntCast<ui32>(), TNode::TTypeError);
  267. UNIT_ASSERT_EXCEPTION(node.IntCast<ui64>(), TNode::TTypeError);
  268. }
  269. Y_UNIT_TEST(TestConvertToString) {
  270. UNIT_ASSERT_VALUES_EQUAL(TNode(5).ConvertTo<TString>(), "5");
  271. UNIT_ASSERT_VALUES_EQUAL(TNode(123432423).ConvertTo<TString>(), "123432423");
  272. UNIT_ASSERT_VALUES_EQUAL(TNode(123456789012345678ll).ConvertTo<TString>(), "123456789012345678");
  273. UNIT_ASSERT_VALUES_EQUAL(TNode(123456789012345678ull).ConvertTo<TString>(), "123456789012345678");
  274. UNIT_ASSERT_VALUES_EQUAL(TNode(-123456789012345678ll).ConvertTo<TString>(), "-123456789012345678");
  275. UNIT_ASSERT_VALUES_EQUAL(TNode(true).ConvertTo<TString>(), "1");
  276. UNIT_ASSERT_VALUES_EQUAL(TNode(false).ConvertTo<TString>(), "0");
  277. UNIT_ASSERT_VALUES_EQUAL(TNode(5.3).ConvertTo<TString>(), "5.3");
  278. }
  279. Y_UNIT_TEST(TestConvertFromString) {
  280. UNIT_ASSERT_VALUES_EQUAL(TNode("123456789012345678").ConvertTo<ui64>(), 123456789012345678ull);
  281. UNIT_ASSERT_VALUES_EQUAL(TNode("123456789012345678").ConvertTo<i64>(), 123456789012345678);
  282. UNIT_ASSERT_VALUES_EQUAL(TNode(ToString(1ull << 63)).ConvertTo<ui64>(), 1ull << 63);
  283. UNIT_ASSERT_EXCEPTION(TNode(ToString(1ull << 63)).ConvertTo<i64>(), TFromStringException);
  284. UNIT_ASSERT_VALUES_EQUAL(TNode("5.34").ConvertTo<double>(), 5.34);
  285. }
  286. Y_UNIT_TEST(TestConvertDoubleInt) {
  287. UNIT_ASSERT_VALUES_EQUAL(TNode(5.3).ConvertTo<i8>(), 5);
  288. UNIT_ASSERT_VALUES_EQUAL(TNode(5.3).ConvertTo<ui8>(), 5);
  289. UNIT_ASSERT_VALUES_EQUAL(TNode(5.3).ConvertTo<i64>(), 5);
  290. UNIT_ASSERT_VALUES_EQUAL(TNode(5.3).ConvertTo<ui64>(), 5);
  291. UNIT_ASSERT_VALUES_EQUAL(TNode(-5.3).ConvertTo<i8>(), -5);
  292. UNIT_ASSERT_VALUES_EQUAL(TNode(-5.3).ConvertTo<i64>(), -5);
  293. UNIT_ASSERT_EXCEPTION(TNode(-5.3).ConvertTo<ui8>(), TNode::TTypeError);
  294. UNIT_ASSERT_EXCEPTION(TNode(-5.3).ConvertTo<ui64>(), TNode::TTypeError);
  295. UNIT_ASSERT_VALUES_EQUAL(TNode(127.0).ConvertTo<i8>(), 127);
  296. UNIT_ASSERT_EXCEPTION(TNode(128.0).ConvertTo<i8>(), TNode::TTypeError);
  297. UNIT_ASSERT_VALUES_EQUAL(TNode(255.0).ConvertTo<ui8>(), 255);
  298. UNIT_ASSERT_EXCEPTION(TNode(256.0).ConvertTo<ui8>(), TNode::TTypeError);
  299. UNIT_ASSERT_EXCEPTION(TNode(1e100).ConvertTo<i64>(), TNode::TTypeError);
  300. UNIT_ASSERT_EXCEPTION(TNode(1e100).ConvertTo<ui64>(), TNode::TTypeError);
  301. {
  302. double v = 1ull << 63;
  303. TNode node = v;
  304. UNIT_ASSERT(node.IsDouble());
  305. UNIT_ASSERT_EXCEPTION(node.ConvertTo<i64>(), TNode::TTypeError);
  306. UNIT_ASSERT_VALUES_EQUAL(node.ConvertTo<ui64>(), static_cast<ui64>(v));
  307. }
  308. {
  309. double v = (double)(1ull << 63) + (1ull << 63);
  310. TNode node = v;
  311. UNIT_ASSERT(node.IsDouble());
  312. UNIT_ASSERT_EXCEPTION(node.ConvertTo<i64>(), TNode::TTypeError);
  313. UNIT_ASSERT_EXCEPTION(node.ConvertTo<ui64>(), TNode::TTypeError);
  314. }
  315. UNIT_ASSERT_EXCEPTION(TNode(NAN).ConvertTo<ui64>(), TNode::TTypeError);
  316. UNIT_ASSERT_EXCEPTION(TNode(NAN).ConvertTo<i64>(), TNode::TTypeError);
  317. UNIT_ASSERT_EXCEPTION(TNode(INFINITY).ConvertTo<ui64>(), TNode::TTypeError);
  318. UNIT_ASSERT_EXCEPTION(TNode(INFINITY).ConvertTo<i64>(), TNode::TTypeError);
  319. }
  320. Y_UNIT_TEST(TestConvertToBool) {
  321. UNIT_ASSERT_VALUES_EQUAL(TNode("true").ConvertTo<bool>(), true);
  322. UNIT_ASSERT_VALUES_EQUAL(TNode("TRUE").ConvertTo<bool>(), true);
  323. UNIT_ASSERT_VALUES_EQUAL(TNode("false").ConvertTo<bool>(), false);
  324. UNIT_ASSERT_VALUES_EQUAL(TNode("FALSE").ConvertTo<bool>(), false);
  325. UNIT_ASSERT_VALUES_EQUAL(TNode(1).ConvertTo<bool>(), true);
  326. UNIT_ASSERT_VALUES_EQUAL(TNode(0).ConvertTo<bool>(), false);
  327. UNIT_ASSERT_EXCEPTION(TNode("random").ConvertTo<bool>(), TFromStringException);
  328. UNIT_ASSERT_EXCEPTION(TNode("").ConvertTo<bool>(), TFromStringException);
  329. }
  330. Y_UNIT_TEST(TestCanonicalSerialization) {
  331. auto node = TNode()
  332. ("ca", "ca")("c", "c")("a", "a")("b", "b")
  333. ("bb", TNode()
  334. ("ii", "ii")("i", "i")("jj", "jj"));
  335. node.Attributes() = TNode()("za", "za")("z", "z")("xxx", "xxx")("xx", "xx");
  336. UNIT_ASSERT_VALUES_EQUAL(NodeToCanonicalYsonString(node),
  337. "<\"xx\"=\"xx\";\"xxx\"=\"xxx\";\"z\"=\"z\";\"za\"=\"za\">"
  338. "{\"a\"=\"a\";\"b\"=\"b\";\"bb\"="
  339. "{\"i\"=\"i\";\"ii\"=\"ii\";\"jj\"=\"jj\"};"
  340. "\"c\"=\"c\";\"ca\"=\"ca\"}");
  341. }
  342. Y_UNIT_TEST(OperatorEqualSubnode) {
  343. TNode node;
  344. node["a"]["b"] = "c";
  345. node = node["a"];
  346. node = node["b"];
  347. UNIT_ASSERT_VALUES_EQUAL(node.AsString(), "c");
  348. }
  349. Y_UNIT_TEST(TestMapGetters) {
  350. auto node = TNode::CreateMap()
  351. ("string", "7")
  352. ("int64", 3)
  353. ("uint64", 5u)
  354. ("double", -3.5)
  355. ("list", TNode::CreateList().Add(5))
  356. ("map", TNode::CreateMap()("key", "value"));
  357. UNIT_ASSERT_VALUES_EQUAL(node.ChildAs<TString>("string"), "7");
  358. UNIT_ASSERT_VALUES_EQUAL(node.ChildAsString("string"), "7");
  359. UNIT_ASSERT_VALUES_EQUAL(node.ChildConvertTo<i64>("string"), 7);
  360. UNIT_ASSERT_VALUES_EQUAL(node.ChildAs<i64>("int64"), 3);
  361. UNIT_ASSERT_VALUES_EQUAL(node.ChildAsInt64("int64"), 3);
  362. UNIT_ASSERT_VALUES_EQUAL(node.ChildIntCast<ui64>("int64"), 3u);
  363. UNIT_ASSERT_VALUES_EQUAL(node.ChildAs<ui64>("uint64"), 5u);
  364. UNIT_ASSERT_VALUES_EQUAL(node.ChildAsUint64("uint64"), 5u);
  365. UNIT_ASSERT_VALUES_EQUAL(node.ChildIntCast<i64>("uint64"), 5);
  366. UNIT_ASSERT_VALUES_EQUAL(node.ChildConvertTo<TString>("uint64"), "5");
  367. UNIT_ASSERT_VALUES_EQUAL(node.ChildAs<double>("double"), -3.5);
  368. UNIT_ASSERT_VALUES_EQUAL(node.ChildAsDouble("double"), -3.5);
  369. UNIT_ASSERT_VALUES_EQUAL(node.ChildConvertTo<TString>("double"), "-3.5");
  370. UNIT_ASSERT_VALUES_EQUAL(node.ChildAs<TNode::TListType>("list")[0].AsInt64(), 5);
  371. UNIT_ASSERT_VALUES_EQUAL(node.ChildAsList("list")[0].AsInt64(), 5);
  372. UNIT_ASSERT_VALUES_EQUAL(node.ChildAs<TNode::TMapType>("map")["key"].AsString(), "value");
  373. UNIT_ASSERT_VALUES_EQUAL(node.ChildAsMap("map")["key"].AsString(), "value");
  374. // mutable accessor
  375. auto& childString = node.ChildAs<TString>("string");
  376. childString = "yaddayadda";
  377. UNIT_ASSERT_VALUES_EQUAL(node.ChildAs<TString>("string"), "yaddayadda");
  378. }
  379. Y_UNIT_TEST(TestListGetters) {
  380. auto node = TNode::CreateList()
  381. .Add("7")
  382. .Add(3)
  383. .Add(5u)
  384. .Add(-3.5)
  385. .Add(TNode::CreateList().Add(5))
  386. .Add(TNode::CreateMap()("key", "value"));
  387. UNIT_ASSERT_VALUES_EQUAL(node.ChildAs<TString>(0), "7");
  388. UNIT_ASSERT_VALUES_EQUAL(node.ChildAsString(0), "7");
  389. UNIT_ASSERT_VALUES_EQUAL(node.ChildConvertTo<i64>(0), 7);
  390. UNIT_ASSERT_VALUES_EQUAL(node.ChildAs<i64>(1), 3);
  391. UNIT_ASSERT_VALUES_EQUAL(node.ChildAsInt64(1), 3);
  392. UNIT_ASSERT_VALUES_EQUAL(node.ChildIntCast<ui64>(1), 3u);
  393. UNIT_ASSERT_VALUES_EQUAL(node.ChildAs<ui64>(2), 5u);
  394. UNIT_ASSERT_VALUES_EQUAL(node.ChildAsUint64(2), 5u);
  395. UNIT_ASSERT_VALUES_EQUAL(node.ChildIntCast<i64>(2), 5);
  396. UNIT_ASSERT_VALUES_EQUAL(node.ChildConvertTo<TString>(2), "5");
  397. UNIT_ASSERT_VALUES_EQUAL(node.ChildAs<double>(3), -3.5);
  398. UNIT_ASSERT_VALUES_EQUAL(node.ChildAsDouble(3), -3.5);
  399. UNIT_ASSERT_VALUES_EQUAL(node.ChildConvertTo<TString>(3), "-3.5");
  400. UNIT_ASSERT_VALUES_EQUAL(node.ChildAs<TNode::TListType>(4)[0].AsInt64(), 5);
  401. UNIT_ASSERT_VALUES_EQUAL(node.ChildAsList(4)[0].AsInt64(), 5);
  402. UNIT_ASSERT_VALUES_EQUAL(node.ChildAs<TNode::TMapType>(5)["key"].AsString(), "value");
  403. UNIT_ASSERT_VALUES_EQUAL(node.ChildAsMap(5)["key"].AsString(), "value");
  404. // mutable accessor
  405. auto& childString = node.ChildAs<TString>(0);
  406. childString = "yaddayadda";
  407. UNIT_ASSERT_VALUES_EQUAL(node.ChildAs<TString>(0), "yaddayadda");
  408. }
  409. }
  410. Y_UNIT_TEST_SUITE(YtNodeIoTest) {
  411. Y_UNIT_TEST(FromJson) {
  412. NYT::TNode node;
  413. node = NYT::NodeFromJsonString("1");
  414. UNIT_ASSERT_VALUES_EQUAL(node.ConvertTo<int>(), 1);
  415. UNIT_ASSERT(!NYT::TryNodeFromJsonString("", node));
  416. UNIT_ASSERT_VALUES_EQUAL(node.ConvertTo<int>(), 1);
  417. UNIT_ASSERT_EXCEPTION(NYT::NodeFromJsonString(""), yexception);
  418. UNIT_ASSERT_VALUES_EQUAL(node.ConvertTo<int>(), 1);
  419. }
  420. }