yaml-cpp

FORK: A YAML parser and emitter in C++
git clone https://git.neptards.moe/neptards/yaml-cpp.git
Log | Files | Refs | README | LICENSE

node_test.cpp (19266B)


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