You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

853 lines
21 KiB

3 months ago
  1. #include "yaml-cpp/node/node.h"
  2. #include "yaml-cpp/emitter.h"
  3. #include "yaml-cpp/node/convert.h"
  4. #include "yaml-cpp/node/detail/impl.h"
  5. #include "yaml-cpp/node/emit.h"
  6. #include "yaml-cpp/node/impl.h"
  7. #include "yaml-cpp/node/iterator.h"
  8. #include "gmock/gmock.h"
  9. #include "gtest/gtest.h"
  10. #include <sstream>
  11. namespace {
  12. // malloc/free based allocator just for testing custom allocators on stl containers
  13. template <class T>
  14. class CustomAllocator : public std::allocator<T> {
  15. public:
  16. typedef std::size_t size_type;
  17. typedef std::ptrdiff_t difference_type;
  18. typedef T* pointer;
  19. typedef const T* const_pointer;
  20. typedef T& reference;
  21. typedef const T& const_reference;
  22. typedef T value_type;
  23. template<class U> struct rebind { typedef CustomAllocator<U> other; };
  24. CustomAllocator() : std::allocator<T>() {}
  25. CustomAllocator(const CustomAllocator& other) : std::allocator<T>(other) {}
  26. template<class U> CustomAllocator(const CustomAllocator<U>& other) : std::allocator<T>(other) {}
  27. ~CustomAllocator() {}
  28. size_type max_size() const { return (std::numeric_limits<std::ptrdiff_t>::max)()/sizeof(T); }
  29. pointer allocate(size_type num, const void* /*hint*/ = 0) {
  30. if (num > std::size_t(-1) / sizeof(T)) throw std::bad_alloc();
  31. return static_cast<pointer>(malloc(num * sizeof(T)));
  32. }
  33. void deallocate(pointer p, size_type /*num*/) { free(p); }
  34. };
  35. template <class T> using CustomVector = std::vector<T,CustomAllocator<T>>;
  36. template <class T> using CustomList = std::list<T,CustomAllocator<T>>;
  37. template <class K, class V, class C=std::less<K>> using CustomMap = std::map<K,V,C,CustomAllocator<std::pair<const K,V>>>;
  38. template <class K, class V, class H=std::hash<K>, class P=std::equal_to<K>> using CustomUnorderedMap = std::unordered_map<K,V,H,P,CustomAllocator<std::pair<const K,V>>>;
  39. } // anonymous namespace
  40. using ::testing::AnyOf;
  41. using ::testing::Eq;
  42. #define EXPECT_THROW_REPRESENTATION_EXCEPTION(statement, message) \
  43. ASSERT_THROW(statement, RepresentationException); \
  44. try { \
  45. statement; \
  46. } catch (const RepresentationException& e) { \
  47. EXPECT_EQ(e.msg, message); \
  48. }
  49. namespace YAML {
  50. namespace {
  51. TEST(NodeTest, SimpleScalar) {
  52. Node node = Node("Hello, World!");
  53. EXPECT_TRUE(node.IsScalar());
  54. EXPECT_EQ("Hello, World!", node.as<std::string>());
  55. }
  56. TEST(NodeTest, IntScalar) {
  57. Node node = Node(15);
  58. EXPECT_TRUE(node.IsScalar());
  59. EXPECT_EQ(15, node.as<int>());
  60. }
  61. TEST(NodeTest, SimpleAppendSequence) {
  62. Node node;
  63. node.push_back(10);
  64. node.push_back("foo");
  65. node.push_back("monkey");
  66. EXPECT_TRUE(node.IsSequence());
  67. EXPECT_EQ(3, node.size());
  68. EXPECT_EQ(10, node[0].as<int>());
  69. EXPECT_EQ("foo", node[1].as<std::string>());
  70. EXPECT_EQ("monkey", node[2].as<std::string>());
  71. EXPECT_TRUE(node.IsSequence());
  72. }
  73. TEST(NodeTest, SequenceElementRemoval) {
  74. Node node;
  75. node[0] = "a";
  76. node[1] = "b";
  77. node[2] = "c";
  78. node.remove(1);
  79. EXPECT_TRUE(node.IsSequence());
  80. EXPECT_EQ(2, node.size());
  81. EXPECT_EQ("a", node[0].as<std::string>());
  82. EXPECT_EQ("c", node[1].as<std::string>());
  83. }
  84. TEST(NodeTest, SequenceElementRemovalSizeCheck) {
  85. Node node;
  86. node[0] = "a";
  87. node[1] = "b";
  88. node[2] = "c";
  89. EXPECT_EQ(3, node.size());
  90. node.remove(1);
  91. EXPECT_TRUE(node.IsSequence());
  92. EXPECT_EQ(2, node.size());
  93. EXPECT_EQ("a", node[0].as<std::string>());
  94. EXPECT_EQ("c", node[1].as<std::string>());
  95. }
  96. TEST(NodeTest, SequenceFirstElementRemoval) {
  97. Node node;
  98. node[0] = "a";
  99. node[1] = "b";
  100. node[2] = "c";
  101. node.remove(0);
  102. EXPECT_TRUE(node.IsSequence());
  103. EXPECT_EQ(2, node.size());
  104. EXPECT_EQ("b", node[0].as<std::string>());
  105. EXPECT_EQ("c", node[1].as<std::string>());
  106. }
  107. TEST(NodeTest, SequenceFirstElementRemovalSizeCheck) {
  108. Node node;
  109. node[0] = "a";
  110. node[1] = "b";
  111. node[2] = "c";
  112. EXPECT_EQ(3, node.size());
  113. node.remove(0);
  114. EXPECT_TRUE(node.IsSequence());
  115. EXPECT_EQ(2, node.size());
  116. EXPECT_EQ("b", node[0].as<std::string>());
  117. EXPECT_EQ("c", node[1].as<std::string>());
  118. }
  119. TEST(NodeTest, SequenceLastElementRemoval) {
  120. Node node;
  121. node[0] = "a";
  122. node[1] = "b";
  123. node[2] = "c";
  124. node.remove(2);
  125. EXPECT_TRUE(node.IsSequence());
  126. EXPECT_EQ(2, node.size());
  127. EXPECT_EQ("a", node[0].as<std::string>());
  128. EXPECT_EQ("b", node[1].as<std::string>());
  129. }
  130. TEST(NodeTest, SequenceLastElementRemovalSizeCheck) {
  131. Node node;
  132. node[0] = "a";
  133. node[1] = "b";
  134. node[2] = "c";
  135. EXPECT_EQ(3, node.size());
  136. node.remove(2);
  137. EXPECT_TRUE(node.IsSequence());
  138. EXPECT_EQ(2, node.size());
  139. EXPECT_EQ("a", node[0].as<std::string>());
  140. EXPECT_EQ("b", node[1].as<std::string>());
  141. }
  142. TEST(NodeTest, NodeAssignment) {
  143. Node node1;
  144. Node node2;
  145. node1[1] = 1;
  146. node1[2] = 2;
  147. node1[3] = 3;
  148. node2 = node1;
  149. EXPECT_EQ(node1, node2);
  150. EXPECT_EQ(node1[1], node2[1]);
  151. EXPECT_EQ(node1[2], node2[2]);
  152. EXPECT_EQ(node1[3], node2[3]);
  153. }
  154. TEST(NodeTest, EqualRepresentationAfterMoveAssignment) {
  155. Node node1;
  156. Node node2;
  157. std::ostringstream ss1, ss2;
  158. node1["foo"] = "bar";
  159. ss1 << node1;
  160. node2["hello"] = "world";
  161. node2 = std::move(node1);
  162. ss2 << node2;
  163. EXPECT_FALSE(node2["hello"]);
  164. EXPECT_EQ("bar", node2["foo"].as<std::string>());
  165. EXPECT_EQ(ss1.str(), ss2.str());
  166. }
  167. TEST(NodeTest, MapElementRemoval) {
  168. Node node;
  169. node["foo"] = "bar";
  170. node.remove("foo");
  171. EXPECT_TRUE(!node["foo"]);
  172. }
  173. TEST(NodeTest, MapIntegerElementRemoval) {
  174. Node node;
  175. node[1] = "hello";
  176. node[2] = 'c';
  177. node["foo"] = "bar";
  178. EXPECT_TRUE(node.IsMap());
  179. node.remove(1);
  180. EXPECT_TRUE(node.IsMap());
  181. }
  182. TEST(NodeTest, SimpleAssignSequence) {
  183. Node node;
  184. node[0] = 10;
  185. node[1] = "foo";
  186. node[2] = "monkey";
  187. EXPECT_TRUE(node.IsSequence());
  188. EXPECT_EQ(3, node.size());
  189. EXPECT_EQ(10, node[0].as<int>());
  190. EXPECT_EQ("foo", node[1].as<std::string>());
  191. EXPECT_EQ("monkey", node[2].as<std::string>());
  192. EXPECT_TRUE(node.IsSequence());
  193. }
  194. TEST(NodeTest, SimpleMap) {
  195. Node node;
  196. node["key"] = "value";
  197. EXPECT_TRUE(node.IsMap());
  198. EXPECT_EQ("value", node["key"].as<std::string>());
  199. EXPECT_EQ(1, node.size());
  200. }
  201. TEST(NodeTest, MapWithUndefinedValues) {
  202. Node node;
  203. node["key"] = "value";
  204. node["undefined"];
  205. EXPECT_TRUE(node.IsMap());
  206. EXPECT_EQ("value", node["key"].as<std::string>());
  207. EXPECT_EQ(1, node.size());
  208. node["undefined"] = "monkey";
  209. EXPECT_EQ("monkey", node["undefined"].as<std::string>());
  210. EXPECT_EQ(2, node.size());
  211. }
  212. TEST(NodeTest, SeqIntoMap) {
  213. Node node;
  214. node[0] = "test";
  215. node[1];
  216. node[2] = "value";
  217. EXPECT_TRUE(node.IsMap());
  218. EXPECT_EQ("test", node[0].as<std::string>());
  219. EXPECT_EQ("value", node[2].as<std::string>());
  220. EXPECT_EQ(2, node.size());
  221. }
  222. TEST(NodeTest, RemoveUnassignedNode) {
  223. Node node(NodeType::Map);
  224. node["key"];
  225. node.remove("key");
  226. EXPECT_EQ(0, node.size());
  227. }
  228. TEST(NodeTest, RemoveUnassignedNodeFromMap) {
  229. Node node(NodeType::Map);
  230. Node n;
  231. node[n];
  232. node.remove(n);
  233. EXPECT_EQ(0, node.size());
  234. }
  235. TEST(NodeTest, MapForceInsert) {
  236. Node node;
  237. Node k1("k1");
  238. Node k2("k2");
  239. Node v1("v1");
  240. Node v2("v2");
  241. node[k1] = v1;
  242. node[k2] = v1;
  243. EXPECT_TRUE(node.IsMap());
  244. EXPECT_EQ("v1", node["k1"].as<std::string>());
  245. EXPECT_EQ("v1", node["k2"].as<std::string>());
  246. EXPECT_EQ(2, node.size());
  247. node.force_insert(k2, v2);
  248. EXPECT_EQ("v1", node["k1"].as<std::string>());
  249. EXPECT_EQ("v1", node["k2"].as<std::string>());
  250. EXPECT_EQ(3, node.size());
  251. }
  252. TEST(NodeTest, UndefinedConstNodeWithFallback) {
  253. Node node;
  254. const Node& cn = node;
  255. EXPECT_EQ(cn["undefined"].as<int>(3), 3);
  256. }
  257. TEST(NodeTest, MapIteratorWithUndefinedValues) {
  258. Node node;
  259. node["key"] = "value";
  260. node["undefined"];
  261. std::size_t count = 0;
  262. for (const_iterator it = node.begin(); it != node.end(); ++it)
  263. count++;
  264. EXPECT_EQ(1, count);
  265. }
  266. TEST(NodeTest, ConstIteratorOnConstUndefinedNode) {
  267. Node node;
  268. const Node& cn = node;
  269. const Node& undefinedCn = cn["undefined"];
  270. std::size_t count = 0;
  271. for (const_iterator it = undefinedCn.begin(); it != undefinedCn.end(); ++it) {
  272. count++;
  273. }
  274. EXPECT_EQ(0, count);
  275. }
  276. TEST(NodeTest, IteratorOnConstUndefinedNode) {
  277. Node node;
  278. const Node& cn = node;
  279. const Node& undefinedCn = cn["undefined"];
  280. Node& nonConstUndefinedNode = const_cast<Node&>(undefinedCn);
  281. std::size_t count = 0;
  282. for (iterator it = nonConstUndefinedNode.begin();
  283. it != nonConstUndefinedNode.end(); ++it) {
  284. count++;
  285. }
  286. EXPECT_EQ(0, count);
  287. }
  288. TEST(NodeTest, InteratorOnSequence) {
  289. Node node;
  290. node[0] = "a";
  291. node[1] = "b";
  292. node[2] = "c";
  293. EXPECT_TRUE(node.IsSequence());
  294. std::size_t count = 0;
  295. for (iterator it = node.begin(); it != node.end(); ++it)
  296. {
  297. EXPECT_FALSE(it->IsNull());
  298. count++;
  299. }
  300. EXPECT_EQ(3, count);
  301. }
  302. TEST(NodeTest, ConstInteratorOnSequence) {
  303. Node node;
  304. node[0] = "a";
  305. node[1] = "b";
  306. node[2] = "c";
  307. EXPECT_TRUE(node.IsSequence());
  308. std::size_t count = 0;
  309. for (const_iterator it = node.begin(); it != node.end(); ++it)
  310. {
  311. EXPECT_FALSE(it->IsNull());
  312. count++;
  313. }
  314. EXPECT_EQ(3, count);
  315. }
  316. #if __cplusplus >= 201703L
  317. TEST(NodeTest, StdStringViewAsKey) {
  318. Node node;
  319. std::string_view key = "username";
  320. node[key] = "monkey";
  321. EXPECT_EQ("monkey", node[key].as<std::string>());
  322. }
  323. #endif
  324. TEST(NodeTest, SimpleSubkeys) {
  325. Node node;
  326. node["device"]["udid"] = "12345";
  327. node["device"]["name"] = "iPhone";
  328. node["device"]["os"] = "4.0";
  329. node["username"] = "monkey";
  330. EXPECT_EQ("12345", node["device"]["udid"].as<std::string>());
  331. EXPECT_EQ("iPhone", node["device"]["name"].as<std::string>());
  332. EXPECT_EQ("4.0", node["device"]["os"].as<std::string>());
  333. EXPECT_EQ("monkey", node["username"].as<std::string>());
  334. }
  335. TEST(NodeTest, StdArray) {
  336. std::array<int, 5> evens{{2, 4, 6, 8, 10}};
  337. Node node;
  338. node["evens"] = evens;
  339. std::array<int, 5> actualEvens = node["evens"].as<std::array<int, 5>>();
  340. EXPECT_EQ(evens, actualEvens);
  341. }
  342. TEST(NodeTest, StdArrayWrongSize) {
  343. std::array<int, 3> evens{{2, 4, 6}};
  344. Node node;
  345. node["evens"] = evens;
  346. EXPECT_THROW_REPRESENTATION_EXCEPTION(
  347. (node["evens"].as<std::array<int, 5>>()), ErrorMsg::BAD_CONVERSION);
  348. }
  349. TEST(NodeTest, StdValrray) {
  350. std::valarray<int> evens{{2, 4, 6, 8, 10}};
  351. Node node;
  352. node["evens"] = evens;
  353. std::valarray<int> actualEvens = node["evens"].as<std::valarray<int>>();
  354. for (int i = 0; i < evens.size(); ++i) {
  355. EXPECT_EQ(evens[i], actualEvens[i]);
  356. }
  357. }
  358. TEST(NodeTest, StdVector) {
  359. std::vector<int> primes;
  360. primes.push_back(2);
  361. primes.push_back(3);
  362. primes.push_back(5);
  363. primes.push_back(7);
  364. primes.push_back(11);
  365. primes.push_back(13);
  366. Node node;
  367. node["primes"] = primes;
  368. EXPECT_EQ(primes, node["primes"].as<std::vector<int>>());
  369. }
  370. TEST(NodeTest, StdVectorWithCustomAllocator) {
  371. CustomVector<int> primes;
  372. primes.push_back(2);
  373. primes.push_back(3);
  374. primes.push_back(5);
  375. primes.push_back(7);
  376. primes.push_back(11);
  377. primes.push_back(13);
  378. Node node;
  379. node["primes"] = primes;
  380. EXPECT_EQ(primes, node["primes"].as<CustomVector<int>>());
  381. }
  382. TEST(NodeTest, StdList) {
  383. std::list<int> primes;
  384. primes.push_back(2);
  385. primes.push_back(3);
  386. primes.push_back(5);
  387. primes.push_back(7);
  388. primes.push_back(11);
  389. primes.push_back(13);
  390. Node node;
  391. node["primes"] = primes;
  392. EXPECT_EQ(primes, node["primes"].as<std::list<int>>());
  393. }
  394. TEST(NodeTest, StdListWithCustomAllocator) {
  395. CustomList<int> primes;
  396. primes.push_back(2);
  397. primes.push_back(3);
  398. primes.push_back(5);
  399. primes.push_back(7);
  400. primes.push_back(11);
  401. primes.push_back(13);
  402. Node node;
  403. node["primes"] = primes;
  404. EXPECT_EQ(primes, node["primes"].as<CustomList<int>>());
  405. }
  406. TEST(NodeTest, StdMap) {
  407. std::map<int, int> squares;
  408. squares[0] = 0;
  409. squares[1] = 1;
  410. squares[2] = 4;
  411. squares[3] = 9;
  412. squares[4] = 16;
  413. Node node;
  414. node["squares"] = squares;
  415. std::map<int, int> actualSquares = node["squares"].as<std::map<int, int>>();
  416. EXPECT_EQ(squares, actualSquares);
  417. }
  418. TEST(NodeTest, StdMapWithCustomAllocator) {
  419. CustomMap<int,int> squares;
  420. squares[0] = 0;
  421. squares[1] = 1;
  422. squares[2] = 4;
  423. squares[3] = 9;
  424. squares[4] = 16;
  425. Node node;
  426. node["squares"] = squares;
  427. CustomMap<int,int> actualSquares = node["squares"].as<CustomMap<int,int>>();
  428. EXPECT_EQ(squares, actualSquares);
  429. }
  430. TEST(NodeTest, StdUnorderedMap) {
  431. std::unordered_map<int, int> squares;
  432. squares[0] = 0;
  433. squares[1] = 1;
  434. squares[2] = 4;
  435. squares[3] = 9;
  436. squares[4] = 16;
  437. Node node;
  438. node["squares"] = squares;
  439. std::unordered_map<int, int> actualSquares = node["squares"].as<std::unordered_map<int, int>>();
  440. EXPECT_EQ(squares, actualSquares);
  441. }
  442. TEST(NodeTest, StdUnorderedMapWithCustomAllocator) {
  443. CustomUnorderedMap<int,int> squares;
  444. squares[0] = 0;
  445. squares[1] = 1;
  446. squares[2] = 4;
  447. squares[3] = 9;
  448. squares[4] = 16;
  449. Node node;
  450. node["squares"] = squares;
  451. CustomUnorderedMap<int,int> actualSquares = node["squares"].as<CustomUnorderedMap<int,int>>();
  452. EXPECT_EQ(squares, actualSquares);
  453. }
  454. TEST(NodeTest, StdPair) {
  455. std::pair<int, std::string> p;
  456. p.first = 5;
  457. p.second = "five";
  458. Node node;
  459. node["pair"] = p;
  460. std::pair<int, std::string> actualP =
  461. node["pair"].as<std::pair<int, std::string>>();
  462. EXPECT_EQ(p, actualP);
  463. }
  464. TEST(NodeTest, SimpleAlias) {
  465. Node node;
  466. node["foo"] = "value";
  467. node["bar"] = node["foo"];
  468. EXPECT_EQ("value", node["foo"].as<std::string>());
  469. EXPECT_EQ("value", node["bar"].as<std::string>());
  470. EXPECT_EQ(node["bar"], node["foo"]);
  471. EXPECT_EQ(2, node.size());
  472. }
  473. TEST(NodeTest, AliasAsKey) {
  474. Node node;
  475. node["foo"] = "value";
  476. Node value = node["foo"];
  477. node[value] = "foo";
  478. EXPECT_EQ("value", node["foo"].as<std::string>());
  479. EXPECT_EQ("foo", node[value].as<std::string>());
  480. EXPECT_EQ("foo", node["value"].as<std::string>());
  481. EXPECT_EQ(2, node.size());
  482. }
  483. TEST(NodeTest, SelfReferenceSequence) {
  484. Node node;
  485. node[0] = node;
  486. EXPECT_TRUE(node.IsSequence());
  487. EXPECT_EQ(1, node.size());
  488. EXPECT_EQ(node, node[0]);
  489. EXPECT_EQ(node, node[0][0]);
  490. EXPECT_EQ(node[0], node[0][0]);
  491. }
  492. TEST(NodeTest, ValueSelfReferenceMap) {
  493. Node node;
  494. node["key"] = node;
  495. EXPECT_TRUE(node.IsMap());
  496. EXPECT_EQ(1, node.size());
  497. EXPECT_EQ(node, node["key"]);
  498. EXPECT_EQ(node, node["key"]["key"]);
  499. EXPECT_EQ(node["key"], node["key"]["key"]);
  500. }
  501. TEST(NodeTest, KeySelfReferenceMap) {
  502. Node node;
  503. node[node] = "value";
  504. EXPECT_TRUE(node.IsMap());
  505. EXPECT_EQ(1, node.size());
  506. EXPECT_EQ("value", node[node].as<std::string>());
  507. }
  508. TEST(NodeTest, SelfReferenceMap) {
  509. Node node;
  510. node[node] = node;
  511. EXPECT_TRUE(node.IsMap());
  512. EXPECT_EQ(1, node.size());
  513. EXPECT_EQ(node, node[node]);
  514. EXPECT_EQ(node, node[node][node]);
  515. EXPECT_EQ(node[node], node[node][node]);
  516. }
  517. TEST(NodeTest, TempMapVariable) {
  518. Node node;
  519. Node tmp = node["key"];
  520. tmp = "value";
  521. EXPECT_TRUE(node.IsMap());
  522. EXPECT_EQ(1, node.size());
  523. EXPECT_EQ("value", node["key"].as<std::string>());
  524. }
  525. TEST(NodeTest, TempMapVariableAlias) {
  526. Node node;
  527. Node tmp = node["key"];
  528. tmp = node["other"];
  529. node["other"] = "value";
  530. EXPECT_TRUE(node.IsMap());
  531. EXPECT_EQ(2, node.size());
  532. EXPECT_EQ("value", node["key"].as<std::string>());
  533. EXPECT_EQ("value", node["other"].as<std::string>());
  534. EXPECT_EQ(node["key"], node["other"]);
  535. }
  536. TEST(NodeTest, Bool) {
  537. Node node;
  538. node[true] = false;
  539. EXPECT_TRUE(node.IsMap());
  540. EXPECT_EQ(false, node[true].as<bool>());
  541. }
  542. TEST(NodeTest, AutoBoolConversion) {
  543. #ifdef _MSC_VER
  544. #pragma warning(disable : 4800)
  545. #endif
  546. Node node;
  547. node["foo"] = "bar";
  548. EXPECT_TRUE(static_cast<bool>(node["foo"]));
  549. EXPECT_TRUE(!node["monkey"]);
  550. EXPECT_TRUE(!!node["foo"]);
  551. }
  552. TEST(NodeTest, FloatingPrecisionFloat) {
  553. const float x = 0.123456789;
  554. Node node = Node(x);
  555. EXPECT_EQ(x, node.as<float>());
  556. }
  557. TEST(NodeTest, FloatingPrecisionPositiveInfinityFloat) {
  558. if (!std::numeric_limits<float>::has_infinity) {
  559. return;
  560. }
  561. const float x = std::numeric_limits<float>::infinity();
  562. Node node = Node(x);
  563. EXPECT_EQ(x, node.as<float>());
  564. }
  565. TEST(NodeTest, FloatingPrecisionNegativeInfinityFloat) {
  566. if (!std::numeric_limits<float>::has_infinity) {
  567. return;
  568. }
  569. const float x = -std::numeric_limits<float>::infinity();
  570. Node node = Node(x);
  571. EXPECT_EQ(x, node.as<float>());
  572. }
  573. TEST(NodeTest, FloatingPrecisionNanFloat) {
  574. if (!std::numeric_limits<float>::has_quiet_NaN) {
  575. return;
  576. }
  577. const float x = std::numeric_limits<float>::quiet_NaN();
  578. Node node = Node(x);
  579. EXPECT_TRUE(std::isnan(node.as<float>()));
  580. }
  581. TEST(NodeTest, FloatingPrecisionDouble) {
  582. const double x = 0.123456789;
  583. Node node = Node(x);
  584. EXPECT_EQ(x, node.as<double>());
  585. }
  586. TEST(NodeTest, FloatingPrecisionPositiveInfinityDouble) {
  587. if (!std::numeric_limits<double>::has_infinity) {
  588. return;
  589. }
  590. const double x = std::numeric_limits<double>::infinity();
  591. Node node = Node(x);
  592. EXPECT_EQ(x, node.as<float>());
  593. }
  594. TEST(NodeTest, FloatingPrecisionNegativeInfinityDouble) {
  595. if (!std::numeric_limits<double>::has_infinity) {
  596. return;
  597. }
  598. const double x = -std::numeric_limits<double>::infinity();
  599. Node node = Node(x);
  600. EXPECT_EQ(x, node.as<double>());
  601. }
  602. TEST(NodeTest, FloatingPrecisionNanDouble) {
  603. if (!std::numeric_limits<double>::has_quiet_NaN) {
  604. return;
  605. }
  606. const double x = std::numeric_limits<double>::quiet_NaN();
  607. Node node = Node(x);
  608. EXPECT_TRUE(std::isnan(node.as<double>()));
  609. }
  610. TEST(NodeTest, SpaceChar) {
  611. Node node = Node(' ');
  612. EXPECT_EQ(' ', node.as<char>());
  613. }
  614. TEST(NodeTest, CloneNull) {
  615. Node node;
  616. Node clone = Clone(node);
  617. EXPECT_EQ(NodeType::Null, clone.Type());
  618. }
  619. TEST(NodeTest, KeyNodeExitsScope) {
  620. Node node;
  621. {
  622. Node temp("Hello, world");
  623. node[temp] = 0;
  624. }
  625. for (Node::const_iterator it = node.begin(); it != node.end(); ++it) {
  626. (void)it;
  627. }
  628. }
  629. TEST(NodeTest, DefaultNodeStyle) {
  630. Node node;
  631. EXPECT_EQ(EmitterStyle::Default, node.Style());
  632. }
  633. TEST(NodeTest, AccessNonexistentKeyOnConstNode) {
  634. YAML::Node node;
  635. node["3"] = "4";
  636. const YAML::Node& other = node;
  637. ASSERT_FALSE(other["5"]);
  638. }
  639. class NodeEmitterTest : public ::testing::Test {
  640. protected:
  641. void ExpectOutput(const std::string& output, const Node& node) {
  642. Emitter emitter;
  643. emitter << node;
  644. ASSERT_TRUE(emitter.good());
  645. EXPECT_EQ(output, emitter.c_str());
  646. }
  647. void ExpectAnyOutput(const Node& node, const std::string& output1,
  648. const std::string& output2) {
  649. Emitter emitter;
  650. emitter << node;
  651. ASSERT_TRUE(emitter.good());
  652. EXPECT_THAT(emitter.c_str(), AnyOf(Eq(output1), Eq(output2)));
  653. }
  654. };
  655. TEST_F(NodeEmitterTest, SimpleFlowSeqNode) {
  656. Node node;
  657. node.SetStyle(EmitterStyle::Flow);
  658. node.push_back(1.5);
  659. node.push_back(2.25);
  660. node.push_back(3.125);
  661. ExpectOutput("[1.5, 2.25, 3.125]", node);
  662. }
  663. TEST_F(NodeEmitterTest, NestFlowSeqNode) {
  664. Node node, cell0, cell1;
  665. cell0.push_back(1.5);
  666. cell0.push_back(2.25);
  667. cell0.push_back(3.125);
  668. cell1.push_back(4.5);
  669. cell1.push_back(5.25);
  670. cell1.push_back(6.125);
  671. node.SetStyle(EmitterStyle::Flow);
  672. node.push_back(cell0);
  673. node.push_back(cell1);
  674. ExpectOutput("[[1.5, 2.25, 3.125], [4.5, 5.25, 6.125]]", node);
  675. }
  676. TEST_F(NodeEmitterTest, MixBlockFlowSeqNode) {
  677. Node node, cell0, cell1;
  678. cell0.SetStyle(EmitterStyle::Flow);
  679. cell0.push_back(1.5);
  680. cell0.push_back(2.25);
  681. cell0.push_back(3.125);
  682. cell1.push_back(4.5);
  683. cell1.push_back(5.25);
  684. cell1.push_back(6.125);
  685. node.SetStyle(EmitterStyle::Block);
  686. node.push_back(cell0);
  687. node.push_back(cell1);
  688. ExpectOutput("- [1.5, 2.25, 3.125]\n-\n - 4.5\n - 5.25\n - 6.125", node);
  689. }
  690. TEST_F(NodeEmitterTest, NestBlockFlowMapListNode) {
  691. Node node, mapNode, blockNode;
  692. node.push_back(1.5);
  693. node.push_back(2.25);
  694. node.push_back(3.125);
  695. mapNode.SetStyle(EmitterStyle::Flow);
  696. mapNode["position"] = node;
  697. blockNode.push_back(1.0625);
  698. blockNode.push_back(mapNode);
  699. ExpectOutput("- 1.0625\n- {position: [1.5, 2.25, 3.125]}", blockNode);
  700. }
  701. TEST_F(NodeEmitterTest, NestBlockMixMapListNode) {
  702. Node node, mapNode, blockNode;
  703. node.push_back(1.5);
  704. node.push_back(2.25);
  705. node.push_back(3.125);
  706. mapNode.SetStyle(EmitterStyle::Flow);
  707. mapNode["position"] = node;
  708. blockNode["scalar"] = 1.0625;
  709. blockNode["object"] = mapNode;
  710. ExpectAnyOutput(blockNode,
  711. "scalar: 1.0625\nobject: {position: [1.5, 2.25, 3.125]}",
  712. "object: {position: [1.5, 2.25, 3.125]}\nscalar: 1.5");
  713. }
  714. TEST_F(NodeEmitterTest, NestBlockMapListNode) {
  715. Node node, mapNode;
  716. node.push_back(1.5);
  717. node.push_back(2.25);
  718. node.push_back(3.125);
  719. mapNode.SetStyle(EmitterStyle::Block);
  720. mapNode["position"] = node;
  721. ExpectOutput("position:\n - 1.5\n - 2.25\n - 3.125", mapNode);
  722. }
  723. TEST_F(NodeEmitterTest, NestFlowMapListNode) {
  724. Node node, mapNode;
  725. node.push_back(1.5);
  726. node.push_back(2.25);
  727. node.push_back(3.125);
  728. mapNode.SetStyle(EmitterStyle::Flow);
  729. mapNode["position"] = node;
  730. ExpectOutput("{position: [1.5, 2.25, 3.125]}", mapNode);
  731. }
  732. }
  733. }