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 
TEST(NodeSpecTest,Ex2_1_SeqScalars)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 
TEST(NodeSpecTest,Ex2_2_MappingScalarsToScalars)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 
TEST(NodeSpecTest,Ex2_3_MappingScalarsToSequences)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 
TEST(NodeSpecTest,Ex2_4_SequenceOfMappings)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 
TEST(NodeSpecTest,Ex2_5_SequenceOfSequences)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 
TEST(NodeSpecTest,Ex2_6_MappingOfMappings)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 
TEST(NodeSpecTest,Ex2_7_TwoDocumentsInAStream)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 
TEST(NodeSpecTest,Ex2_8_PlayByPlayFeed)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 
TEST(NodeSpecTest,Ex2_9_SingleDocumentWithTwoComments)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 
TEST(NodeSpecTest,Ex2_10_SimpleAnchor)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 
TEST(NodeSpecTest,Ex2_11_MappingBetweenSequences)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 
TEST(NodeSpecTest,Ex2_12_CompactNestedMapping)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 
TEST(NodeSpecTest,Ex2_13_InLiteralsNewlinesArePreserved)187 TEST(NodeSpecTest, Ex2_13_InLiteralsNewlinesArePreserved) {
188   Node doc = Load(ex2_13);
189   EXPECT_TRUE(doc.as<std::string>() ==
190               "\\//||\\/||\n"
191               "// ||  ||__");
192 }
193 
TEST(NodeSpecTest,Ex2_14_InFoldedScalarsNewlinesBecomeSpaces)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 
TEST(NodeSpecTest,Ex2_15_FoldedNewlinesArePreservedForMoreIndentedAndBlankLines)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 
TEST(NodeSpecTest,Ex2_16_IndentationDeterminesScope)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 
TEST(NodeSpecTest,Ex2_17_QuotedScalars)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 
TEST(NodeSpecTest,Ex2_18_MultiLineFlowScalars)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 
TEST(NodeSpecTest,Ex2_23_VariousExplicitTags)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 
TEST(NodeSpecTest,Ex2_24_GlobalTags)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 
TEST(NodeSpecTest,Ex2_25_UnorderedSets)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 
TEST(NodeSpecTest,Ex2_16_OrderedMappings)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 
TEST(NodeSpecTest,Ex2_27_Invoice)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 
TEST(NodeSpecTest,Ex2_28_LogFile)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 
TEST(NodeSpecTest,Ex5_3_BlockStructureIndicators)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 
TEST(NodeSpecTest,Ex5_4_FlowStructureIndicators)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 
TEST(NodeSpecTest,Ex5_5_CommentIndicator)419 TEST(NodeSpecTest, Ex5_5_CommentIndicator) {
420   Node doc = Load(ex5_5);
421   EXPECT_TRUE(doc.IsNull());
422 }
423 
TEST(NodeSpecTest,Ex5_6_NodePropertyIndicators)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 
TEST(NodeSpecTest,Ex5_7_BlockScalarIndicators)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 
TEST(NodeSpecTest,Ex5_8_QuotedScalarIndicators)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 
TEST(NodeSpecTest,Ex5_11_LineBreakCharacters)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 
TEST(NodeSpecTest,Ex5_12_TabsAndSpaces)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 
TEST(NodeSpecTest,Ex5_13_EscapedCharacters)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 
TEST(NodeSpecTest,Ex5_14_InvalidEscapedCharacters)473 TEST(NodeSpecTest, Ex5_14_InvalidEscapedCharacters) {
474   EXPECT_THROW_PARSER_EXCEPTION(Load(ex5_14),
475                                 std::string(ErrorMsg::INVALID_ESCAPE) + "c");
476 }
477 
TEST(NodeSpecTest,Ex6_1_IndentationSpaces)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 
TEST(NodeSpecTest,Ex6_2_IndentationIndicators)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 
TEST(NodeSpecTest,Ex6_3_SeparationSpaces)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 
TEST(NodeSpecTest,Ex6_4_LinePrefixes)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 
TEST(NodeSpecTest,Ex6_5_EmptyLines)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 
TEST(NodeSpecTest,Ex6_6_LineFolding)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 
TEST(NodeSpecTest,Ex6_7_BlockFolding)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 
TEST(NodeSpecTest,Ex6_8_FlowFolding)538 TEST(NodeSpecTest, Ex6_8_FlowFolding) {
539   Node doc = Load(ex6_8);
540   EXPECT_EQ(" foo\nbar\nbaz ", doc.as<std::string>());
541 }
542 
TEST(NodeSpecTest,Ex6_9_SeparatedComment)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 
TEST(NodeSpecTest,Ex6_10_CommentLines)549 TEST(NodeSpecTest, Ex6_10_CommentLines) {
550   Node doc = Load(ex6_10);
551   EXPECT_TRUE(doc.IsNull());
552 }
553 
TEST(NodeSpecTest,Ex6_11_MultiLineComments)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 
TEST(NodeSpecTest,Ex6_12_SeparationSpacesII)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 
TEST(NodeSpecTest,Ex6_13_ReservedDirectives)573 TEST(NodeSpecTest, Ex6_13_ReservedDirectives) {
574   Node doc = Load(ex6_13);
575   EXPECT_EQ("foo", doc.as<std::string>());
576 }
577 
TEST(NodeSpecTest,Ex6_14_YAMLDirective)578 TEST(NodeSpecTest, Ex6_14_YAMLDirective) {
579   Node doc = Load(ex6_14);
580   EXPECT_EQ("foo", doc.as<std::string>());
581 }
582 
TEST(NodeSpecTest,Ex6_15_InvalidRepeatedYAMLDirective)583 TEST(NodeSpecTest, Ex6_15_InvalidRepeatedYAMLDirective) {
584   EXPECT_THROW_PARSER_EXCEPTION(Load(ex6_15),
585                                 ErrorMsg::REPEATED_YAML_DIRECTIVE);
586 }
587 
TEST(NodeSpecTest,Ex6_16_TagDirective)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 
TEST(NodeSpecTest,Ex6_17_InvalidRepeatedTagDirective)594 TEST(NodeSpecTest, Ex6_17_InvalidRepeatedTagDirective) {
595   EXPECT_THROW_PARSER_EXCEPTION(Load(ex6_17), ErrorMsg::REPEATED_TAG_DIRECTIVE);
596 }
597 
TEST(NodeSpecTest,Ex6_18_PrimaryTagHandle)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 
TEST(NodeSpecTest,Ex6_19_SecondaryTagHandle)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 
TEST(NodeSpecTest,Ex6_20_TagHandles)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 
TEST(NodeSpecTest,Ex6_21_LocalTagPrefix)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 
TEST(NodeSpecTest,Ex6_22_GlobalTagPrefix)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 
TEST(NodeSpecTest,Ex6_23_NodeProperties)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 
TEST(NodeSpecTest,Ex6_24_VerbatimTags)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 
TEST(NodeSpecTest,DISABLED_Ex6_25_InvalidVerbatimTags)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 
TEST(NodeSpecTest,Ex6_26_TagShorthands)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 
TEST(NodeSpecTest,Ex6_27a_InvalidTagShorthands)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)?
TEST(NodeSpecTest,DISABLED_Ex6_27b_InvalidTagShorthands)699 TEST(NodeSpecTest, DISABLED_Ex6_27b_InvalidTagShorthands) {
700   Load(ex6_27b);
701   FAIL() << "not implemented yet";
702 }
703 
TEST(NodeSpecTest,Ex6_28_NonSpecificTags)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 
TEST(NodeSpecTest,Ex6_29_NodeAnchors)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 
TEST(NodeSpecTest,Ex7_1_AliasNodes)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 
TEST(NodeSpecTest,Ex7_2_EmptyNodes)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 
TEST(NodeSpecTest,Ex7_3_CompletelyEmptyNodes)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 
TEST(NodeSpecTest,Ex7_4_DoubleQuotedImplicitKeys)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 
TEST(NodeSpecTest,Ex7_5_DoubleQuotedLineBreaks)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 
TEST(NodeSpecTest,Ex7_6_DoubleQuotedLines)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 
TEST(NodeSpecTest,Ex7_7_SingleQuotedCharacters)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 
TEST(NodeSpecTest,Ex7_8_SingleQuotedImplicitKeys)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 
TEST(NodeSpecTest,Ex7_9_SingleQuotedLines)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 
TEST(NodeSpecTest,Ex7_10_PlainCharacters)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 
TEST(NodeSpecTest,Ex7_11_PlainImplicitKeys)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 
TEST(NodeSpecTest,Ex7_12_PlainLines)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 
TEST(NodeSpecTest,Ex7_13_FlowSequence)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 
TEST(NodeSpecTest,Ex7_14_FlowSequenceEntries)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 
TEST(NodeSpecTest,Ex7_15_FlowMappings)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 
TEST(NodeSpecTest,Ex7_16_FlowMappingEntries)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 
TEST(NodeSpecTest,Ex7_17_FlowMappingSeparateValues)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 
TEST(NodeSpecTest,Ex7_18_FlowMappingAdjacentValues)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 
TEST(NodeSpecTest,Ex7_19_SinglePairFlowMappings)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 
TEST(NodeSpecTest,Ex7_20_SinglePairExplicitEntry)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 
TEST(NodeSpecTest,Ex7_21_SinglePairImplicitEntries)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 
TEST(NodeSpecTest,Ex7_22_InvalidImplicitKeys)915 TEST(NodeSpecTest, Ex7_22_InvalidImplicitKeys) {
916   EXPECT_THROW_PARSER_EXCEPTION(Load(ex7_22), ErrorMsg::END_OF_SEQ_FLOW);
917 }
918 
TEST(NodeSpecTest,Ex7_23_FlowContent)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 
TEST(NodeSpecTest,Ex7_24_FlowNodes)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 
TEST(NodeSpecTest,Ex8_1_BlockScalarHeader)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 
TEST(NodeSpecTest,Ex8_2_BlockIndentationHeader)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 
TEST(NodeSpecTest,Ex8_3a_InvalidBlockScalarIndentationIndicators)962 TEST(NodeSpecTest, Ex8_3a_InvalidBlockScalarIndentationIndicators) {
963   EXPECT_THROW_PARSER_EXCEPTION(Load(ex8_3a), ErrorMsg::END_OF_SEQ);
964 }
965 
TEST(NodeSpecTest,Ex8_3b_InvalidBlockScalarIndentationIndicators)966 TEST(NodeSpecTest, Ex8_3b_InvalidBlockScalarIndentationIndicators) {
967   EXPECT_THROW_PARSER_EXCEPTION(Load(ex8_3b), ErrorMsg::END_OF_SEQ);
968 }
969 
TEST(NodeSpecTest,Ex8_3c_InvalidBlockScalarIndentationIndicators)970 TEST(NodeSpecTest, Ex8_3c_InvalidBlockScalarIndentationIndicators) {
971   EXPECT_THROW_PARSER_EXCEPTION(Load(ex8_3c), ErrorMsg::END_OF_SEQ);
972 }
973 
TEST(NodeSpecTest,Ex8_4_ChompingFinalLineBreak)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 
TEST(NodeSpecTest,DISABLED_Ex8_5_ChompingTrailingLines)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 
TEST(NodeSpecTest,Ex8_6_EmptyScalarChomping)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 
TEST(NodeSpecTest,Ex8_7_LiteralScalar)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 
TEST(NodeSpecTest,Ex8_8_LiteralContent)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 
TEST(NodeSpecTest,Ex8_9_FoldedScalar)1010 TEST(NodeSpecTest, Ex8_9_FoldedScalar) {
1011   Node doc = Load(ex8_9);
1012   EXPECT_EQ("folded text\n", doc.as<std::string>());
1013 }
1014 
TEST(NodeSpecTest,Ex8_10_FoldedLines)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 
TEST(NodeSpecTest,Ex8_11_MoreIndentedLines)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 
TEST(NodeSpecTest,Ex8_12_EmptySeparationLines)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 
TEST(NodeSpecTest,Ex8_13_FinalEmptyLines)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 
TEST(NodeSpecTest,Ex8_14_BlockSequence)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 
TEST(NodeSpecTest,Ex8_15_BlockSequenceEntryTypes)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 
TEST(NodeSpecTest,Ex8_16_BlockMappings)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 
TEST(NodeSpecTest,Ex8_17_ExplicitBlockMappingEntries)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 
TEST(NodeSpecTest,Ex8_18_ImplicitBlockMappingEntries)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 
TEST(NodeSpecTest,Ex8_19_CompactBlockMappings)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 
TEST(NodeSpecTest,Ex8_20_BlockNodeTypes)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 
TEST(NodeSpecTest,DISABLED_Ex8_21_BlockScalarNodes)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 
TEST(NodeSpecTest,Ex8_22_BlockCollectionNodes)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 
TEST(NodeSpecTest,FlowMapNotClosed)1131 TEST(NodeSpecTest, FlowMapNotClosed) {
1132   EXPECT_THROW_PARSER_EXCEPTION(Load("{x:"), ErrorMsg::UNKNOWN_TOKEN);
1133 }
1134 
1135 }
1136 }
1137