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_spec_test.cpp (38975B)


      1 #include "specexamples.h"
      2 #include "yaml-cpp/yaml.h"  // IWYU pragma: keep
      3 
      4 #include "gtest/gtest.h"
      5 
      6 #define EXPECT_THROW_PARSER_EXCEPTION(statement, message) \
      7   ASSERT_THROW(statement, ParserException);               \
      8   try {                                                   \
      9     statement;                                            \
     10   } catch (const ParserException& e) {                    \
     11     EXPECT_EQ(e.msg, message);                            \
     12   }
     13 
     14 namespace YAML {
     15 namespace {
     16 
     17 TEST(NodeSpecTest, Ex2_1_SeqScalars) {
     18   Node doc = Load(ex2_1);
     19   EXPECT_TRUE(doc.IsSequence());
     20   EXPECT_EQ(3, doc.size());
     21   EXPECT_EQ("Mark McGwire", doc[0].as<std::string>());
     22   EXPECT_EQ("Sammy Sosa", doc[1].as<std::string>());
     23   EXPECT_EQ("Ken Griffey", doc[2].as<std::string>());
     24 }
     25 
     26 TEST(NodeSpecTest, Ex2_2_MappingScalarsToScalars) {
     27   Node doc = Load(ex2_2);
     28   EXPECT_TRUE(doc.IsMap());
     29   EXPECT_EQ(3, doc.size());
     30   EXPECT_EQ("65", doc["hr"].as<std::string>());
     31   EXPECT_EQ("0.278", doc["avg"].as<std::string>());
     32   EXPECT_EQ("147", doc["rbi"].as<std::string>());
     33 }
     34 
     35 TEST(NodeSpecTest, Ex2_3_MappingScalarsToSequences) {
     36   Node doc = Load(ex2_3);
     37   EXPECT_TRUE(doc.IsMap());
     38   EXPECT_EQ(2, doc.size());
     39   EXPECT_EQ(3, doc["american"].size());
     40   EXPECT_EQ("Boston Red Sox", doc["american"][0].as<std::string>());
     41   EXPECT_EQ("Detroit Tigers", doc["american"][1].as<std::string>());
     42   EXPECT_EQ("New York Yankees", doc["american"][2].as<std::string>());
     43   EXPECT_EQ(3, doc["national"].size());
     44   EXPECT_EQ("New York Mets", doc["national"][0].as<std::string>());
     45   EXPECT_EQ("Chicago Cubs", doc["national"][1].as<std::string>());
     46   EXPECT_EQ("Atlanta Braves", doc["national"][2].as<std::string>());
     47 }
     48 
     49 TEST(NodeSpecTest, Ex2_4_SequenceOfMappings) {
     50   Node doc = Load(ex2_4);
     51   EXPECT_EQ(2, doc.size());
     52   EXPECT_EQ(3, doc[0].size());
     53   EXPECT_EQ("Mark McGwire", doc[0]["name"].as<std::string>());
     54   EXPECT_EQ("65", doc[0]["hr"].as<std::string>());
     55   EXPECT_EQ("0.278", doc[0]["avg"].as<std::string>());
     56   EXPECT_EQ(3, doc[1].size());
     57   EXPECT_EQ("Sammy Sosa", doc[1]["name"].as<std::string>());
     58   EXPECT_EQ("63", doc[1]["hr"].as<std::string>());
     59   EXPECT_EQ("0.288", doc[1]["avg"].as<std::string>());
     60 }
     61 
     62 TEST(NodeSpecTest, Ex2_5_SequenceOfSequences) {
     63   Node doc = Load(ex2_5);
     64   EXPECT_EQ(3, doc.size());
     65   EXPECT_EQ(3, doc[0].size());
     66   EXPECT_EQ("name", doc[0][0].as<std::string>());
     67   EXPECT_EQ("hr", doc[0][1].as<std::string>());
     68   EXPECT_EQ("avg", doc[0][2].as<std::string>());
     69   EXPECT_EQ(3, doc[1].size());
     70   EXPECT_EQ("Mark McGwire", doc[1][0].as<std::string>());
     71   EXPECT_EQ("65", doc[1][1].as<std::string>());
     72   EXPECT_EQ("0.278", doc[1][2].as<std::string>());
     73   EXPECT_EQ(3, doc[2].size());
     74   EXPECT_EQ("Sammy Sosa", doc[2][0].as<std::string>());
     75   EXPECT_EQ("63", doc[2][1].as<std::string>());
     76   EXPECT_EQ("0.288", doc[2][2].as<std::string>());
     77 }
     78 
     79 TEST(NodeSpecTest, Ex2_6_MappingOfMappings) {
     80   Node doc = Load(ex2_6);
     81   EXPECT_EQ(2, doc.size());
     82   EXPECT_EQ(2, doc["Mark McGwire"].size());
     83   EXPECT_EQ("65", doc["Mark McGwire"]["hr"].as<std::string>());
     84   EXPECT_EQ("0.278", doc["Mark McGwire"]["avg"].as<std::string>());
     85   EXPECT_EQ(2, doc["Sammy Sosa"].size());
     86   EXPECT_EQ("63", doc["Sammy Sosa"]["hr"].as<std::string>());
     87   EXPECT_EQ("0.288", doc["Sammy Sosa"]["avg"].as<std::string>());
     88 }
     89 
     90 TEST(NodeSpecTest, Ex2_7_TwoDocumentsInAStream) {
     91   std::vector<Node> docs = LoadAll(ex2_7);
     92   EXPECT_EQ(2, docs.size());
     93 
     94   {
     95     Node doc = docs[0];
     96     EXPECT_EQ(3, doc.size());
     97     EXPECT_EQ("Mark McGwire", doc[0].as<std::string>());
     98     EXPECT_EQ("Sammy Sosa", doc[1].as<std::string>());
     99     EXPECT_EQ("Ken Griffey", doc[2].as<std::string>());
    100   }
    101 
    102   {
    103     Node doc = docs[1];
    104     EXPECT_EQ(2, doc.size());
    105     EXPECT_EQ("Chicago Cubs", doc[0].as<std::string>());
    106     EXPECT_EQ("St Louis Cardinals", doc[1].as<std::string>());
    107   }
    108 }
    109 
    110 TEST(NodeSpecTest, Ex2_8_PlayByPlayFeed) {
    111   std::vector<Node> docs = LoadAll(ex2_8);
    112   EXPECT_EQ(2, docs.size());
    113 
    114   {
    115     Node doc = docs[0];
    116     EXPECT_EQ(3, doc.size());
    117     EXPECT_EQ("20:03:20", doc["time"].as<std::string>());
    118     EXPECT_EQ("Sammy Sosa", doc["player"].as<std::string>());
    119     EXPECT_EQ("strike (miss)", doc["action"].as<std::string>());
    120   }
    121 
    122   {
    123     Node doc = docs[1];
    124     EXPECT_EQ(3, doc.size());
    125     EXPECT_EQ("20:03:47", doc["time"].as<std::string>());
    126     EXPECT_EQ("Sammy Sosa", doc["player"].as<std::string>());
    127     EXPECT_EQ("grand slam", doc["action"].as<std::string>());
    128   }
    129 }
    130 
    131 TEST(NodeSpecTest, Ex2_9_SingleDocumentWithTwoComments) {
    132   Node doc = Load(ex2_9);
    133   EXPECT_EQ(2, doc.size());
    134   EXPECT_EQ(2, doc["hr"].size());
    135   EXPECT_EQ("Mark McGwire", doc["hr"][0].as<std::string>());
    136   EXPECT_EQ("Sammy Sosa", doc["hr"][1].as<std::string>());
    137   EXPECT_EQ(2, doc["rbi"].size());
    138   EXPECT_EQ("Sammy Sosa", doc["rbi"][0].as<std::string>());
    139   EXPECT_EQ("Ken Griffey", doc["rbi"][1].as<std::string>());
    140 }
    141 
    142 TEST(NodeSpecTest, Ex2_10_SimpleAnchor) {
    143   Node doc = Load(ex2_10);
    144   EXPECT_EQ(2, doc.size());
    145   EXPECT_EQ(2, doc["hr"].size());
    146   EXPECT_EQ("Mark McGwire", doc["hr"][0].as<std::string>());
    147   EXPECT_EQ("Sammy Sosa", doc["hr"][1].as<std::string>());
    148   EXPECT_EQ(2, doc["rbi"].size());
    149   EXPECT_EQ("Sammy Sosa", doc["rbi"][0].as<std::string>());
    150   EXPECT_EQ("Ken Griffey", doc["rbi"][1].as<std::string>());
    151 }
    152 
    153 TEST(NodeSpecTest, Ex2_11_MappingBetweenSequences) {
    154   Node doc = Load(ex2_11);
    155 
    156   std::vector<std::string> tigers_cubs;
    157   tigers_cubs.push_back("Detroit Tigers");
    158   tigers_cubs.push_back("Chicago cubs");
    159 
    160   std::vector<std::string> yankees_braves;
    161   yankees_braves.push_back("New York Yankees");
    162   yankees_braves.push_back("Atlanta Braves");
    163 
    164   EXPECT_EQ(2, doc.size());
    165   EXPECT_EQ(1, doc[tigers_cubs].size());
    166   EXPECT_EQ("2001-07-23", doc[tigers_cubs][0].as<std::string>());
    167   EXPECT_EQ(3, doc[yankees_braves].size());
    168   EXPECT_EQ("2001-07-02", doc[yankees_braves][0].as<std::string>());
    169   EXPECT_EQ("2001-08-12", doc[yankees_braves][1].as<std::string>());
    170   EXPECT_EQ("2001-08-14", doc[yankees_braves][2].as<std::string>());
    171 }
    172 
    173 TEST(NodeSpecTest, Ex2_12_CompactNestedMapping) {
    174   Node doc = Load(ex2_12);
    175   EXPECT_EQ(3, doc.size());
    176   EXPECT_EQ(2, doc[0].size());
    177   EXPECT_EQ("Super Hoop", doc[0]["item"].as<std::string>());
    178   EXPECT_EQ(1, doc[0]["quantity"].as<int>());
    179   EXPECT_EQ(2, doc[1].size());
    180   EXPECT_EQ("Basketball", doc[1]["item"].as<std::string>());
    181   EXPECT_EQ(4, doc[1]["quantity"].as<int>());
    182   EXPECT_EQ(2, doc[2].size());
    183   EXPECT_EQ("Big Shoes", doc[2]["item"].as<std::string>());
    184   EXPECT_EQ(1, doc[2]["quantity"].as<int>());
    185 }
    186 
    187 TEST(NodeSpecTest, Ex2_13_InLiteralsNewlinesArePreserved) {
    188   Node doc = Load(ex2_13);
    189   EXPECT_TRUE(doc.as<std::string>() ==
    190               "\\//||\\/||\n"
    191               "// ||  ||__");
    192 }
    193 
    194 TEST(NodeSpecTest, Ex2_14_InFoldedScalarsNewlinesBecomeSpaces) {
    195   Node doc = Load(ex2_14);
    196   EXPECT_TRUE(doc.as<std::string>() ==
    197               "Mark McGwire's year was crippled by a knee injury.");
    198 }
    199 
    200 TEST(NodeSpecTest,
    201      Ex2_15_FoldedNewlinesArePreservedForMoreIndentedAndBlankLines) {
    202   Node doc = Load(ex2_15);
    203   EXPECT_TRUE(doc.as<std::string>() ==
    204               "Sammy Sosa completed another fine season with great stats.\n\n"
    205               "  63 Home Runs\n"
    206               "  0.288 Batting Average\n\n"
    207               "What a year!");
    208 }
    209 
    210 TEST(NodeSpecTest, Ex2_16_IndentationDeterminesScope) {
    211   Node doc = Load(ex2_16);
    212   EXPECT_EQ(3, doc.size());
    213   EXPECT_EQ("Mark McGwire", doc["name"].as<std::string>());
    214   EXPECT_TRUE(doc["accomplishment"].as<std::string>() ==
    215               "Mark set a major league home run record in 1998.\n");
    216   EXPECT_TRUE(doc["stats"].as<std::string>() ==
    217               "65 Home Runs\n0.278 Batting Average\n");
    218 }
    219 
    220 TEST(NodeSpecTest, Ex2_17_QuotedScalars) {
    221   Node doc = Load(ex2_17);
    222   EXPECT_EQ(6, doc.size());
    223   EXPECT_EQ("Sosa did fine.\xe2\x98\xba", doc["unicode"].as<std::string>());
    224   EXPECT_EQ("\b1998\t1999\t2000\n", doc["control"].as<std::string>());
    225   EXPECT_EQ("\x0d\x0a is \r\n", doc["hex esc"].as<std::string>());
    226   EXPECT_EQ("\"Howdy!\" he cried.", doc["single"].as<std::string>());
    227   EXPECT_EQ(" # Not a 'comment'.", doc["quoted"].as<std::string>());
    228   EXPECT_EQ("|\\-*-/|", doc["tie-fighter"].as<std::string>());
    229 }
    230 
    231 TEST(NodeSpecTest, Ex2_18_MultiLineFlowScalars) {
    232   Node doc = Load(ex2_18);
    233   EXPECT_EQ(2, doc.size());
    234   EXPECT_TRUE(doc["plain"].as<std::string>() ==
    235               "This unquoted scalar spans many lines.");
    236   EXPECT_TRUE(doc["quoted"].as<std::string>() ==
    237               "So does this quoted scalar.\n");
    238 }
    239 
    240 // TODO: 2.19 - 2.22 schema tags
    241 
    242 TEST(NodeSpecTest, Ex2_23_VariousExplicitTags) {
    243   Node doc = Load(ex2_23);
    244   EXPECT_EQ(3, doc.size());
    245   EXPECT_EQ("tag:yaml.org,2002:str", doc["not-date"].Tag());
    246   EXPECT_EQ("2002-04-28", doc["not-date"].as<std::string>());
    247   EXPECT_EQ("tag:yaml.org,2002:binary", doc["picture"].Tag());
    248   EXPECT_TRUE(doc["picture"].as<std::string>() ==
    249               "R0lGODlhDAAMAIQAAP//9/X\n"
    250               "17unp5WZmZgAAAOfn515eXv\n"
    251               "Pz7Y6OjuDg4J+fn5OTk6enp\n"
    252               "56enmleECcgggoBADs=\n");
    253   EXPECT_EQ("!something", doc["application specific tag"].Tag());
    254   EXPECT_TRUE(doc["application specific tag"].as<std::string>() ==
    255               "The semantics of the tag\n"
    256               "above may be different for\n"
    257               "different documents.");
    258 }
    259 
    260 TEST(NodeSpecTest, Ex2_24_GlobalTags) {
    261   Node doc = Load(ex2_24);
    262   EXPECT_EQ("tag:clarkevans.com,2002:shape", doc.Tag());
    263   EXPECT_EQ(3, doc.size());
    264   EXPECT_EQ("tag:clarkevans.com,2002:circle", doc[0].Tag());
    265   EXPECT_EQ(2, doc[0].size());
    266   EXPECT_EQ(2, doc[0]["center"].size());
    267   EXPECT_EQ(73, doc[0]["center"]["x"].as<int>());
    268   EXPECT_EQ(129, doc[0]["center"]["y"].as<int>());
    269   EXPECT_EQ(7, doc[0]["radius"].as<int>());
    270   EXPECT_EQ("tag:clarkevans.com,2002:line", doc[1].Tag());
    271   EXPECT_EQ(2, doc[1].size());
    272   EXPECT_EQ(2, doc[1]["start"].size());
    273   EXPECT_EQ(73, doc[1]["start"]["x"].as<int>());
    274   EXPECT_EQ(129, doc[1]["start"]["y"].as<int>());
    275   EXPECT_EQ(2, doc[1]["finish"].size());
    276   EXPECT_EQ(89, doc[1]["finish"]["x"].as<int>());
    277   EXPECT_EQ(102, doc[1]["finish"]["y"].as<int>());
    278   EXPECT_EQ("tag:clarkevans.com,2002:label", doc[2].Tag());
    279   EXPECT_EQ(3, doc[2].size());
    280   EXPECT_EQ(2, doc[2]["start"].size());
    281   EXPECT_EQ(73, doc[2]["start"]["x"].as<int>());
    282   EXPECT_EQ(129, doc[2]["start"]["y"].as<int>());
    283   EXPECT_EQ("0xFFEEBB", doc[2]["color"].as<std::string>());
    284   EXPECT_EQ("Pretty vector drawing.", doc[2]["text"].as<std::string>());
    285 }
    286 
    287 TEST(NodeSpecTest, Ex2_25_UnorderedSets) {
    288   Node doc = Load(ex2_25);
    289   EXPECT_EQ("tag:yaml.org,2002:set", doc.Tag());
    290   EXPECT_EQ(3, doc.size());
    291   EXPECT_TRUE(doc["Mark McGwire"].IsNull());
    292   EXPECT_TRUE(doc["Sammy Sosa"].IsNull());
    293   EXPECT_TRUE(doc["Ken Griffey"].IsNull());
    294 }
    295 
    296 TEST(NodeSpecTest, Ex2_16_OrderedMappings) {
    297   Node doc = Load(ex2_26);
    298   EXPECT_EQ("tag:yaml.org,2002:omap", doc.Tag());
    299   EXPECT_EQ(3, doc.size());
    300   EXPECT_EQ(1, doc[0].size());
    301   EXPECT_EQ(65, doc[0]["Mark McGwire"].as<int>());
    302   EXPECT_EQ(1, doc[1].size());
    303   EXPECT_EQ(63, doc[1]["Sammy Sosa"].as<int>());
    304   EXPECT_EQ(1, doc[2].size());
    305   EXPECT_EQ(58, doc[2]["Ken Griffey"].as<int>());
    306 }
    307 
    308 TEST(NodeSpecTest, Ex2_27_Invoice) {
    309   Node doc = Load(ex2_27);
    310   EXPECT_EQ("tag:clarkevans.com,2002:invoice", doc.Tag());
    311   EXPECT_EQ(8, doc.size());
    312   EXPECT_EQ(34843, doc["invoice"].as<int>());
    313   EXPECT_EQ("2001-01-23", doc["date"].as<std::string>());
    314   EXPECT_EQ(3, doc["bill-to"].size());
    315   EXPECT_EQ("Chris", doc["bill-to"]["given"].as<std::string>());
    316   EXPECT_EQ("Dumars", doc["bill-to"]["family"].as<std::string>());
    317   EXPECT_EQ(4, doc["bill-to"]["address"].size());
    318   EXPECT_TRUE(doc["bill-to"]["address"]["lines"].as<std::string>() ==
    319               "458 Walkman Dr.\nSuite #292\n");
    320   EXPECT_TRUE(doc["bill-to"]["address"]["city"].as<std::string>() ==
    321               "Royal Oak");
    322   EXPECT_EQ("MI", doc["bill-to"]["address"]["state"].as<std::string>());
    323   EXPECT_EQ("48046", doc["bill-to"]["address"]["postal"].as<std::string>());
    324   EXPECT_EQ(3, doc["ship-to"].size());
    325   EXPECT_EQ("Chris", doc["ship-to"]["given"].as<std::string>());
    326   EXPECT_EQ("Dumars", doc["ship-to"]["family"].as<std::string>());
    327   EXPECT_EQ(4, doc["ship-to"]["address"].size());
    328   EXPECT_TRUE(doc["ship-to"]["address"]["lines"].as<std::string>() ==
    329               "458 Walkman Dr.\nSuite #292\n");
    330   EXPECT_TRUE(doc["ship-to"]["address"]["city"].as<std::string>() ==
    331               "Royal Oak");
    332   EXPECT_EQ("MI", doc["ship-to"]["address"]["state"].as<std::string>());
    333   EXPECT_EQ("48046", doc["ship-to"]["address"]["postal"].as<std::string>());
    334   EXPECT_EQ(2, doc["product"].size());
    335   EXPECT_EQ(4, doc["product"][0].size());
    336   EXPECT_EQ("BL394D", doc["product"][0]["sku"].as<std::string>());
    337   EXPECT_EQ(4, doc["product"][0]["quantity"].as<int>());
    338   EXPECT_TRUE(doc["product"][0]["description"].as<std::string>() ==
    339               "Basketball");
    340   EXPECT_EQ("450.00", doc["product"][0]["price"].as<std::string>());
    341   EXPECT_EQ(4, doc["product"][1].size());
    342   EXPECT_EQ("BL4438H", doc["product"][1]["sku"].as<std::string>());
    343   EXPECT_EQ(1, doc["product"][1]["quantity"].as<int>());
    344   EXPECT_TRUE(doc["product"][1]["description"].as<std::string>() ==
    345               "Super Hoop");
    346   EXPECT_EQ("2392.00", doc["product"][1]["price"].as<std::string>());
    347   EXPECT_EQ("251.42", doc["tax"].as<std::string>());
    348   EXPECT_EQ("4443.52", doc["total"].as<std::string>());
    349   EXPECT_EQ(
    350       "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.",
    351       doc["comments"].as<std::string>());
    352 }
    353 
    354 TEST(NodeSpecTest, Ex2_28_LogFile) {
    355   std::vector<Node> docs = LoadAll(ex2_28);
    356   EXPECT_EQ(3, docs.size());
    357 
    358   {
    359     Node doc = docs[0];
    360     EXPECT_EQ(3, doc.size());
    361     EXPECT_EQ("2001-11-23 15:01:42 -5", doc["Time"].as<std::string>());
    362     EXPECT_EQ("ed", doc["User"].as<std::string>());
    363     EXPECT_TRUE(doc["Warning"].as<std::string>() ==
    364                 "This is an error message for the log file");
    365   }
    366 
    367   {
    368     Node doc = docs[1];
    369     EXPECT_EQ(3, doc.size());
    370     EXPECT_EQ("2001-11-23 15:02:31 -5", doc["Time"].as<std::string>());
    371     EXPECT_EQ("ed", doc["User"].as<std::string>());
    372     EXPECT_TRUE(doc["Warning"].as<std::string>() ==
    373                 "A slightly different error message.");
    374   }
    375 
    376   {
    377     Node doc = docs[2];
    378     EXPECT_EQ(4, doc.size());
    379     EXPECT_EQ("2001-11-23 15:03:17 -5", doc["Date"].as<std::string>());
    380     EXPECT_EQ("ed", doc["User"].as<std::string>());
    381     EXPECT_EQ("Unknown variable \"bar\"", doc["Fatal"].as<std::string>());
    382     EXPECT_EQ(2, doc["Stack"].size());
    383     EXPECT_EQ(3, doc["Stack"][0].size());
    384     EXPECT_EQ("TopClass.py", doc["Stack"][0]["file"].as<std::string>());
    385     EXPECT_EQ("23", doc["Stack"][0]["line"].as<std::string>());
    386     EXPECT_TRUE(doc["Stack"][0]["code"].as<std::string>() ==
    387                 "x = MoreObject(\"345\\n\")\n");
    388     EXPECT_EQ(3, doc["Stack"][1].size());
    389     EXPECT_EQ("MoreClass.py", doc["Stack"][1]["file"].as<std::string>());
    390     EXPECT_EQ("58", doc["Stack"][1]["line"].as<std::string>());
    391     EXPECT_EQ("foo = bar", doc["Stack"][1]["code"].as<std::string>());
    392   }
    393 }
    394 
    395 // TODO: 5.1 - 5.2 BOM
    396 
    397 TEST(NodeSpecTest, Ex5_3_BlockStructureIndicators) {
    398   Node doc = Load(ex5_3);
    399   EXPECT_EQ(2, doc.size());
    400   EXPECT_EQ(2, doc["sequence"].size());
    401   EXPECT_EQ("one", doc["sequence"][0].as<std::string>());
    402   EXPECT_EQ("two", doc["sequence"][1].as<std::string>());
    403   EXPECT_EQ(2, doc["mapping"].size());
    404   EXPECT_EQ("blue", doc["mapping"]["sky"].as<std::string>());
    405   EXPECT_EQ("green", doc["mapping"]["sea"].as<std::string>());
    406 }
    407 
    408 TEST(NodeSpecTest, Ex5_4_FlowStructureIndicators) {
    409   Node doc = Load(ex5_4);
    410   EXPECT_EQ(2, doc.size());
    411   EXPECT_EQ(2, doc["sequence"].size());
    412   EXPECT_EQ("one", doc["sequence"][0].as<std::string>());
    413   EXPECT_EQ("two", doc["sequence"][1].as<std::string>());
    414   EXPECT_EQ(2, doc["mapping"].size());
    415   EXPECT_EQ("blue", doc["mapping"]["sky"].as<std::string>());
    416   EXPECT_EQ("green", doc["mapping"]["sea"].as<std::string>());
    417 }
    418 
    419 TEST(NodeSpecTest, Ex5_5_CommentIndicator) {
    420   Node doc = Load(ex5_5);
    421   EXPECT_TRUE(doc.IsNull());
    422 }
    423 
    424 TEST(NodeSpecTest, Ex5_6_NodePropertyIndicators) {
    425   Node doc = Load(ex5_6);
    426   EXPECT_EQ(2, doc.size());
    427   EXPECT_TRUE(doc["anchored"].as<std::string>() ==
    428               "value");  // TODO: assert tag
    429   EXPECT_EQ("value", doc["alias"].as<std::string>());
    430 }
    431 
    432 TEST(NodeSpecTest, Ex5_7_BlockScalarIndicators) {
    433   Node doc = Load(ex5_7);
    434   EXPECT_EQ(2, doc.size());
    435   EXPECT_EQ("some\ntext\n", doc["literal"].as<std::string>());
    436   EXPECT_EQ("some text\n", doc["folded"].as<std::string>());
    437 }
    438 
    439 TEST(NodeSpecTest, Ex5_8_QuotedScalarIndicators) {
    440   Node doc = Load(ex5_8);
    441   EXPECT_EQ(2, doc.size());
    442   EXPECT_EQ("text", doc["single"].as<std::string>());
    443   EXPECT_EQ("text", doc["double"].as<std::string>());
    444 }
    445 
    446 // TODO: 5.9 directive
    447 // TODO: 5.10 reserved indicator
    448 
    449 TEST(NodeSpecTest, Ex5_11_LineBreakCharacters) {
    450   Node doc = Load(ex5_11);
    451   EXPECT_TRUE(doc.as<std::string>() ==
    452               "Line break (no glyph)\nLine break (glyphed)\n");
    453 }
    454 
    455 TEST(NodeSpecTest, Ex5_12_TabsAndSpaces) {
    456   Node doc = Load(ex5_12);
    457   EXPECT_EQ(2, doc.size());
    458   EXPECT_EQ("Quoted\t", doc["quoted"].as<std::string>());
    459   EXPECT_TRUE(doc["block"].as<std::string>() ==
    460               "void main() {\n"
    461               "\tprintf(\"Hello, world!\\n\");\n"
    462               "}");
    463 }
    464 
    465 TEST(NodeSpecTest, Ex5_13_EscapedCharacters) {
    466   Node doc = Load(ex5_13);
    467   EXPECT_TRUE(doc.as<std::string>() ==
    468               "Fun with \x5C \x22 \x07 \x08 \x1B \x0C \x0A \x0D \x09 \x0B " +
    469                   std::string("\x00", 1) +
    470                   " \x20 \xA0 \x85 \xe2\x80\xa8 \xe2\x80\xa9 A A A");
    471 }
    472 
    473 TEST(NodeSpecTest, Ex5_14_InvalidEscapedCharacters) {
    474   EXPECT_THROW_PARSER_EXCEPTION(Load(ex5_14),
    475                                 std::string(ErrorMsg::INVALID_ESCAPE) + "c");
    476 }
    477 
    478 TEST(NodeSpecTest, Ex6_1_IndentationSpaces) {
    479   Node doc = Load(ex6_1);
    480   EXPECT_EQ(1, doc.size());
    481   EXPECT_EQ(2, doc["Not indented"].size());
    482   EXPECT_TRUE(doc["Not indented"]["By one space"].as<std::string>() ==
    483               "By four\n  spaces\n");
    484   EXPECT_EQ(3, doc["Not indented"]["Flow style"].size());
    485   EXPECT_TRUE(doc["Not indented"]["Flow style"][0].as<std::string>() ==
    486               "By two");
    487   EXPECT_TRUE(doc["Not indented"]["Flow style"][1].as<std::string>() ==
    488               "Also by two");
    489   EXPECT_TRUE(doc["Not indented"]["Flow style"][2].as<std::string>() ==
    490               "Still by two");
    491 }
    492 
    493 TEST(NodeSpecTest, Ex6_2_IndentationIndicators) {
    494   Node doc = Load(ex6_2);
    495   EXPECT_EQ(1, doc.size());
    496   EXPECT_EQ(2, doc["a"].size());
    497   EXPECT_EQ("b", doc["a"][0].as<std::string>());
    498   EXPECT_EQ(2, doc["a"][1].size());
    499   EXPECT_EQ("c", doc["a"][1][0].as<std::string>());
    500   EXPECT_EQ("d", doc["a"][1][1].as<std::string>());
    501 }
    502 
    503 TEST(NodeSpecTest, Ex6_3_SeparationSpaces) {
    504   Node doc = Load(ex6_3);
    505   EXPECT_EQ(2, doc.size());
    506   EXPECT_EQ(1, doc[0].size());
    507   EXPECT_EQ("bar", doc[0]["foo"].as<std::string>());
    508   EXPECT_EQ(2, doc[1].size());
    509   EXPECT_EQ("baz", doc[1][0].as<std::string>());
    510   EXPECT_EQ("baz", doc[1][1].as<std::string>());
    511 }
    512 
    513 TEST(NodeSpecTest, Ex6_4_LinePrefixes) {
    514   Node doc = Load(ex6_4);
    515   EXPECT_EQ(3, doc.size());
    516   EXPECT_EQ("text lines", doc["plain"].as<std::string>());
    517   EXPECT_EQ("text lines", doc["quoted"].as<std::string>());
    518   EXPECT_EQ("text\n \tlines\n", doc["block"].as<std::string>());
    519 }
    520 
    521 TEST(NodeSpecTest, Ex6_5_EmptyLines) {
    522   Node doc = Load(ex6_5);
    523   EXPECT_EQ(2, doc.size());
    524   EXPECT_EQ("Empty line\nas a line feed", doc["Folding"].as<std::string>());
    525   EXPECT_EQ("Clipped empty lines\n", doc["Chomping"].as<std::string>());
    526 }
    527 
    528 TEST(NodeSpecTest, Ex6_6_LineFolding) {
    529   Node doc = Load(ex6_6);
    530   EXPECT_EQ("trimmed\n\n\nas space", doc.as<std::string>());
    531 }
    532 
    533 TEST(NodeSpecTest, Ex6_7_BlockFolding) {
    534   Node doc = Load(ex6_7);
    535   EXPECT_EQ("foo \n\n\t bar\n\nbaz\n", doc.as<std::string>());
    536 }
    537 
    538 TEST(NodeSpecTest, Ex6_8_FlowFolding) {
    539   Node doc = Load(ex6_8);
    540   EXPECT_EQ(" foo\nbar\nbaz ", doc.as<std::string>());
    541 }
    542 
    543 TEST(NodeSpecTest, Ex6_9_SeparatedComment) {
    544   Node doc = Load(ex6_9);
    545   EXPECT_EQ(1, doc.size());
    546   EXPECT_EQ("value", doc["key"].as<std::string>());
    547 }
    548 
    549 TEST(NodeSpecTest, Ex6_10_CommentLines) {
    550   Node doc = Load(ex6_10);
    551   EXPECT_TRUE(doc.IsNull());
    552 }
    553 
    554 TEST(NodeSpecTest, Ex6_11_MultiLineComments) {
    555   Node doc = Load(ex6_11);
    556   EXPECT_EQ(1, doc.size());
    557   EXPECT_EQ("value", doc["key"].as<std::string>());
    558 }
    559 
    560 TEST(NodeSpecTest, Ex6_12_SeparationSpacesII) {
    561   Node doc = Load(ex6_12);
    562 
    563   std::map<std::string, std::string> sammy;
    564   sammy["first"] = "Sammy";
    565   sammy["last"] = "Sosa";
    566 
    567   EXPECT_EQ(1, doc.size());
    568   EXPECT_EQ(2, doc[sammy].size());
    569   EXPECT_EQ(65, doc[sammy]["hr"].as<int>());
    570   EXPECT_EQ("0.278", doc[sammy]["avg"].as<std::string>());
    571 }
    572 
    573 TEST(NodeSpecTest, Ex6_13_ReservedDirectives) {
    574   Node doc = Load(ex6_13);
    575   EXPECT_EQ("foo", doc.as<std::string>());
    576 }
    577 
    578 TEST(NodeSpecTest, Ex6_14_YAMLDirective) {
    579   Node doc = Load(ex6_14);
    580   EXPECT_EQ("foo", doc.as<std::string>());
    581 }
    582 
    583 TEST(NodeSpecTest, Ex6_15_InvalidRepeatedYAMLDirective) {
    584   EXPECT_THROW_PARSER_EXCEPTION(Load(ex6_15),
    585                                 ErrorMsg::REPEATED_YAML_DIRECTIVE);
    586 }
    587 
    588 TEST(NodeSpecTest, Ex6_16_TagDirective) {
    589   Node doc = Load(ex6_16);
    590   EXPECT_EQ("tag:yaml.org,2002:str", doc.Tag());
    591   EXPECT_EQ("foo", doc.as<std::string>());
    592 }
    593 
    594 TEST(NodeSpecTest, Ex6_17_InvalidRepeatedTagDirective) {
    595   EXPECT_THROW_PARSER_EXCEPTION(Load(ex6_17), ErrorMsg::REPEATED_TAG_DIRECTIVE);
    596 }
    597 
    598 TEST(NodeSpecTest, Ex6_18_PrimaryTagHandle) {
    599   std::vector<Node> docs = LoadAll(ex6_18);
    600   EXPECT_EQ(2, docs.size());
    601 
    602   {
    603     Node doc = docs[0];
    604     EXPECT_EQ("!foo", doc.Tag());
    605     EXPECT_EQ("bar", doc.as<std::string>());
    606   }
    607 
    608   {
    609     Node doc = docs[1];
    610     EXPECT_EQ("tag:example.com,2000:app/foo", doc.Tag());
    611     EXPECT_EQ("bar", doc.as<std::string>());
    612   }
    613 }
    614 
    615 TEST(NodeSpecTest, Ex6_19_SecondaryTagHandle) {
    616   Node doc = Load(ex6_19);
    617   EXPECT_EQ("tag:example.com,2000:app/int", doc.Tag());
    618   EXPECT_EQ("1 - 3", doc.as<std::string>());
    619 }
    620 
    621 TEST(NodeSpecTest, Ex6_20_TagHandles) {
    622   Node doc = Load(ex6_20);
    623   EXPECT_EQ("tag:example.com,2000:app/foo", doc.Tag());
    624   EXPECT_EQ("bar", doc.as<std::string>());
    625 }
    626 
    627 TEST(NodeSpecTest, Ex6_21_LocalTagPrefix) {
    628   std::vector<Node> docs = LoadAll(ex6_21);
    629   EXPECT_EQ(2, docs.size());
    630 
    631   {
    632     Node doc = docs[0];
    633     EXPECT_EQ("!my-light", doc.Tag());
    634     EXPECT_EQ("fluorescent", doc.as<std::string>());
    635   }
    636 
    637   {
    638     Node doc = docs[1];
    639     EXPECT_EQ("!my-light", doc.Tag());
    640     EXPECT_EQ("green", doc.as<std::string>());
    641   }
    642 }
    643 
    644 TEST(NodeSpecTest, Ex6_22_GlobalTagPrefix) {
    645   Node doc = Load(ex6_22);
    646   EXPECT_EQ(1, doc.size());
    647   EXPECT_EQ("tag:example.com,2000:app/foo", doc[0].Tag());
    648   EXPECT_EQ("bar", doc[0].as<std::string>());
    649 }
    650 
    651 TEST(NodeSpecTest, Ex6_23_NodeProperties) {
    652   Node doc = Load(ex6_23);
    653   EXPECT_EQ(2, doc.size());
    654   for (const_iterator it = doc.begin(); it != doc.end(); ++it) {
    655     if (it->first.as<std::string>() == "foo") {
    656       EXPECT_EQ("tag:yaml.org,2002:str", it->first.Tag());
    657       EXPECT_EQ("tag:yaml.org,2002:str", it->second.Tag());
    658       EXPECT_EQ("bar", it->second.as<std::string>());
    659     } else if (it->first.as<std::string>() == "baz") {
    660       EXPECT_EQ("foo", it->second.as<std::string>());
    661     } else
    662       FAIL() << "unknown key";
    663   }
    664 }
    665 
    666 TEST(NodeSpecTest, Ex6_24_VerbatimTags) {
    667   Node doc = Load(ex6_24);
    668   EXPECT_EQ(1, doc.size());
    669   for (const_iterator it = doc.begin(); it != doc.end(); ++it) {
    670     EXPECT_EQ("tag:yaml.org,2002:str", it->first.Tag());
    671     EXPECT_EQ("foo", it->first.as<std::string>());
    672     EXPECT_EQ("!bar", it->second.Tag());
    673     EXPECT_EQ("baz", it->second.as<std::string>());
    674   }
    675 }
    676 
    677 TEST(NodeSpecTest, DISABLED_Ex6_25_InvalidVerbatimTags) {
    678   Node doc = Load(ex6_25);
    679   // TODO: check tags (but we probably will say these are valid, I think)
    680   FAIL() << "not implemented yet";
    681 }
    682 
    683 TEST(NodeSpecTest, Ex6_26_TagShorthands) {
    684   Node doc = Load(ex6_26);
    685   EXPECT_EQ(3, doc.size());
    686   EXPECT_EQ("!local", doc[0].Tag());
    687   EXPECT_EQ("foo", doc[0].as<std::string>());
    688   EXPECT_EQ("tag:yaml.org,2002:str", doc[1].Tag());
    689   EXPECT_EQ("bar", doc[1].as<std::string>());
    690   EXPECT_EQ("tag:example.com,2000:app/tag%21", doc[2].Tag());
    691   EXPECT_EQ("baz", doc[2].as<std::string>());
    692 }
    693 
    694 TEST(NodeSpecTest, Ex6_27a_InvalidTagShorthands) {
    695   EXPECT_THROW_PARSER_EXCEPTION(Load(ex6_27a), ErrorMsg::TAG_WITH_NO_SUFFIX);
    696 }
    697 
    698 // TODO: should we reject this one (since !h! is not declared)?
    699 TEST(NodeSpecTest, DISABLED_Ex6_27b_InvalidTagShorthands) {
    700   Load(ex6_27b);
    701   FAIL() << "not implemented yet";
    702 }
    703 
    704 TEST(NodeSpecTest, Ex6_28_NonSpecificTags) {
    705   Node doc = Load(ex6_28);
    706   EXPECT_EQ(3, doc.size());
    707   EXPECT_EQ("12", doc[0].as<std::string>());  // TODO: check tags. How?
    708   EXPECT_EQ(12, doc[1].as<int>());
    709   EXPECT_EQ("12", doc[2].as<std::string>());
    710 }
    711 
    712 TEST(NodeSpecTest, Ex6_29_NodeAnchors) {
    713   Node doc = Load(ex6_29);
    714   EXPECT_EQ(2, doc.size());
    715   EXPECT_EQ("Value", doc["First occurrence"].as<std::string>());
    716   EXPECT_EQ("Value", doc["Second occurrence"].as<std::string>());
    717 }
    718 
    719 TEST(NodeSpecTest, Ex7_1_AliasNodes) {
    720   Node doc = Load(ex7_1);
    721   EXPECT_EQ(4, doc.size());
    722   EXPECT_EQ("Foo", doc["First occurrence"].as<std::string>());
    723   EXPECT_EQ("Foo", doc["Second occurrence"].as<std::string>());
    724   EXPECT_EQ("Bar", doc["Override anchor"].as<std::string>());
    725   EXPECT_EQ("Bar", doc["Reuse anchor"].as<std::string>());
    726 }
    727 
    728 TEST(NodeSpecTest, Ex7_2_EmptyNodes) {
    729   Node doc = Load(ex7_2);
    730   EXPECT_EQ(2, doc.size());
    731   for (const_iterator it = doc.begin(); it != doc.end(); ++it) {
    732     if (it->first.as<std::string>() == "foo") {
    733       EXPECT_EQ("tag:yaml.org,2002:str", it->second.Tag());
    734       EXPECT_EQ("", it->second.as<std::string>());
    735     } else if (it->first.as<std::string>() == "") {
    736       EXPECT_EQ("tag:yaml.org,2002:str", it->first.Tag());
    737       EXPECT_EQ("bar", it->second.as<std::string>());
    738     } else
    739       FAIL() << "unexpected key";
    740   }
    741 }
    742 
    743 TEST(NodeSpecTest, Ex7_3_CompletelyEmptyNodes) {
    744   Node doc = Load(ex7_3);
    745   EXPECT_EQ(2, doc.size());
    746   EXPECT_TRUE(doc["foo"].IsNull());
    747   EXPECT_EQ("bar", doc[Null].as<std::string>());
    748 }
    749 
    750 TEST(NodeSpecTest, Ex7_4_DoubleQuotedImplicitKeys) {
    751   Node doc = Load(ex7_4);
    752   EXPECT_EQ(1, doc.size());
    753   EXPECT_EQ(1, doc["implicit block key"].size());
    754   EXPECT_EQ(1, doc["implicit block key"][0].size());
    755   EXPECT_EQ(
    756       "value",
    757       doc["implicit block key"][0]["implicit flow key"].as<std::string>());
    758 }
    759 
    760 TEST(NodeSpecTest, Ex7_5_DoubleQuotedLineBreaks) {
    761   Node doc = Load(ex7_5);
    762   EXPECT_TRUE(doc.as<std::string>() ==
    763               "folded to a space,\nto a line feed, or \t \tnon-content");
    764 }
    765 
    766 TEST(NodeSpecTest, Ex7_6_DoubleQuotedLines) {
    767   Node doc = Load(ex7_6);
    768   EXPECT_TRUE(doc.as<std::string>() ==
    769               " 1st non-empty\n2nd non-empty 3rd non-empty ");
    770 }
    771 
    772 TEST(NodeSpecTest, Ex7_7_SingleQuotedCharacters) {
    773   Node doc = Load(ex7_7);
    774   EXPECT_EQ("here's to \"quotes\"", doc.as<std::string>());
    775 }
    776 
    777 TEST(NodeSpecTest, Ex7_8_SingleQuotedImplicitKeys) {
    778   Node doc = Load(ex7_8);
    779   EXPECT_EQ(1, doc.size());
    780   EXPECT_EQ(1, doc["implicit block key"].size());
    781   EXPECT_EQ(1, doc["implicit block key"][0].size());
    782   EXPECT_EQ(
    783       "value",
    784       doc["implicit block key"][0]["implicit flow key"].as<std::string>());
    785 }
    786 
    787 TEST(NodeSpecTest, Ex7_9_SingleQuotedLines) {
    788   Node doc = Load(ex7_9);
    789   EXPECT_TRUE(doc.as<std::string>() ==
    790               " 1st non-empty\n2nd non-empty 3rd non-empty ");
    791 }
    792 
    793 TEST(NodeSpecTest, Ex7_10_PlainCharacters) {
    794   Node doc = Load(ex7_10);
    795   EXPECT_EQ(6, doc.size());
    796   EXPECT_EQ("::vector", doc[0].as<std::string>());
    797   EXPECT_EQ(": - ()", doc[1].as<std::string>());
    798   EXPECT_EQ("Up, up, and away!", doc[2].as<std::string>());
    799   EXPECT_EQ(-123, doc[3].as<int>());
    800   EXPECT_EQ("http://example.com/foo#bar", doc[4].as<std::string>());
    801   EXPECT_EQ(5, doc[5].size());
    802   EXPECT_EQ("::vector", doc[5][0].as<std::string>());
    803   EXPECT_EQ(": - ()", doc[5][1].as<std::string>());
    804   EXPECT_EQ("Up, up, and away!", doc[5][2].as<std::string>());
    805   EXPECT_EQ(-123, doc[5][3].as<int>());
    806   EXPECT_EQ("http://example.com/foo#bar", doc[5][4].as<std::string>());
    807 }
    808 
    809 TEST(NodeSpecTest, Ex7_11_PlainImplicitKeys) {
    810   Node doc = Load(ex7_11);
    811   EXPECT_EQ(1, doc.size());
    812   EXPECT_EQ(1, doc["implicit block key"].size());
    813   EXPECT_EQ(1, doc["implicit block key"][0].size());
    814   EXPECT_EQ(
    815       "value",
    816       doc["implicit block key"][0]["implicit flow key"].as<std::string>());
    817 }
    818 
    819 TEST(NodeSpecTest, Ex7_12_PlainLines) {
    820   Node doc = Load(ex7_12);
    821   EXPECT_TRUE(doc.as<std::string>() ==
    822               "1st non-empty\n2nd non-empty 3rd non-empty");
    823 }
    824 
    825 TEST(NodeSpecTest, Ex7_13_FlowSequence) {
    826   Node doc = Load(ex7_13);
    827   EXPECT_EQ(2, doc.size());
    828   EXPECT_EQ(2, doc[0].size());
    829   EXPECT_EQ("one", doc[0][0].as<std::string>());
    830   EXPECT_EQ("two", doc[0][1].as<std::string>());
    831   EXPECT_EQ(2, doc[1].size());
    832   EXPECT_EQ("three", doc[1][0].as<std::string>());
    833   EXPECT_EQ("four", doc[1][1].as<std::string>());
    834 }
    835 
    836 TEST(NodeSpecTest, Ex7_14_FlowSequenceEntries) {
    837   Node doc = Load(ex7_14);
    838   EXPECT_EQ(5, doc.size());
    839   EXPECT_EQ("double quoted", doc[0].as<std::string>());
    840   EXPECT_EQ("single quoted", doc[1].as<std::string>());
    841   EXPECT_EQ("plain text", doc[2].as<std::string>());
    842   EXPECT_EQ(1, doc[3].size());
    843   EXPECT_EQ("nested", doc[3][0].as<std::string>());
    844   EXPECT_EQ(1, doc[4].size());
    845   EXPECT_EQ("pair", doc[4]["single"].as<std::string>());
    846 }
    847 
    848 TEST(NodeSpecTest, Ex7_15_FlowMappings) {
    849   Node doc = Load(ex7_15);
    850   EXPECT_EQ(2, doc.size());
    851   EXPECT_EQ(2, doc[0].size());
    852   EXPECT_EQ("two", doc[0]["one"].as<std::string>());
    853   EXPECT_EQ("four", doc[0]["three"].as<std::string>());
    854   EXPECT_EQ(2, doc[1].size());
    855   EXPECT_EQ("six", doc[1]["five"].as<std::string>());
    856   EXPECT_EQ("eight", doc[1]["seven"].as<std::string>());
    857 }
    858 
    859 TEST(NodeSpecTest, Ex7_16_FlowMappingEntries) {
    860   Node doc = Load(ex7_16);
    861   EXPECT_EQ(3, doc.size());
    862   EXPECT_EQ("entry", doc["explicit"].as<std::string>());
    863   EXPECT_EQ("entry", doc["implicit"].as<std::string>());
    864   EXPECT_TRUE(doc[Null].IsNull());
    865 }
    866 
    867 TEST(NodeSpecTest, Ex7_17_FlowMappingSeparateValues) {
    868   Node doc = Load(ex7_17);
    869   EXPECT_EQ(4, doc.size());
    870   EXPECT_EQ("separate", doc["unquoted"].as<std::string>());
    871   EXPECT_TRUE(doc["http://foo.com"].IsNull());
    872   EXPECT_TRUE(doc["omitted value"].IsNull());
    873   EXPECT_EQ("omitted key", doc[Null].as<std::string>());
    874 }
    875 
    876 TEST(NodeSpecTest, Ex7_18_FlowMappingAdjacentValues) {
    877   Node doc = Load(ex7_18);
    878   EXPECT_EQ(3, doc.size());
    879   EXPECT_EQ("value", doc["adjacent"].as<std::string>());
    880   EXPECT_EQ("value", doc["readable"].as<std::string>());
    881   EXPECT_TRUE(doc["empty"].IsNull());
    882 }
    883 
    884 TEST(NodeSpecTest, Ex7_19_SinglePairFlowMappings) {
    885   Node doc = Load(ex7_19);
    886   EXPECT_EQ(1, doc.size());
    887   EXPECT_EQ(1, doc[0].size());
    888   EXPECT_EQ("bar", doc[0]["foo"].as<std::string>());
    889 }
    890 
    891 TEST(NodeSpecTest, Ex7_20_SinglePairExplicitEntry) {
    892   Node doc = Load(ex7_20);
    893   EXPECT_EQ(1, doc.size());
    894   EXPECT_EQ(1, doc[0].size());
    895   EXPECT_EQ("baz", doc[0]["foo bar"].as<std::string>());
    896 }
    897 
    898 TEST(NodeSpecTest, Ex7_21_SinglePairImplicitEntries) {
    899   Node doc = Load(ex7_21);
    900   EXPECT_EQ(3, doc.size());
    901   EXPECT_EQ(1, doc[0].size());
    902   EXPECT_EQ(1, doc[0][0].size());
    903   EXPECT_EQ("separate", doc[0][0]["YAML"].as<std::string>());
    904   EXPECT_EQ(1, doc[1].size());
    905   EXPECT_EQ(1, doc[1][0].size());
    906   EXPECT_EQ("empty key entry", doc[1][0][Null].as<std::string>());
    907   EXPECT_EQ(1, doc[2].size());
    908   EXPECT_EQ(1, doc[2][0].size());
    909 
    910   std::map<std::string, std::string> key;
    911   key["JSON"] = "like";
    912   EXPECT_EQ("adjacent", doc[2][0][key].as<std::string>());
    913 }
    914 
    915 TEST(NodeSpecTest, Ex7_22_InvalidImplicitKeys) {
    916   EXPECT_THROW_PARSER_EXCEPTION(Load(ex7_22), ErrorMsg::END_OF_SEQ_FLOW);
    917 }
    918 
    919 TEST(NodeSpecTest, Ex7_23_FlowContent) {
    920   Node doc = Load(ex7_23);
    921   EXPECT_EQ(5, doc.size());
    922   EXPECT_EQ(2, doc[0].size());
    923   EXPECT_EQ("a", doc[0][0].as<std::string>());
    924   EXPECT_EQ("b", doc[0][1].as<std::string>());
    925   EXPECT_EQ(1, doc[1].size());
    926   EXPECT_EQ("b", doc[1]["a"].as<std::string>());
    927   EXPECT_EQ("a", doc[2].as<std::string>());
    928   EXPECT_EQ('b', doc[3].as<char>());
    929   EXPECT_EQ("c", doc[4].as<std::string>());
    930 }
    931 
    932 TEST(NodeSpecTest, Ex7_24_FlowNodes) {
    933   Node doc = Load(ex7_24);
    934   EXPECT_EQ(5, doc.size());
    935   EXPECT_EQ("tag:yaml.org,2002:str", doc[0].Tag());
    936   EXPECT_EQ("a", doc[0].as<std::string>());
    937   EXPECT_EQ('b', doc[1].as<char>());
    938   EXPECT_EQ("c", doc[2].as<std::string>());
    939   EXPECT_EQ("c", doc[3].as<std::string>());
    940   EXPECT_EQ("tag:yaml.org,2002:str", doc[4].Tag());
    941   EXPECT_EQ("", doc[4].as<std::string>());
    942 }
    943 
    944 TEST(NodeSpecTest, Ex8_1_BlockScalarHeader) {
    945   Node doc = Load(ex8_1);
    946   EXPECT_EQ(4, doc.size());
    947   EXPECT_EQ("literal\n", doc[0].as<std::string>());
    948   EXPECT_EQ(" folded\n", doc[1].as<std::string>());
    949   EXPECT_EQ("keep\n\n", doc[2].as<std::string>());
    950   EXPECT_EQ(" strip", doc[3].as<std::string>());
    951 }
    952 
    953 TEST(NodeSpecTest, Ex8_2_BlockIndentationHeader) {
    954   Node doc = Load(ex8_2);
    955   EXPECT_EQ(4, doc.size());
    956   EXPECT_EQ("detected\n", doc[0].as<std::string>());
    957   EXPECT_EQ("\n\n# detected\n", doc[1].as<std::string>());
    958   EXPECT_EQ(" explicit\n", doc[2].as<std::string>());
    959   EXPECT_EQ("\t\ndetected\n", doc[3].as<std::string>());
    960 }
    961 
    962 TEST(NodeSpecTest, Ex8_3a_InvalidBlockScalarIndentationIndicators) {
    963   EXPECT_THROW_PARSER_EXCEPTION(Load(ex8_3a), ErrorMsg::END_OF_SEQ);
    964 }
    965 
    966 TEST(NodeSpecTest, Ex8_3b_InvalidBlockScalarIndentationIndicators) {
    967   EXPECT_THROW_PARSER_EXCEPTION(Load(ex8_3b), ErrorMsg::END_OF_SEQ);
    968 }
    969 
    970 TEST(NodeSpecTest, Ex8_3c_InvalidBlockScalarIndentationIndicators) {
    971   EXPECT_THROW_PARSER_EXCEPTION(Load(ex8_3c), ErrorMsg::END_OF_SEQ);
    972 }
    973 
    974 TEST(NodeSpecTest, Ex8_4_ChompingFinalLineBreak) {
    975   Node doc = Load(ex8_4);
    976   EXPECT_EQ(3, doc.size());
    977   EXPECT_EQ("text", doc["strip"].as<std::string>());
    978   EXPECT_EQ("text\n", doc["clip"].as<std::string>());
    979   EXPECT_EQ("text\n", doc["keep"].as<std::string>());
    980 }
    981 
    982 TEST(NodeSpecTest, DISABLED_Ex8_5_ChompingTrailingLines) {
    983   Node doc = Load(ex8_5);
    984   EXPECT_EQ(3, doc.size());
    985   EXPECT_EQ("# text", doc["strip"].as<std::string>());
    986   EXPECT_EQ("# text\n", doc["clip"].as<std::string>());
    987   // NOTE: I believe this is a bug in the YAML spec -
    988   // it should be "# text\n\n"
    989   EXPECT_EQ("# text\n", doc["keep"].as<std::string>());
    990 }
    991 
    992 TEST(NodeSpecTest, Ex8_6_EmptyScalarChomping) {
    993   Node doc = Load(ex8_6);
    994   EXPECT_EQ(3, doc.size());
    995   EXPECT_EQ("", doc["strip"].as<std::string>());
    996   EXPECT_EQ("", doc["clip"].as<std::string>());
    997   EXPECT_EQ("\n", doc["keep"].as<std::string>());
    998 }
    999 
   1000 TEST(NodeSpecTest, Ex8_7_LiteralScalar) {
   1001   Node doc = Load(ex8_7);
   1002   EXPECT_EQ("literal\n\ttext\n", doc.as<std::string>());
   1003 }
   1004 
   1005 TEST(NodeSpecTest, Ex8_8_LiteralContent) {
   1006   Node doc = Load(ex8_8);
   1007   EXPECT_EQ("\n\nliteral\n \n\ntext\n", doc.as<std::string>());
   1008 }
   1009 
   1010 TEST(NodeSpecTest, Ex8_9_FoldedScalar) {
   1011   Node doc = Load(ex8_9);
   1012   EXPECT_EQ("folded text\n", doc.as<std::string>());
   1013 }
   1014 
   1015 TEST(NodeSpecTest, Ex8_10_FoldedLines) {
   1016   Node doc = Load(ex8_10);
   1017   EXPECT_TRUE(doc.as<std::string>() ==
   1018               "\nfolded line\nnext line\n  * bullet\n\n  * list\n  * "
   1019               "lines\n\nlast line\n");
   1020 }
   1021 
   1022 TEST(NodeSpecTest, Ex8_11_MoreIndentedLines) {
   1023   Node doc = Load(ex8_11);
   1024   EXPECT_TRUE(doc.as<std::string>() ==
   1025               "\nfolded line\nnext line\n  * bullet\n\n  * list\n  * "
   1026               "lines\n\nlast line\n");
   1027 }
   1028 
   1029 TEST(NodeSpecTest, Ex8_12_EmptySeparationLines) {
   1030   Node doc = Load(ex8_12);
   1031   EXPECT_TRUE(doc.as<std::string>() ==
   1032               "\nfolded line\nnext line\n  * bullet\n\n  * list\n  * "
   1033               "lines\n\nlast line\n");
   1034 }
   1035 
   1036 TEST(NodeSpecTest, Ex8_13_FinalEmptyLines) {
   1037   Node doc = Load(ex8_13);
   1038   EXPECT_TRUE(doc.as<std::string>() ==
   1039               "\nfolded line\nnext line\n  * bullet\n\n  * list\n  * "
   1040               "lines\n\nlast line\n");
   1041 }
   1042 
   1043 TEST(NodeSpecTest, Ex8_14_BlockSequence) {
   1044   Node doc = Load(ex8_14);
   1045   EXPECT_EQ(1, doc.size());
   1046   EXPECT_EQ(2, doc["block sequence"].size());
   1047   EXPECT_EQ("one", doc["block sequence"][0].as<std::string>());
   1048   EXPECT_EQ(1, doc["block sequence"][1].size());
   1049   EXPECT_EQ("three", doc["block sequence"][1]["two"].as<std::string>());
   1050 }
   1051 
   1052 TEST(NodeSpecTest, Ex8_15_BlockSequenceEntryTypes) {
   1053   Node doc = Load(ex8_15);
   1054   EXPECT_EQ(4, doc.size());
   1055   EXPECT_TRUE(doc[0].IsNull());
   1056   EXPECT_EQ("block node\n", doc[1].as<std::string>());
   1057   EXPECT_EQ(2, doc[2].size());
   1058   EXPECT_EQ("one", doc[2][0].as<std::string>());
   1059   EXPECT_EQ("two", doc[2][1].as<std::string>());
   1060   EXPECT_EQ(1, doc[3].size());
   1061   EXPECT_EQ("two", doc[3]["one"].as<std::string>());
   1062 }
   1063 
   1064 TEST(NodeSpecTest, Ex8_16_BlockMappings) {
   1065   Node doc = Load(ex8_16);
   1066   EXPECT_EQ(1, doc.size());
   1067   EXPECT_EQ(1, doc["block mapping"].size());
   1068   EXPECT_EQ("value", doc["block mapping"]["key"].as<std::string>());
   1069 }
   1070 
   1071 TEST(NodeSpecTest, Ex8_17_ExplicitBlockMappingEntries) {
   1072   Node doc = Load(ex8_17);
   1073   EXPECT_EQ(2, doc.size());
   1074   EXPECT_TRUE(doc["explicit key"].IsNull());
   1075   EXPECT_EQ(2, doc["block key\n"].size());
   1076   EXPECT_EQ("one", doc["block key\n"][0].as<std::string>());
   1077   EXPECT_EQ("two", doc["block key\n"][1].as<std::string>());
   1078 }
   1079 
   1080 TEST(NodeSpecTest, Ex8_18_ImplicitBlockMappingEntries) {
   1081   Node doc = Load(ex8_18);
   1082   EXPECT_EQ(3, doc.size());
   1083   EXPECT_EQ("in-line value", doc["plain key"].as<std::string>());
   1084   EXPECT_TRUE(doc[Null].IsNull());
   1085   EXPECT_EQ(1, doc["quoted key"].size());
   1086   EXPECT_EQ("entry", doc["quoted key"][0].as<std::string>());
   1087 }
   1088 
   1089 TEST(NodeSpecTest, Ex8_19_CompactBlockMappings) {
   1090   Node doc = Load(ex8_19);
   1091   EXPECT_EQ(2, doc.size());
   1092   EXPECT_EQ(1, doc[0].size());
   1093   EXPECT_EQ("yellow", doc[0]["sun"].as<std::string>());
   1094   EXPECT_EQ(1, doc[1].size());
   1095   std::map<std::string, std::string> key;
   1096   key["earth"] = "blue";
   1097   EXPECT_EQ(1, doc[1][key].size());
   1098   EXPECT_EQ("white", doc[1][key]["moon"].as<std::string>());
   1099 }
   1100 
   1101 TEST(NodeSpecTest, Ex8_20_BlockNodeTypes) {
   1102   Node doc = Load(ex8_20);
   1103   EXPECT_EQ(3, doc.size());
   1104   EXPECT_EQ("flow in block", doc[0].as<std::string>());
   1105   EXPECT_EQ("Block scalar\n", doc[1].as<std::string>());
   1106   EXPECT_EQ(1, doc[2].size());
   1107   EXPECT_EQ("bar", doc[2]["foo"].as<std::string>());
   1108 }
   1109 
   1110 TEST(NodeSpecTest, DISABLED_Ex8_21_BlockScalarNodes) {
   1111   Node doc = Load(ex8_21);
   1112   EXPECT_EQ(2, doc.size());
   1113   // NOTE: I believe this is a bug in the YAML spec -
   1114   // it should be "value\n"
   1115   EXPECT_EQ("value", doc["literal"].as<std::string>());
   1116   EXPECT_EQ("value", doc["folded"].as<std::string>());
   1117   EXPECT_EQ("!foo", doc["folded"].Tag());
   1118 }
   1119 
   1120 TEST(NodeSpecTest, Ex8_22_BlockCollectionNodes) {
   1121   Node doc = Load(ex8_22);
   1122   EXPECT_EQ(2, doc.size());
   1123   EXPECT_EQ(2, doc["sequence"].size());
   1124   EXPECT_EQ("entry", doc["sequence"][0].as<std::string>());
   1125   EXPECT_EQ(1, doc["sequence"][1].size());
   1126   EXPECT_EQ("nested", doc["sequence"][1][0].as<std::string>());
   1127   EXPECT_EQ(1, doc["mapping"].size());
   1128   EXPECT_EQ("bar", doc["mapping"]["foo"].as<std::string>());
   1129 }
   1130 
   1131 TEST(NodeSpecTest, FlowMapNotClosed) {
   1132   EXPECT_THROW_PARSER_EXCEPTION(Load("{x:"), ErrorMsg::UNKNOWN_TOKEN);
   1133 }
   1134 
   1135 }
   1136 }