1 #include "spectests.h"
2 #include "specexamples.h"
3 #include "yaml-cpp03/yaml.h"
4 #include <fstream>
5 #include <sstream>
6 #include <vector>
7 #include <iostream>
8 
9 #define YAML_ASSERT(cond) do { if(!(cond)) return "  Assert failed: " #cond; } while(false)
10 #define PARSE(doc, input) \
11 	std::stringstream stream(input);\
12 	YAML::Parser parser(stream);\
13 	YAML::Node doc;\
14 	parser.GetNextDocument(doc)
15 #define PARSE_NEXT(doc) parser.GetNextDocument(doc)
16 
17 namespace Test {
18 	namespace Spec {
19 		// 2.1
SeqScalars()20 		TEST SeqScalars() {
21 			PARSE(doc, ex2_1);
22 			YAML_ASSERT(doc.size() == 3);
23 			YAML_ASSERT(doc[0].to<std::string>() == "Mark McGwire");
24 			YAML_ASSERT(doc[1].to<std::string>() == "Sammy Sosa");
25 			YAML_ASSERT(doc[2].to<std::string>() == "Ken Griffey");
26 			return true;
27 		}
28 
29 		// 2.2
MappingScalarsToScalars()30 		TEST MappingScalarsToScalars() {
31 			PARSE(doc, ex2_2);
32 			YAML_ASSERT(doc.size() == 3);
33 			YAML_ASSERT(doc["hr"].to<std::string>() == "65");
34 			YAML_ASSERT(doc["avg"].to<std::string>() == "0.278");
35 			YAML_ASSERT(doc["rbi"].to<std::string>() == "147");
36 			return true;
37 		}
38 
39 		// 2.3
MappingScalarsToSequences()40 		TEST MappingScalarsToSequences() {
41 			PARSE(doc, ex2_3);
42 			YAML_ASSERT(doc.size() == 2);
43 			YAML_ASSERT(doc["american"].size() == 3);
44 			YAML_ASSERT(doc["american"][0].to<std::string>() == "Boston Red Sox");
45 			YAML_ASSERT(doc["american"][1].to<std::string>() == "Detroit Tigers");
46 			YAML_ASSERT(doc["american"][2].to<std::string>() == "New York Yankees");
47 			YAML_ASSERT(doc["national"].size() == 3);
48 			YAML_ASSERT(doc["national"][0].to<std::string>() == "New York Mets");
49 			YAML_ASSERT(doc["national"][1].to<std::string>() == "Chicago Cubs");
50 			YAML_ASSERT(doc["national"][2].to<std::string>() == "Atlanta Braves");
51 			return true;
52 		}
53 
54 		// 2.4
SequenceOfMappings()55 		TEST SequenceOfMappings()
56 		{
57 			PARSE(doc, ex2_4);
58 			YAML_ASSERT(doc.size() == 2);
59 			YAML_ASSERT(doc[0].size() == 3);
60 			YAML_ASSERT(doc[0]["name"].to<std::string>() == "Mark McGwire");
61 			YAML_ASSERT(doc[0]["hr"].to<std::string>() == "65");
62 			YAML_ASSERT(doc[0]["avg"].to<std::string>() == "0.278");
63 			YAML_ASSERT(doc[1].size() == 3);
64 			YAML_ASSERT(doc[1]["name"].to<std::string>() == "Sammy Sosa");
65 			YAML_ASSERT(doc[1]["hr"].to<std::string>() == "63");
66 			YAML_ASSERT(doc[1]["avg"].to<std::string>() == "0.288");
67 			return true;
68 		}
69 
70 		// 2.5
SequenceOfSequences()71 		TEST SequenceOfSequences()
72 		{
73 			PARSE(doc, ex2_5);
74 			YAML_ASSERT(doc.size() == 3);
75 			YAML_ASSERT(doc[0].size() == 3);
76 			YAML_ASSERT(doc[0][0].to<std::string>() == "name");
77 			YAML_ASSERT(doc[0][1].to<std::string>() == "hr");
78 			YAML_ASSERT(doc[0][2].to<std::string>() == "avg");
79 			YAML_ASSERT(doc[1].size() == 3);
80 			YAML_ASSERT(doc[1][0].to<std::string>() == "Mark McGwire");
81 			YAML_ASSERT(doc[1][1].to<std::string>() == "65");
82 			YAML_ASSERT(doc[1][2].to<std::string>() == "0.278");
83 			YAML_ASSERT(doc[2].size() == 3);
84 			YAML_ASSERT(doc[2][0].to<std::string>() == "Sammy Sosa");
85 			YAML_ASSERT(doc[2][1].to<std::string>() == "63");
86 			YAML_ASSERT(doc[2][2].to<std::string>() == "0.288");
87 			return true;
88 		}
89 
90 		// 2.6
MappingOfMappings()91 		TEST MappingOfMappings()
92 		{
93 			PARSE(doc, ex2_6);
94 			YAML_ASSERT(doc.size() == 2);
95 			YAML_ASSERT(doc["Mark McGwire"].size() == 2);
96 			YAML_ASSERT(doc["Mark McGwire"]["hr"].to<std::string>() == "65");
97 			YAML_ASSERT(doc["Mark McGwire"]["avg"].to<std::string>() == "0.278");
98 			YAML_ASSERT(doc["Sammy Sosa"].size() == 2);
99 			YAML_ASSERT(doc["Sammy Sosa"]["hr"].to<std::string>() == "63");
100 			YAML_ASSERT(doc["Sammy Sosa"]["avg"].to<std::string>() == "0.288");
101 			return true;
102 		}
103 
104 		// 2.7
TwoDocumentsInAStream()105 		TEST TwoDocumentsInAStream()
106 		{
107 			PARSE(doc, ex2_7);
108 			YAML_ASSERT(doc.size() == 3);
109 			YAML_ASSERT(doc[0].to<std::string>() == "Mark McGwire");
110 			YAML_ASSERT(doc[1].to<std::string>() == "Sammy Sosa");
111 			YAML_ASSERT(doc[2].to<std::string>() == "Ken Griffey");
112 
113 			PARSE_NEXT(doc);
114 			YAML_ASSERT(doc.size() == 2);
115 			YAML_ASSERT(doc[0].to<std::string>() == "Chicago Cubs");
116 			YAML_ASSERT(doc[1].to<std::string>() == "St Louis Cardinals");
117 			return true;
118 		}
119 
120 		// 2.8
PlayByPlayFeed()121 		TEST PlayByPlayFeed()
122 		{
123 			PARSE(doc, ex2_8);
124 			YAML_ASSERT(doc.size() == 3);
125 			YAML_ASSERT(doc["time"].to<std::string>() == "20:03:20");
126 			YAML_ASSERT(doc["player"].to<std::string>() == "Sammy Sosa");
127 			YAML_ASSERT(doc["action"].to<std::string>() == "strike (miss)");
128 
129 			PARSE_NEXT(doc);
130 			YAML_ASSERT(doc.size() == 3);
131 			YAML_ASSERT(doc["time"].to<std::string>() == "20:03:47");
132 			YAML_ASSERT(doc["player"].to<std::string>() == "Sammy Sosa");
133 			YAML_ASSERT(doc["action"].to<std::string>() == "grand slam");
134 			return true;
135 		}
136 
137 		// 2.9
SingleDocumentWithTwoComments()138 		TEST SingleDocumentWithTwoComments()
139 		{
140 			PARSE(doc, ex2_9);
141 			YAML_ASSERT(doc.size() == 2);
142 			YAML_ASSERT(doc["hr"].size() == 2);
143 			YAML_ASSERT(doc["hr"][0].to<std::string>() == "Mark McGwire");
144 			YAML_ASSERT(doc["hr"][1].to<std::string>() == "Sammy Sosa");
145 			YAML_ASSERT(doc["rbi"].size() == 2);
146 			YAML_ASSERT(doc["rbi"][0].to<std::string>() == "Sammy Sosa");
147 			YAML_ASSERT(doc["rbi"][1].to<std::string>() == "Ken Griffey");
148 			return true;
149 		}
150 
151 		// 2.10
SimpleAnchor()152 		TEST SimpleAnchor()
153 		{
154 			PARSE(doc, ex2_10);
155 			YAML_ASSERT(doc.size() == 2);
156 			YAML_ASSERT(doc["hr"].size() == 2);
157 			YAML_ASSERT(doc["hr"][0].to<std::string>() == "Mark McGwire");
158 			YAML_ASSERT(doc["hr"][1].to<std::string>() == "Sammy Sosa");
159 			YAML_ASSERT(doc["rbi"].size() == 2);
160 			YAML_ASSERT(doc["rbi"][0].to<std::string>() == "Sammy Sosa");
161 			YAML_ASSERT(doc["rbi"][1].to<std::string>() == "Ken Griffey");
162 			return true;
163 		}
164 
165 		struct Pair {
PairTest::Spec::Pair166 			Pair() {}
PairTest::Spec::Pair167 			Pair(const std::string& f, const std::string& s): first(f), second(s) {}
168 			std::string first, second;
169 		};
170 
operator ==(const Pair & p,const Pair & q)171 		bool operator == (const Pair& p, const Pair& q) {
172 			return p.first == q.first && p.second == q.second;
173 		}
174 
operator >>(const YAML::Node & node,Pair & p)175 		void operator >> (const YAML::Node& node, Pair& p) {
176 			node[0] >> p.first;
177 			node[1] >> p.second;
178 		}
179 
180 		// 2.11
MappingBetweenSequences()181 		TEST MappingBetweenSequences()
182 		{
183 			PARSE(doc, ex2_11);
184 			YAML_ASSERT(doc.size() == 2);
185 			YAML_ASSERT(doc[Pair("Detroit Tigers", "Chicago cubs")].size() == 1);
186 			YAML_ASSERT(doc[Pair("Detroit Tigers", "Chicago cubs")][0].to<std::string>() == "2001-07-23");
187 			YAML_ASSERT(doc[Pair("New York Yankees", "Atlanta Braves")].size() == 3);
188 			YAML_ASSERT(doc[Pair("New York Yankees", "Atlanta Braves")][0].to<std::string>() == "2001-07-02");
189 			YAML_ASSERT(doc[Pair("New York Yankees", "Atlanta Braves")][1].to<std::string>() == "2001-08-12");
190 			YAML_ASSERT(doc[Pair("New York Yankees", "Atlanta Braves")][2].to<std::string>() == "2001-08-14");
191 			return true;
192 		}
193 
194 		// 2.12
CompactNestedMapping()195 		TEST CompactNestedMapping()
196 		{
197 			PARSE(doc, ex2_12);
198 			YAML_ASSERT(doc.size() == 3);
199 			YAML_ASSERT(doc[0].size() == 2);
200 			YAML_ASSERT(doc[0]["item"].to<std::string>() == "Super Hoop");
201 			YAML_ASSERT(doc[0]["quantity"].to<int>() == 1);
202 			YAML_ASSERT(doc[1].size() == 2);
203 			YAML_ASSERT(doc[1]["item"].to<std::string>() == "Basketball");
204 			YAML_ASSERT(doc[1]["quantity"].to<int>() == 4);
205 			YAML_ASSERT(doc[2].size() == 2);
206 			YAML_ASSERT(doc[2]["item"].to<std::string>() == "Big Shoes");
207 			YAML_ASSERT(doc[2]["quantity"].to<int>() == 1);
208 			return true;
209 		}
210 
211 		// 2.13
InLiteralsNewlinesArePreserved()212 		TEST InLiteralsNewlinesArePreserved()
213 		{
214 			PARSE(doc, ex2_13);
215 			YAML_ASSERT(doc.to<std::string>() ==
216 						"\\//||\\/||\n"
217 						"// ||  ||__");
218 			return true;
219 		}
220 
221 		// 2.14
InFoldedScalarsNewlinesBecomeSpaces()222 		TEST InFoldedScalarsNewlinesBecomeSpaces()
223 		{
224 			PARSE(doc, ex2_14);
225 			YAML_ASSERT(doc.to<std::string>() == "Mark McGwire's year was crippled by a knee injury.");
226 			return true;
227 		}
228 
229 		// 2.15
FoldedNewlinesArePreservedForMoreIndentedAndBlankLines()230 		TEST FoldedNewlinesArePreservedForMoreIndentedAndBlankLines()
231 		{
232 			PARSE(doc, ex2_15);
233 			YAML_ASSERT(doc.to<std::string>() ==
234 						"Sammy Sosa completed another fine season with great stats.\n\n"
235 						"  63 Home Runs\n"
236 						"  0.288 Batting Average\n\n"
237 						"What a year!");
238 			return true;
239 		}
240 
241 		// 2.16
IndentationDeterminesScope()242 		TEST IndentationDeterminesScope()
243 		{
244 			PARSE(doc, ex2_16);
245 			YAML_ASSERT(doc.size() == 3);
246 			YAML_ASSERT(doc["name"].to<std::string>() == "Mark McGwire");
247 			YAML_ASSERT(doc["accomplishment"].to<std::string>() == "Mark set a major league home run record in 1998.\n");
248 			YAML_ASSERT(doc["stats"].to<std::string>() == "65 Home Runs\n0.278 Batting Average\n");
249 			return true;
250 		}
251 
252 		// 2.17
QuotedScalars()253 		TEST QuotedScalars()
254 		{
255 			PARSE(doc, ex2_17);
256 			YAML_ASSERT(doc.size() == 6);
257 			YAML_ASSERT(doc["unicode"].to<std::string>() == "Sosa did fine.\xe2\x98\xba");
258 			YAML_ASSERT(doc["control"].to<std::string>() == "\b1998\t1999\t2000\n");
259 			YAML_ASSERT(doc["hex esc"].to<std::string>() == "\x0d\x0a is \r\n");
260 			YAML_ASSERT(doc["single"].to<std::string>() == "\"Howdy!\" he cried.");
261 			YAML_ASSERT(doc["quoted"].to<std::string>() == " # Not a 'comment'.");
262 			YAML_ASSERT(doc["tie-fighter"].to<std::string>() == "|\\-*-/|");
263 			return true;
264 		}
265 
266 		// 2.18
MultiLineFlowScalars()267 		TEST MultiLineFlowScalars()
268 		{
269 			PARSE(doc, ex2_18);
270 			YAML_ASSERT(doc.size() == 2);
271 			YAML_ASSERT(doc["plain"].to<std::string>() == "This unquoted scalar spans many lines.");
272 			YAML_ASSERT(doc["quoted"].to<std::string>() == "So does this quoted scalar.\n");
273 			return true;
274 		}
275 
276 		// TODO: 2.19 - 2.22 schema tags
277 
278 		// 2.23
VariousExplicitTags()279 		TEST VariousExplicitTags()
280 		{
281 			PARSE(doc, ex2_23);
282 			YAML_ASSERT(doc.size() == 3);
283 			YAML_ASSERT(doc["not-date"].Tag() == "tag:yaml.org,2002:str");
284 			YAML_ASSERT(doc["not-date"].to<std::string>() == "2002-04-28");
285 			YAML_ASSERT(doc["picture"].Tag() == "tag:yaml.org,2002:binary");
286 			YAML_ASSERT(doc["picture"].to<std::string>() ==
287 				"R0lGODlhDAAMAIQAAP//9/X\n"
288 				"17unp5WZmZgAAAOfn515eXv\n"
289 				"Pz7Y6OjuDg4J+fn5OTk6enp\n"
290 				"56enmleECcgggoBADs=\n"
291 			);
292 			YAML_ASSERT(doc["application specific tag"].Tag() == "!something");
293 			YAML_ASSERT(doc["application specific tag"].to<std::string>() ==
294 				"The semantics of the tag\n"
295 				"above may be different for\n"
296 				"different documents."
297 			);
298 			return true;
299 		}
300 
301 		// 2.24
GlobalTags()302 		TEST GlobalTags()
303 		{
304 			PARSE(doc, ex2_24);
305 			YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:shape");
306 			YAML_ASSERT(doc.size() == 3);
307 			YAML_ASSERT(doc[0].Tag() == "tag:clarkevans.com,2002:circle");
308 			YAML_ASSERT(doc[0].size() == 2);
309 			YAML_ASSERT(doc[0]["center"].size() == 2);
310 			YAML_ASSERT(doc[0]["center"]["x"].to<int>() == 73);
311 			YAML_ASSERT(doc[0]["center"]["y"].to<int>() == 129);
312 			YAML_ASSERT(doc[0]["radius"].to<int>() == 7);
313 			YAML_ASSERT(doc[1].Tag() == "tag:clarkevans.com,2002:line");
314 			YAML_ASSERT(doc[1].size() == 2);
315 			YAML_ASSERT(doc[1]["start"].size() == 2);
316 			YAML_ASSERT(doc[1]["start"]["x"].to<int>() == 73);
317 			YAML_ASSERT(doc[1]["start"]["y"].to<int>() == 129);
318 			YAML_ASSERT(doc[1]["finish"].size() == 2);
319 			YAML_ASSERT(doc[1]["finish"]["x"].to<int>() == 89);
320 			YAML_ASSERT(doc[1]["finish"]["y"].to<int>() == 102);
321 			YAML_ASSERT(doc[2].Tag() == "tag:clarkevans.com,2002:label");
322 			YAML_ASSERT(doc[2].size() == 3);
323 			YAML_ASSERT(doc[2]["start"].size() == 2);
324 			YAML_ASSERT(doc[2]["start"]["x"].to<int>() == 73);
325 			YAML_ASSERT(doc[2]["start"]["y"].to<int>() == 129);
326 			YAML_ASSERT(doc[2]["color"].to<std::string>() == "0xFFEEBB");
327 			YAML_ASSERT(doc[2]["text"].to<std::string>() == "Pretty vector drawing.");
328 			return true;
329 		}
330 
331 		// 2.25
UnorderedSets()332 		TEST UnorderedSets()
333 		{
334 			PARSE(doc, ex2_25);
335 			YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:set");
336 			YAML_ASSERT(doc.size() == 3);
337 			YAML_ASSERT(IsNull(doc["Mark McGwire"]));
338 			YAML_ASSERT(IsNull(doc["Sammy Sosa"]));
339 			YAML_ASSERT(IsNull(doc["Ken Griffey"]));
340 			return true;
341 		}
342 
343 		// 2.26
OrderedMappings()344 		TEST OrderedMappings()
345 		{
346 			PARSE(doc, ex2_26);
347 			YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:omap");
348 			YAML_ASSERT(doc.size() == 3);
349 			YAML_ASSERT(doc[0].size() == 1);
350 			YAML_ASSERT(doc[0]["Mark McGwire"].to<int>() == 65);
351 			YAML_ASSERT(doc[1].size() == 1);
352 			YAML_ASSERT(doc[1]["Sammy Sosa"].to<int>() == 63);
353 			YAML_ASSERT(doc[2].size() == 1);
354 			YAML_ASSERT(doc[2]["Ken Griffey"].to<int>() == 58);
355 			return true;
356 		}
357 
358 		// 2.27
Invoice()359 		TEST Invoice()
360 		{
361 			PARSE(doc, ex2_27);
362 			YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:invoice");
363 			YAML_ASSERT(doc.size() == 8);
364 			YAML_ASSERT(doc["invoice"].to<int>() == 34843);
365 			YAML_ASSERT(doc["date"].to<std::string>() == "2001-01-23");
366 			YAML_ASSERT(doc["bill-to"].size() == 3);
367 			YAML_ASSERT(doc["bill-to"]["given"].to<std::string>() == "Chris");
368 			YAML_ASSERT(doc["bill-to"]["family"].to<std::string>() == "Dumars");
369 			YAML_ASSERT(doc["bill-to"]["address"].size() == 4);
370 			YAML_ASSERT(doc["bill-to"]["address"]["lines"].to<std::string>() == "458 Walkman Dr.\nSuite #292\n");
371 			YAML_ASSERT(doc["bill-to"]["address"]["city"].to<std::string>() == "Royal Oak");
372 			YAML_ASSERT(doc["bill-to"]["address"]["state"].to<std::string>() == "MI");
373 			YAML_ASSERT(doc["bill-to"]["address"]["postal"].to<std::string>() == "48046");
374 			YAML_ASSERT(doc["ship-to"].size() == 3);
375 			YAML_ASSERT(doc["ship-to"]["given"].to<std::string>() == "Chris");
376 			YAML_ASSERT(doc["ship-to"]["family"].to<std::string>() == "Dumars");
377 			YAML_ASSERT(doc["ship-to"]["address"].size() == 4);
378 			YAML_ASSERT(doc["ship-to"]["address"]["lines"].to<std::string>() == "458 Walkman Dr.\nSuite #292\n");
379 			YAML_ASSERT(doc["ship-to"]["address"]["city"].to<std::string>() == "Royal Oak");
380 			YAML_ASSERT(doc["ship-to"]["address"]["state"].to<std::string>() == "MI");
381 			YAML_ASSERT(doc["ship-to"]["address"]["postal"].to<std::string>() == "48046");
382 			YAML_ASSERT(doc["product"].size() == 2);
383 			YAML_ASSERT(doc["product"][0].size() == 4);
384 			YAML_ASSERT(doc["product"][0]["sku"].to<std::string>() == "BL394D");
385 			YAML_ASSERT(doc["product"][0]["quantity"].to<int>() == 4);
386 			YAML_ASSERT(doc["product"][0]["description"].to<std::string>() == "Basketball");
387 			YAML_ASSERT(doc["product"][0]["price"].to<std::string>() == "450.00");
388 			YAML_ASSERT(doc["product"][1].size() == 4);
389 			YAML_ASSERT(doc["product"][1]["sku"].to<std::string>() == "BL4438H");
390 			YAML_ASSERT(doc["product"][1]["quantity"].to<int>() == 1);
391 			YAML_ASSERT(doc["product"][1]["description"].to<std::string>() == "Super Hoop");
392 			YAML_ASSERT(doc["product"][1]["price"].to<std::string>() == "2392.00");
393 			YAML_ASSERT(doc["tax"].to<std::string>() == "251.42");
394 			YAML_ASSERT(doc["total"].to<std::string>() == "4443.52");
395 			YAML_ASSERT(doc["comments"].to<std::string>() == "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.");
396 			return true;
397 		}
398 
399 		// 2.28
LogFile()400 		TEST LogFile()
401 		{
402 			PARSE(doc, ex2_28);
403 			YAML_ASSERT(doc.size() == 3);
404 			YAML_ASSERT(doc["Time"].to<std::string>() == "2001-11-23 15:01:42 -5");
405 			YAML_ASSERT(doc["User"].to<std::string>() == "ed");
406 			YAML_ASSERT(doc["Warning"].to<std::string>() == "This is an error message for the log file");
407 
408 			PARSE_NEXT(doc);
409 			YAML_ASSERT(doc.size() == 3);
410 			YAML_ASSERT(doc["Time"].to<std::string>() == "2001-11-23 15:02:31 -5");
411 			YAML_ASSERT(doc["User"].to<std::string>() == "ed");
412 			YAML_ASSERT(doc["Warning"].to<std::string>() == "A slightly different error message.");
413 
414 			PARSE_NEXT(doc);
415 			YAML_ASSERT(doc.size() == 4);
416 			YAML_ASSERT(doc["Date"].to<std::string>() == "2001-11-23 15:03:17 -5");
417 			YAML_ASSERT(doc["User"].to<std::string>() == "ed");
418 			YAML_ASSERT(doc["Fatal"].to<std::string>() == "Unknown variable \"bar\"");
419 			YAML_ASSERT(doc["Stack"].size() == 2);
420 			YAML_ASSERT(doc["Stack"][0].size() == 3);
421 			YAML_ASSERT(doc["Stack"][0]["file"].to<std::string>() == "TopClass.py");
422 			YAML_ASSERT(doc["Stack"][0]["line"].to<std::string>() == "23");
423 			YAML_ASSERT(doc["Stack"][0]["code"].to<std::string>() == "x = MoreObject(\"345\\n\")\n");
424 			YAML_ASSERT(doc["Stack"][1].size() == 3);
425 			YAML_ASSERT(doc["Stack"][1]["file"].to<std::string>() == "MoreClass.py");
426 			YAML_ASSERT(doc["Stack"][1]["line"].to<std::string>() == "58");
427 			YAML_ASSERT(doc["Stack"][1]["code"].to<std::string>() == "foo = bar");
428 			return true;
429 		}
430 
431 		// TODO: 5.1 - 5.2 BOM
432 
433 		// 5.3
BlockStructureIndicators()434 		TEST BlockStructureIndicators()
435 		{
436 			PARSE(doc, ex5_3);
437 			YAML_ASSERT(doc.size() == 2);
438 			YAML_ASSERT(doc["sequence"].size() == 2);
439 			YAML_ASSERT(doc["sequence"][0].to<std::string>() == "one");
440 			YAML_ASSERT(doc["sequence"][1].to<std::string>() == "two");
441 			YAML_ASSERT(doc["mapping"].size() == 2);
442 			YAML_ASSERT(doc["mapping"]["sky"].to<std::string>() == "blue");
443 			YAML_ASSERT(doc["mapping"]["sea"].to<std::string>() == "green");
444 			return true;
445 		}
446 
447 		// 5.4
FlowStructureIndicators()448 		TEST FlowStructureIndicators()
449 		{
450 			PARSE(doc, ex5_4);
451 			YAML_ASSERT(doc.size() == 2);
452 			YAML_ASSERT(doc["sequence"].size() == 2);
453 			YAML_ASSERT(doc["sequence"][0].to<std::string>() == "one");
454 			YAML_ASSERT(doc["sequence"][1].to<std::string>() == "two");
455 			YAML_ASSERT(doc["mapping"].size() == 2);
456 			YAML_ASSERT(doc["mapping"]["sky"].to<std::string>() == "blue");
457 			YAML_ASSERT(doc["mapping"]["sea"].to<std::string>() == "green");
458 			return true;
459 		}
460 
461 		// 5.5
CommentIndicator()462 		TEST CommentIndicator()
463 		{
464 			PARSE(doc, ex5_5);
465 			YAML_ASSERT(doc.size() == 0);
466 			return true;
467 		}
468 
469 		// 5.6
NodePropertyIndicators()470 		TEST NodePropertyIndicators()
471 		{
472 			PARSE(doc, ex5_6);
473 			YAML_ASSERT(doc.size() == 2);
474 			YAML_ASSERT(doc["anchored"].to<std::string>() == "value"); // TODO: assert tag
475 			YAML_ASSERT(doc["alias"].to<std::string>() == "value");
476 			return true;
477 		}
478 
479 		// 5.7
BlockScalarIndicators()480 		TEST BlockScalarIndicators()
481 		{
482 			PARSE(doc, ex5_7);
483 			YAML_ASSERT(doc.size() == 2);
484 			YAML_ASSERT(doc["literal"].to<std::string>() == "some\ntext\n");
485 			YAML_ASSERT(doc["folded"].to<std::string>() == "some text\n");
486 			return true;
487 		}
488 
489 		// 5.8
QuotedScalarIndicators()490 		TEST QuotedScalarIndicators()
491 		{
492 			PARSE(doc, ex5_8);
493 			YAML_ASSERT(doc.size() == 2);
494 			YAML_ASSERT(doc["single"].to<std::string>() == "text");
495 			YAML_ASSERT(doc["double"].to<std::string>() == "text");
496 			return true;
497 		}
498 
499 		// TODO: 5.9 directive
500 		// TODO: 5.10 reserved indicator
501 
502 		// 5.11
LineBreakCharacters()503 		TEST LineBreakCharacters()
504 		{
505 			PARSE(doc, ex5_11);
506 			YAML_ASSERT(doc.to<std::string>() == "Line break (no glyph)\nLine break (glyphed)\n");
507 			return true;
508 		}
509 
510 		// 5.12
TabsAndSpaces()511 		TEST TabsAndSpaces()
512 		{
513 			PARSE(doc, ex5_12);
514 			YAML_ASSERT(doc.size() == 2);
515 			YAML_ASSERT(doc["quoted"].to<std::string>() == "Quoted\t");
516 			YAML_ASSERT(doc["block"].to<std::string>() ==
517 						"void main() {\n"
518 						"\tprintf(\"Hello, world!\\n\");\n"
519 						"}");
520 			return true;
521 		}
522 
523 		// 5.13
EscapedCharacters()524 		TEST EscapedCharacters()
525 		{
526 			PARSE(doc, ex5_13);
527 			YAML_ASSERT(doc.to<std::string>() == "Fun with \x5C \x22 \x07 \x08 \x1B \x0C \x0A \x0D \x09 \x0B " + std::string("\x00", 1) + " \x20 \xA0 \x85 \xe2\x80\xa8 \xe2\x80\xa9 A A A");
528 			return true;
529 		}
530 
531 		// 5.14
InvalidEscapedCharacters()532 		TEST InvalidEscapedCharacters()
533 		{
534 			std::stringstream stream(ex5_14);
535 			try {
536 				YAML::Parser parser(stream);
537 				YAML::Node doc;
538 				parser.GetNextDocument(doc);
539 			} catch(const YAML::ParserException& e) {
540 				YAML_ASSERT(e.msg == std::string(YAML::ErrorMsg::INVALID_ESCAPE) + "c");
541 				return true;
542 			}
543 
544 			return false;
545 		}
546 
547 		// 6.1
IndentationSpaces()548 		TEST IndentationSpaces()
549 		{
550 			PARSE(doc, ex6_1);
551 			YAML_ASSERT(doc.size() == 1);
552 			YAML_ASSERT(doc["Not indented"].size() == 2);
553 			YAML_ASSERT(doc["Not indented"]["By one space"].to<std::string>() == "By four\n  spaces\n");
554 			YAML_ASSERT(doc["Not indented"]["Flow style"].size() == 3);
555 			YAML_ASSERT(doc["Not indented"]["Flow style"][0].to<std::string>() == "By two");
556 			YAML_ASSERT(doc["Not indented"]["Flow style"][1].to<std::string>() == "Also by two");
557 			YAML_ASSERT(doc["Not indented"]["Flow style"][2].to<std::string>() == "Still by two");
558 			return true;
559 		}
560 
561 		// 6.2
IndentationIndicators()562 		TEST IndentationIndicators()
563 		{
564 			PARSE(doc, ex6_2);
565 			YAML_ASSERT(doc.size() == 1);
566 			YAML_ASSERT(doc["a"].size() == 2);
567 			YAML_ASSERT(doc["a"][0].to<std::string>() == "b");
568 			YAML_ASSERT(doc["a"][1].size() == 2);
569 			YAML_ASSERT(doc["a"][1][0].to<std::string>() == "c");
570 			YAML_ASSERT(doc["a"][1][1].to<std::string>() == "d");
571 			return true;
572 		}
573 
574 		// 6.3
SeparationSpaces()575 		TEST SeparationSpaces()
576 		{
577 			PARSE(doc, ex6_3);
578 			YAML_ASSERT(doc.size() == 2);
579 			YAML_ASSERT(doc[0].size() == 1);
580 			YAML_ASSERT(doc[0]["foo"].to<std::string>() == "bar");
581 			YAML_ASSERT(doc[1].size() == 2);
582 			YAML_ASSERT(doc[1][0].to<std::string>() == "baz");
583 			YAML_ASSERT(doc[1][1].to<std::string>() == "baz");
584 			return true;
585 		}
586 
587 		// 6.4
LinePrefixes()588 		TEST LinePrefixes()
589 		{
590 			PARSE(doc, ex6_4);
591 			YAML_ASSERT(doc.size() == 3);
592 			YAML_ASSERT(doc["plain"].to<std::string>() == "text lines");
593 			YAML_ASSERT(doc["quoted"].to<std::string>() == "text lines");
594 			YAML_ASSERT(doc["block"].to<std::string>() == "text\n \tlines\n");
595 			return true;
596 		}
597 
598 		// 6.5
EmptyLines()599 		TEST EmptyLines()
600 		{
601 			PARSE(doc, ex6_5);
602 			YAML_ASSERT(doc.size() == 2);
603 			YAML_ASSERT(doc["Folding"].to<std::string>() == "Empty line\nas a line feed");
604 			YAML_ASSERT(doc["Chomping"].to<std::string>() == "Clipped empty lines\n");
605 			return true;
606 		}
607 
608 		// 6.6
LineFolding()609 		TEST LineFolding()
610 		{
611 			PARSE(doc, ex6_6);
612 			YAML_ASSERT(doc.to<std::string>() == "trimmed\n\n\nas space");
613 			return true;
614 		}
615 
616 		// 6.7
BlockFolding()617 		TEST BlockFolding()
618 		{
619 			PARSE(doc, ex6_7);
620 			YAML_ASSERT(doc.to<std::string>() == "foo \n\n\t bar\n\nbaz\n");
621 			return true;
622 		}
623 
624 		// 6.8
FlowFolding()625 		TEST FlowFolding()
626 		{
627 			PARSE(doc, ex6_8);
628 			YAML_ASSERT(doc.to<std::string>() == " foo\nbar\nbaz ");
629 			return true;
630 		}
631 
632 		// 6.9
SeparatedComment()633 		TEST SeparatedComment()
634 		{
635 			PARSE(doc, ex6_9);
636 			YAML_ASSERT(doc.size() == 1);
637 			YAML_ASSERT(doc["key"].to<std::string>() == "value");
638 			return true;
639 		}
640 
641 		// 6.10
CommentLines()642 		TEST CommentLines()
643 		{
644 			PARSE(doc, ex6_10);
645 			YAML_ASSERT(doc.size() == 0);
646 			return true;
647 		}
648 
649 		// 6.11
MultiLineComments()650 		TEST MultiLineComments()
651 		{
652 			PARSE(doc, ex6_11);
653 			YAML_ASSERT(doc.size() == 1);
654 			YAML_ASSERT(doc["key"].to<std::string>() == "value");
655 			return true;
656 		}
657 
658 		struct StringMap {
659 			typedef std::map<std::string, std::string> Map;
660 			Map _;
661 		};
662 
operator ==(const StringMap & m,const StringMap & n)663 		bool operator == (const StringMap& m, const StringMap& n) {
664 			return m._ == n._;
665 		}
666 
operator >>(const YAML::Node & node,StringMap & m)667 		void operator >> (const YAML::Node& node, StringMap& m) {
668 			m._.clear();
669 			for(YAML::Iterator it=node.begin();it!=node.end();++it) {
670 				std::string key = it.first().to<std::string>();
671 				std::string value = it.second().to<std::string>();
672 				m._[key] = value;
673 			}
674 		}
675 
676 
677 		// 6.12
SeparationSpacesII()678 		TEST SeparationSpacesII()
679 		{
680 			PARSE(doc, ex6_12);
681 			std::map<std::string, std::string> key;
682 			key["first"] = "Sammy";
683 			key["last"] = "Sosa";
684 			YAML_ASSERT(doc.size() == 1);
685 			YAML_ASSERT(doc[key].size() == 2);
686 			YAML_ASSERT(doc[key]["hr"].to<int>() == 65);
687 			YAML_ASSERT(doc[key]["avg"].to<std::string>() == "0.278");
688 			return true;
689 		}
690 
691 		// 6.13
ReservedDirectives()692 		TEST ReservedDirectives()
693 		{
694 			PARSE(doc, ex6_13);
695 			return true;
696 		}
697 
698 		// 6.14
YAMLDirective()699 		TEST YAMLDirective()
700 		{
701 			PARSE(doc, ex6_14);
702 			return true;
703 		}
704 
705 		// 6.15
InvalidRepeatedYAMLDirective()706 		TEST InvalidRepeatedYAMLDirective()
707 		{
708 			try {
709 				PARSE(doc, ex6_15);
710 			} catch(const YAML::ParserException& e) {
711 				if(e.msg == YAML::ErrorMsg::REPEATED_YAML_DIRECTIVE)
712 					return true;
713 
714 				throw;
715 			}
716 
717 			return "  No exception was thrown";
718 		}
719 
720 		// 6.16
TagDirective()721 		TEST TagDirective()
722 		{
723 			PARSE(doc, ex6_16);
724 			YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:str");
725 			YAML_ASSERT(doc.to<std::string>() == "foo");
726 			return true;
727 		}
728 
729 		// 6.17
InvalidRepeatedTagDirective()730 		TEST InvalidRepeatedTagDirective()
731 		{
732 			try {
733 				PARSE(doc, ex6_17);
734 			} catch(const YAML::ParserException& e) {
735 				if(e.msg == YAML::ErrorMsg::REPEATED_TAG_DIRECTIVE)
736 					return true;
737 
738 				throw;
739 			}
740 
741 			return "  No exception was thrown";
742 		}
743 
744 		// 6.18
PrimaryTagHandle()745 		TEST PrimaryTagHandle()
746 		{
747 			PARSE(doc, ex6_18);
748 			YAML_ASSERT(doc.Tag() == "!foo");
749 			YAML_ASSERT(doc.to<std::string>() == "bar");
750 
751 			PARSE_NEXT(doc);
752 			YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo");
753 			YAML_ASSERT(doc.to<std::string>() == "bar");
754 			return true;
755 		}
756 
757 		// 6.19
SecondaryTagHandle()758 		TEST SecondaryTagHandle()
759 		{
760 			PARSE(doc, ex6_19);
761 			YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/int");
762 			YAML_ASSERT(doc.to<std::string>() == "1 - 3");
763 			return true;
764 		}
765 
766 		// 6.20
TagHandles()767 		TEST TagHandles()
768 		{
769 			PARSE(doc, ex6_20);
770 			YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo");
771 			YAML_ASSERT(doc.to<std::string>() == "bar");
772 			return true;
773 		}
774 
775 		// 6.21
LocalTagPrefix()776 		TEST LocalTagPrefix()
777 		{
778 			PARSE(doc, ex6_21);
779 			YAML_ASSERT(doc.Tag() == "!my-light");
780 			YAML_ASSERT(doc.to<std::string>() == "fluorescent");
781 
782 			PARSE_NEXT(doc);
783 			YAML_ASSERT(doc.Tag() == "!my-light");
784 			YAML_ASSERT(doc.to<std::string>() == "green");
785 			return true;
786 		}
787 
788 		// 6.22
GlobalTagPrefix()789 		TEST GlobalTagPrefix()
790 		{
791 			PARSE(doc, ex6_22);
792 			YAML_ASSERT(doc.size() == 1);
793 			YAML_ASSERT(doc[0].Tag() == "tag:example.com,2000:app/foo");
794 			YAML_ASSERT(doc[0].to<std::string>() == "bar");
795 			return true;
796 		}
797 
798 		// 6.23
NodeProperties()799 		TEST NodeProperties()
800 		{
801 			PARSE(doc, ex6_23);
802 			YAML_ASSERT(doc.size() == 2);
803 			for(YAML::Iterator it=doc.begin();it!=doc.end();++it) {
804 				if(it.first().to<std::string>() == "foo") {
805 					YAML_ASSERT(it.first().Tag() == "tag:yaml.org,2002:str");
806 					YAML_ASSERT(it.second().Tag() == "tag:yaml.org,2002:str");
807 					YAML_ASSERT(it.second().to<std::string>() == "bar");
808 				} else if(it.first().to<std::string>() == "baz") {
809 					YAML_ASSERT(it.second().to<std::string>() == "foo");
810 				} else
811 					return "  unknown key";
812 			}
813 
814 			return true;
815 		}
816 
817 		// 6.24
VerbatimTags()818 		TEST VerbatimTags()
819 		{
820 			PARSE(doc, ex6_24);
821 			YAML_ASSERT(doc.size() == 1);
822 			for(YAML::Iterator it=doc.begin();it!=doc.end();++it) {
823 				YAML_ASSERT(it.first().Tag() == "tag:yaml.org,2002:str");
824 				YAML_ASSERT(it.first().to<std::string>() == "foo");
825 				YAML_ASSERT(it.second().Tag() == "!bar");
826 				YAML_ASSERT(it.second().to<std::string>() == "baz");
827 			}
828 			return true;
829 		}
830 
831 		// 6.25
InvalidVerbatimTags()832 		TEST InvalidVerbatimTags()
833 		{
834 			PARSE(doc, ex6_25);
835 			return "  not implemented yet"; // TODO: check tags (but we probably will say these are valid, I think)
836 		}
837 
838 		// 6.26
TagShorthands()839 		TEST TagShorthands()
840 		{
841 			PARSE(doc, ex6_26);
842 			YAML_ASSERT(doc.size() == 3);
843 			YAML_ASSERT(doc[0].Tag() == "!local");
844 			YAML_ASSERT(doc[0].to<std::string>() == "foo");
845 			YAML_ASSERT(doc[1].Tag() == "tag:yaml.org,2002:str");
846 			YAML_ASSERT(doc[1].to<std::string>() == "bar");
847 			YAML_ASSERT(doc[2].Tag() == "tag:example.com,2000:app/tag%21");
848 			YAML_ASSERT(doc[2].to<std::string>() == "baz");
849 			return true;
850 		}
851 
852 		// 6.27
InvalidTagShorthands()853 		TEST InvalidTagShorthands()
854 		{
855 			bool threw = false;
856 			try {
857 				PARSE(doc, ex6_27a);
858 			} catch(const YAML::ParserException& e) {
859 				threw = true;
860 				if(e.msg != YAML::ErrorMsg::TAG_WITH_NO_SUFFIX)
861 					throw;
862 			}
863 
864 			if(!threw)
865 				return "  No exception was thrown for a tag with no suffix";
866 
867 			PARSE(doc, ex6_27b); // TODO: should we reject this one (since !h! is not declared)?
868 			return "  not implemented yet";
869 		}
870 
871 		// 6.28
NonSpecificTags()872 		TEST NonSpecificTags()
873 		{
874 			PARSE(doc, ex6_28);
875 			YAML_ASSERT(doc.size() == 3);
876 			YAML_ASSERT(doc[0].to<std::string>() == "12"); // TODO: check tags. How?
877 			YAML_ASSERT(doc[1].to<int>() == 12);
878 			YAML_ASSERT(doc[2].to<std::string>() == "12");
879 			return true;
880 		}
881 
882 		// 6.29
NodeAnchors()883 		TEST NodeAnchors()
884 		{
885 			PARSE(doc, ex6_29);
886 			YAML_ASSERT(doc.size() == 2);
887 			YAML_ASSERT(doc["First occurrence"].to<std::string>() == "Value");
888 			YAML_ASSERT(doc["Second occurrence"].to<std::string>() == "Value");
889 			return true;
890 		}
891 
892 		// 7.1
AliasNodes()893 		TEST AliasNodes()
894 		{
895 			PARSE(doc, ex7_1);
896 			YAML_ASSERT(doc.size() == 4);
897 			YAML_ASSERT(doc["First occurrence"].to<std::string>() == "Foo");
898 			YAML_ASSERT(doc["Second occurrence"].to<std::string>() == "Foo");
899 			YAML_ASSERT(doc["Override anchor"].to<std::string>() == "Bar");
900 			YAML_ASSERT(doc["Reuse anchor"].to<std::string>() == "Bar");
901 			return true;
902 		}
903 
904 		// 7.2
EmptyNodes()905 		TEST EmptyNodes()
906 		{
907 			PARSE(doc, ex7_2);
908 			YAML_ASSERT(doc.size() == 2);
909 			for(YAML::Iterator it=doc.begin();it!=doc.end();++it) {
910 				if(it.first().to<std::string>() == "foo") {
911 					YAML_ASSERT(it.second().Tag() == "tag:yaml.org,2002:str");
912 					YAML_ASSERT(it.second().to<std::string>() == "");
913 				} else if(it.first().to<std::string>() == "") {
914 					YAML_ASSERT(it.first().Tag() == "tag:yaml.org,2002:str");
915 					YAML_ASSERT(it.second().to<std::string>() == "bar");
916 				} else
917 					return "  unexpected key";
918 			}
919 			return true;
920 		}
921 
922 		// 7.3
CompletelyEmptyNodes()923 		TEST CompletelyEmptyNodes()
924 		{
925 			PARSE(doc, ex7_3);
926 			YAML_ASSERT(doc.size() == 2);
927 			YAML_ASSERT(IsNull(doc["foo"]));
928 			YAML_ASSERT(doc[YAML::Null].to<std::string>() == "bar");
929 			return true;
930 		}
931 
932 		// 7.4
DoubleQuotedImplicitKeys()933 		TEST DoubleQuotedImplicitKeys()
934 		{
935 			PARSE(doc, ex7_4);
936 			YAML_ASSERT(doc.size() == 1);
937 			YAML_ASSERT(doc["implicit block key"].size() == 1);
938 			YAML_ASSERT(doc["implicit block key"][0].size() == 1);
939 			YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"].to<std::string>() == "value");
940 			return true;
941 		}
942 
943 		// 7.5
DoubleQuotedLineBreaks()944 		TEST DoubleQuotedLineBreaks()
945 		{
946 			PARSE(doc, ex7_5);
947 			YAML_ASSERT(doc.to<std::string>() == "folded to a space,\nto a line feed, or \t \tnon-content");
948 			return true;
949 		}
950 
951 		// 7.6
DoubleQuotedLines()952 		TEST DoubleQuotedLines()
953 		{
954 			PARSE(doc, ex7_6);
955 			YAML_ASSERT(doc.to<std::string>() == " 1st non-empty\n2nd non-empty 3rd non-empty ");
956 			return true;
957 		}
958 
959 		// 7.7
SingleQuotedCharacters()960 		TEST SingleQuotedCharacters()
961 		{
962 			PARSE(doc, ex7_7);
963 			YAML_ASSERT(doc.to<std::string>() == "here's to \"quotes\"");
964 			return true;
965 		}
966 
967 		// 7.8
SingleQuotedImplicitKeys()968 		TEST SingleQuotedImplicitKeys()
969 		{
970 			PARSE(doc, ex7_8);
971 			YAML_ASSERT(doc.size() == 1);
972 			YAML_ASSERT(doc["implicit block key"].size() == 1);
973 			YAML_ASSERT(doc["implicit block key"][0].size() == 1);
974 			YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"].to<std::string>() == "value");
975 			return true;
976 		}
977 
978 		// 7.9
SingleQuotedLines()979 		TEST SingleQuotedLines()
980 		{
981 			PARSE(doc, ex7_9);
982 			YAML_ASSERT(doc.to<std::string>() == " 1st non-empty\n2nd non-empty 3rd non-empty ");
983 			return true;
984 		}
985 
986 		// 7.10
PlainCharacters()987 		TEST PlainCharacters()
988 		{
989 			PARSE(doc, ex7_10);
990 			YAML_ASSERT(doc.size() == 6);
991 			YAML_ASSERT(doc[0].to<std::string>() == "::vector");
992 			YAML_ASSERT(doc[1].to<std::string>() == ": - ()");
993 			YAML_ASSERT(doc[2].to<std::string>() == "Up, up, and away!");
994 			YAML_ASSERT(doc[3].to<int>() == -123);
995 			YAML_ASSERT(doc[4].to<std::string>() == "http://example.com/foo#bar");
996 			YAML_ASSERT(doc[5].size() == 5);
997 			YAML_ASSERT(doc[5][0].to<std::string>() == "::vector");
998 			YAML_ASSERT(doc[5][1].to<std::string>() == ": - ()");
999 			YAML_ASSERT(doc[5][2].to<std::string>() == "Up, up, and away!");
1000 			YAML_ASSERT(doc[5][3].to<int>() == -123);
1001 			YAML_ASSERT(doc[5][4].to<std::string>() == "http://example.com/foo#bar");
1002 			return true;
1003 		}
1004 
1005 		// 7.11
PlainImplicitKeys()1006 		TEST PlainImplicitKeys()
1007 		{
1008 			PARSE(doc, ex7_11);
1009 			YAML_ASSERT(doc.size() == 1);
1010 			YAML_ASSERT(doc["implicit block key"].size() == 1);
1011 			YAML_ASSERT(doc["implicit block key"][0].size() == 1);
1012 			YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"].to<std::string>() == "value");
1013 			return true;
1014 		}
1015 
1016 		// 7.12
PlainLines()1017 		TEST PlainLines()
1018 		{
1019 			PARSE(doc, ex7_12);
1020 			YAML_ASSERT(doc.to<std::string>() == "1st non-empty\n2nd non-empty 3rd non-empty");
1021 			return true;
1022 		}
1023 
1024 		// 7.13
FlowSequence()1025 		TEST FlowSequence()
1026 		{
1027 			PARSE(doc, ex7_13);
1028 			YAML_ASSERT(doc.size() == 2);
1029 			YAML_ASSERT(doc[0].size() == 2);
1030 			YAML_ASSERT(doc[0][0].to<std::string>() == "one");
1031 			YAML_ASSERT(doc[0][1].to<std::string>() == "two");
1032 			YAML_ASSERT(doc[1].size() == 2);
1033 			YAML_ASSERT(doc[1][0].to<std::string>() == "three");
1034 			YAML_ASSERT(doc[1][1].to<std::string>() == "four");
1035 			return true;
1036 		}
1037 
1038 		// 7.14
FlowSequenceEntries()1039 		TEST FlowSequenceEntries()
1040 		{
1041 			PARSE(doc, ex7_14);
1042 			YAML_ASSERT(doc.size() == 5);
1043 			YAML_ASSERT(doc[0].to<std::string>() == "double quoted");
1044 			YAML_ASSERT(doc[1].to<std::string>() == "single quoted");
1045 			YAML_ASSERT(doc[2].to<std::string>() == "plain text");
1046 			YAML_ASSERT(doc[3].size() == 1);
1047 			YAML_ASSERT(doc[3][0].to<std::string>() == "nested");
1048 			YAML_ASSERT(doc[4].size() == 1);
1049 			YAML_ASSERT(doc[4]["single"].to<std::string>() == "pair");
1050 			return true;
1051 		}
1052 
1053 		// 7.15
FlowMappings()1054 		TEST FlowMappings()
1055 		{
1056 			PARSE(doc, ex7_15);
1057 			YAML_ASSERT(doc.size() == 2);
1058 			YAML_ASSERT(doc[0].size() == 2);
1059 			YAML_ASSERT(doc[0]["one"].to<std::string>() == "two");
1060 			YAML_ASSERT(doc[0]["three"].to<std::string>() == "four");
1061 			YAML_ASSERT(doc[1].size() == 2);
1062 			YAML_ASSERT(doc[1]["five"].to<std::string>() == "six");
1063 			YAML_ASSERT(doc[1]["seven"].to<std::string>() == "eight");
1064 			return true;
1065 		}
1066 
1067 		// 7.16
FlowMappingEntries()1068 		TEST FlowMappingEntries()
1069 		{
1070 			PARSE(doc, ex7_16);
1071 			YAML_ASSERT(doc.size() == 3);
1072 			YAML_ASSERT(doc["explicit"].to<std::string>() == "entry");
1073 			YAML_ASSERT(doc["implicit"].to<std::string>() == "entry");
1074 			YAML_ASSERT(IsNull(doc[YAML::Null]));
1075 			return true;
1076 		}
1077 
1078 		// 7.17
FlowMappingSeparateValues()1079 		TEST FlowMappingSeparateValues()
1080 		{
1081 			PARSE(doc, ex7_17);
1082 			YAML_ASSERT(doc.size() == 4);
1083 			YAML_ASSERT(doc["unquoted"].to<std::string>() == "separate");
1084 			YAML_ASSERT(IsNull(doc["http://foo.com"]));
1085 			YAML_ASSERT(IsNull(doc["omitted value"]));
1086 			YAML_ASSERT(doc[YAML::Null].to<std::string>() == "omitted key");
1087 			return true;
1088 		}
1089 
1090 		// 7.18
FlowMappingAdjacentValues()1091 		TEST FlowMappingAdjacentValues()
1092 		{
1093 			PARSE(doc, ex7_18);
1094 			YAML_ASSERT(doc.size() == 3);
1095 			YAML_ASSERT(doc["adjacent"].to<std::string>() == "value");
1096 			YAML_ASSERT(doc["readable"].to<std::string>() == "value");
1097 			YAML_ASSERT(IsNull(doc["empty"]));
1098 			return true;
1099 		}
1100 
1101 		// 7.19
SinglePairFlowMappings()1102 		TEST SinglePairFlowMappings()
1103 		{
1104 			PARSE(doc, ex7_19);
1105 			YAML_ASSERT(doc.size() == 1);
1106 			YAML_ASSERT(doc[0].size() == 1);
1107 			YAML_ASSERT(doc[0]["foo"].to<std::string>() == "bar");
1108 			return true;
1109 		}
1110 
1111 		// 7.20
SinglePairExplicitEntry()1112 		TEST SinglePairExplicitEntry()
1113 		{
1114 			PARSE(doc, ex7_20);
1115 			YAML_ASSERT(doc.size() == 1);
1116 			YAML_ASSERT(doc[0].size() == 1);
1117 			YAML_ASSERT(doc[0]["foo bar"].to<std::string>() == "baz");
1118 			return true;
1119 		}
1120 
1121 		// 7.21
SinglePairImplicitEntries()1122 		TEST SinglePairImplicitEntries()
1123 		{
1124 			PARSE(doc, ex7_21);
1125 			YAML_ASSERT(doc.size() == 3);
1126 			YAML_ASSERT(doc[0].size() == 1);
1127 			YAML_ASSERT(doc[0][0].size() == 1);
1128 			YAML_ASSERT(doc[0][0]["YAML"].to<std::string>() == "separate");
1129 			YAML_ASSERT(doc[1].size() == 1);
1130 			YAML_ASSERT(doc[1][0].size() == 1);
1131 			YAML_ASSERT(doc[1][0][YAML::Null].to<std::string>() == "empty key entry");
1132 			YAML_ASSERT(doc[2].size() == 1);
1133 			YAML_ASSERT(doc[2][0].size() == 1);
1134 			StringMap key;
1135 			key._["JSON"] = "like";
1136 			YAML_ASSERT(doc[2][0][key].to<std::string>() == "adjacent");
1137 			return true;
1138 		}
1139 
1140 		// 7.22
InvalidImplicitKeys()1141 		TEST InvalidImplicitKeys()
1142 		{
1143 			try {
1144 				PARSE(doc, ex7_22);
1145 			} catch(const YAML::Exception& e) {
1146 				if(e.msg == YAML::ErrorMsg::END_OF_SEQ_FLOW)
1147 					return true;
1148 
1149 				throw;
1150 			}
1151 			return "  no exception thrown";
1152 		}
1153 
1154 		// 7.23
FlowContent()1155 		TEST FlowContent()
1156 		{
1157 			PARSE(doc, ex7_23);
1158 			YAML_ASSERT(doc.size() == 5);
1159 			YAML_ASSERT(doc[0].size() == 2);
1160 			YAML_ASSERT(doc[0][0].to<std::string>() == "a");
1161 			YAML_ASSERT(doc[0][1].to<std::string>() == "b");
1162 			YAML_ASSERT(doc[1].size() == 1);
1163 			YAML_ASSERT(doc[1]["a"].to<std::string>() == "b");
1164 			YAML_ASSERT(doc[2].to<std::string>() == "a");
1165 			YAML_ASSERT(doc[3].to<char>() == 'b');
1166 			YAML_ASSERT(doc[4].to<std::string>() == "c");
1167 			return true;
1168 		}
1169 
1170 		// 7.24
FlowNodes()1171 		TEST FlowNodes()
1172 		{
1173 			PARSE(doc, ex7_24);
1174 			YAML_ASSERT(doc.size() == 5);
1175 			YAML_ASSERT(doc[0].Tag() == "tag:yaml.org,2002:str");
1176 			YAML_ASSERT(doc[0].to<std::string>() == "a");
1177 			YAML_ASSERT(doc[1].to<char>() == 'b');
1178 			YAML_ASSERT(doc[2].to<std::string>() == "c");
1179 			YAML_ASSERT(doc[3].to<std::string>() == "c");
1180 			YAML_ASSERT(doc[4].Tag() == "tag:yaml.org,2002:str");
1181 			YAML_ASSERT(doc[4].to<std::string>() == "");
1182 			return true;
1183 		}
1184 
1185 		// 8.1
BlockScalarHeader()1186 		TEST BlockScalarHeader()
1187 		{
1188 			PARSE(doc, ex8_1);
1189 			YAML_ASSERT(doc.size() == 4);
1190 			YAML_ASSERT(doc[0].to<std::string>() == "literal\n");
1191 			YAML_ASSERT(doc[1].to<std::string>() == " folded\n");
1192 			YAML_ASSERT(doc[2].to<std::string>() == "keep\n\n");
1193 			YAML_ASSERT(doc[3].to<std::string>() == " strip");
1194 			return true;
1195 		}
1196 
1197 		// 8.2
BlockIndentationHeader()1198 		TEST BlockIndentationHeader()
1199 		{
1200 			PARSE(doc, ex8_2);
1201 			YAML_ASSERT(doc.size() == 4);
1202 			YAML_ASSERT(doc[0].to<std::string>() == "detected\n");
1203 			YAML_ASSERT(doc[1].to<std::string>() == "\n\n# detected\n");
1204 			YAML_ASSERT(doc[2].to<std::string>() == " explicit\n");
1205 			YAML_ASSERT(doc[3].to<std::string>() == "\t\ndetected\n");
1206 			return true;
1207 		}
1208 
1209 		// 8.3
InvalidBlockScalarIndentationIndicators()1210 		TEST InvalidBlockScalarIndentationIndicators()
1211 		{
1212 			{
1213 				bool threw = false;
1214 				try {
1215 					PARSE(doc, ex8_3a);
1216 				} catch(const YAML::Exception& e) {
1217 					if(e.msg != YAML::ErrorMsg::END_OF_SEQ)
1218 						throw;
1219 
1220 					threw = true;
1221 				}
1222 
1223 				if(!threw)
1224 					return "  no exception thrown for less indented auto-detecting indentation for a literal block scalar";
1225 			}
1226 
1227 			{
1228 				bool threw = false;
1229 				try {
1230 					PARSE(doc, ex8_3b);
1231 				} catch(const YAML::Exception& e) {
1232 					if(e.msg != YAML::ErrorMsg::END_OF_SEQ)
1233 						throw;
1234 
1235 					threw = true;
1236 				}
1237 
1238 				if(!threw)
1239 					return "  no exception thrown for less indented auto-detecting indentation for a folded block scalar";
1240 			}
1241 
1242 			{
1243 				bool threw = false;
1244 				try {
1245 					PARSE(doc, ex8_3c);
1246 				} catch(const YAML::Exception& e) {
1247 					if(e.msg != YAML::ErrorMsg::END_OF_SEQ)
1248 						throw;
1249 
1250 					threw = true;
1251 				}
1252 
1253 				if(!threw)
1254 					return "  no exception thrown for less indented explicit indentation for a literal block scalar";
1255 			}
1256 
1257 			return true;
1258 		}
1259 
1260 		// 8.4
ChompingFinalLineBreak()1261 		TEST ChompingFinalLineBreak()
1262 		{
1263 			PARSE(doc, ex8_4);
1264 			YAML_ASSERT(doc.size() == 3);
1265 			YAML_ASSERT(doc["strip"].to<std::string>() == "text");
1266 			YAML_ASSERT(doc["clip"].to<std::string>() == "text\n");
1267 			YAML_ASSERT(doc["keep"].to<std::string>() == "text\n");
1268 			return true;
1269 		}
1270 
1271 		// 8.5
ChompingTrailingLines()1272 		TEST ChompingTrailingLines()
1273 		{
1274 			PARSE(doc, ex8_5);
1275 			YAML_ASSERT(doc.size() == 3);
1276 			YAML_ASSERT(doc["strip"].to<std::string>() == "# text");
1277 			YAML_ASSERT(doc["clip"].to<std::string>() == "# text\n");
1278 			YAML_ASSERT(doc["keep"].to<std::string>() == "# text\n"); // Note: I believe this is a bug in the YAML spec - it should be "# text\n\n"
1279 			return true;
1280 		}
1281 
1282 		// 8.6
EmptyScalarChomping()1283 		TEST EmptyScalarChomping()
1284 		{
1285 			PARSE(doc, ex8_6);
1286 			YAML_ASSERT(doc.size() == 3);
1287 			YAML_ASSERT(doc["strip"].to<std::string>() == "");
1288 			YAML_ASSERT(doc["clip"].to<std::string>() == "");
1289 			YAML_ASSERT(doc["keep"].to<std::string>() == "\n");
1290 			return true;
1291 		}
1292 
1293 		// 8.7
LiteralScalar()1294 		TEST LiteralScalar()
1295 		{
1296 			PARSE(doc, ex8_7);
1297 			YAML_ASSERT(doc.to<std::string>() == "literal\n\ttext\n");
1298 			return true;
1299 		}
1300 
1301 		// 8.8
LiteralContent()1302 		TEST LiteralContent()
1303 		{
1304 			PARSE(doc, ex8_8);
1305 			YAML_ASSERT(doc.to<std::string>() == "\n\nliteral\n \n\ntext\n");
1306 			return true;
1307 		}
1308 
1309 		// 8.9
FoldedScalar()1310 		TEST FoldedScalar()
1311 		{
1312 			PARSE(doc, ex8_9);
1313 			YAML_ASSERT(doc.to<std::string>() == "folded text\n");
1314 			return true;
1315 		}
1316 
1317 		// 8.10
FoldedLines()1318 		TEST FoldedLines()
1319 		{
1320 			PARSE(doc, ex8_10);
1321 			YAML_ASSERT(doc.to<std::string>() == "\nfolded line\nnext line\n  * bullet\n\n  * list\n  * lines\n\nlast line\n");
1322 			return true;
1323 		}
1324 
1325 		// 8.11
MoreIndentedLines()1326 		TEST MoreIndentedLines()
1327 		{
1328 			return true; // same as 8.10
1329 		}
1330 
1331 		// 8.12
EmptySeparationLines()1332 		TEST EmptySeparationLines()
1333 		{
1334 			return true; // same as 8.10
1335 		}
1336 
1337 		// 8.13
FinalEmptyLines()1338 		TEST FinalEmptyLines()
1339 		{
1340 			return true; // same as 8.10
1341 		}
1342 
1343 		// 8.14
BlockSequence()1344 		TEST BlockSequence()
1345 		{
1346 			PARSE(doc, ex8_14);
1347 			YAML_ASSERT(doc.size() == 1);
1348 			YAML_ASSERT(doc["block sequence"].size() == 2);
1349 			YAML_ASSERT(doc["block sequence"][0].to<std::string>() == "one");
1350 			YAML_ASSERT(doc["block sequence"][1].size() == 1);
1351 			YAML_ASSERT(doc["block sequence"][1]["two"].to<std::string>() == "three");
1352 			return true;
1353 		}
1354 
1355 		// 8.15
BlockSequenceEntryTypes()1356 		TEST BlockSequenceEntryTypes()
1357 		{
1358 			PARSE(doc, ex8_15);
1359 			YAML_ASSERT(doc.size() == 4);
1360 			YAML_ASSERT(YAML::IsNull(doc[0]));
1361 			YAML_ASSERT(doc[1].to<std::string>() == "block node\n");
1362 			YAML_ASSERT(doc[2].size() == 2);
1363 			YAML_ASSERT(doc[2][0].to<std::string>() == "one");
1364 			YAML_ASSERT(doc[2][1].to<std::string>() == "two");
1365 			YAML_ASSERT(doc[3].size() == 1);
1366 			YAML_ASSERT(doc[3]["one"].to<std::string>() == "two");
1367 			return true;
1368 		}
1369 
1370 		// 8.16
BlockMappings()1371 		TEST BlockMappings()
1372 		{
1373 			PARSE(doc, ex8_16);
1374 			YAML_ASSERT(doc.size() == 1);
1375 			YAML_ASSERT(doc["block mapping"].size() == 1);
1376 			YAML_ASSERT(doc["block mapping"]["key"].to<std::string>() == "value");
1377 			return true;
1378 		}
1379 
1380 		// 8.17
ExplicitBlockMappingEntries()1381 		TEST ExplicitBlockMappingEntries()
1382 		{
1383 			PARSE(doc, ex8_17);
1384 			YAML_ASSERT(doc.size() == 2);
1385 			YAML_ASSERT(IsNull(doc["explicit key"]));
1386 			YAML_ASSERT(doc["block key\n"].size() == 2);
1387 			YAML_ASSERT(doc["block key\n"][0].to<std::string>() == "one");
1388 			YAML_ASSERT(doc["block key\n"][1].to<std::string>() == "two");
1389 			return true;
1390 		}
1391 
1392 		// 8.18
ImplicitBlockMappingEntries()1393 		TEST ImplicitBlockMappingEntries()
1394 		{
1395 			PARSE(doc, ex8_18);
1396 			YAML_ASSERT(doc.size() == 3);
1397 			YAML_ASSERT(doc["plain key"].to<std::string>() == "in-line value");
1398 			YAML_ASSERT(IsNull(doc[YAML::Null]));
1399 			YAML_ASSERT(doc["quoted key"].size() == 1);
1400 			YAML_ASSERT(doc["quoted key"][0].to<std::string>() == "entry");
1401 			return true;
1402 		}
1403 
1404 		// 8.19
CompactBlockMappings()1405 		TEST CompactBlockMappings()
1406 		{
1407 			PARSE(doc, ex8_19);
1408 			YAML_ASSERT(doc.size() == 2);
1409 			YAML_ASSERT(doc[0].size() == 1);
1410 			YAML_ASSERT(doc[0]["sun"].to<std::string>() == "yellow");
1411 			YAML_ASSERT(doc[1].size() == 1);
1412 			std::map<std::string, std::string> key;
1413 			key["earth"] = "blue";
1414 			YAML_ASSERT(doc[1][key].size() == 1);
1415 			YAML_ASSERT(doc[1][key]["moon"].to<std::string>() == "white");
1416 			return true;
1417 		}
1418 
1419 		// 8.20
BlockNodeTypes()1420 		TEST BlockNodeTypes()
1421 		{
1422 			PARSE(doc, ex8_20);
1423 			YAML_ASSERT(doc.size() == 3);
1424 			YAML_ASSERT(doc[0].to<std::string>() == "flow in block");
1425 			YAML_ASSERT(doc[1].to<std::string>() == "Block scalar\n");
1426 			YAML_ASSERT(doc[2].size() == 1);
1427 			YAML_ASSERT(doc[2]["foo"].to<std::string>() == "bar");
1428 			return true;
1429 		}
1430 
1431 		// 8.21
BlockScalarNodes()1432 		TEST BlockScalarNodes()
1433 		{
1434 			PARSE(doc, ex8_21);
1435 			YAML_ASSERT(doc.size() == 2);
1436 			YAML_ASSERT(doc["literal"].to<std::string>() == "value"); // Note: I believe this is a bug in the YAML spec - it should be "value\n"
1437 			YAML_ASSERT(doc["folded"].to<std::string>() == "value");
1438 			YAML_ASSERT(doc["folded"].Tag() == "!foo");
1439 			return true;
1440 		}
1441 
1442 		// 8.22
BlockCollectionNodes()1443 		TEST BlockCollectionNodes()
1444 		{
1445 			PARSE(doc, ex8_22);
1446 			YAML_ASSERT(doc.size() == 2);
1447 			YAML_ASSERT(doc["sequence"].size() == 2);
1448 			YAML_ASSERT(doc["sequence"][0].to<std::string>() == "entry");
1449 			YAML_ASSERT(doc["sequence"][1].size() == 1);
1450 			YAML_ASSERT(doc["sequence"][1][0].to<std::string>() == "nested");
1451 			YAML_ASSERT(doc["mapping"].size() == 1);
1452 			YAML_ASSERT(doc["mapping"]["foo"].to<std::string>() == "bar");
1453 			return true;
1454 		}
1455 	}
1456 }
1457