spectests.cpp 67.5 KB
Newer Older
Jesse Beder's avatar
Jesse Beder committed
1
#include "spectests.h"
2
#include "yaml-cpp/yaml.h"
Jesse Beder's avatar
Jesse Beder committed
3
4
5
6
7
#include <fstream>
#include <sstream>
#include <vector>
#include <iostream>

Jesse Beder's avatar
Jesse Beder committed
8
9
10
11
12
13
14
15
16
17
18
namespace {
	struct TEST {
		TEST(): ok(false) {}
		TEST(bool ok_): ok(ok_) {}
		TEST(const char *error_): ok(false), error(error_) {}
		
		bool ok;
		std::string error;
	};
}

19
#define YAML_ASSERT(cond) do { if(!(cond)) return "  Assert failed: " #cond; } while(false)
20
21
22
23
24
25
#define PARSE(doc, input) \
	std::stringstream stream(input);\
	YAML::Parser parser(stream);\
	YAML::Node doc;\
	parser.GetNextDocument(doc)
#define PARSE_NEXT(doc) parser.GetNextDocument(doc)
26

Jesse Beder's avatar
Jesse Beder committed
27
28
namespace Test {
	namespace {
Jesse Beder's avatar
Jesse Beder committed
29
		void RunSpecTest(TEST (*test)(), const std::string& index, const std::string& name, int& passed, int& total) {
Jesse Beder's avatar
Jesse Beder committed
30
			TEST ret;
Jesse Beder's avatar
Jesse Beder committed
31
			try {
Jesse Beder's avatar
Jesse Beder committed
32
				ret = test();
Jesse Beder's avatar
Jesse Beder committed
33
			} catch(const YAML::Exception& e) {
Jesse Beder's avatar
Jesse Beder committed
34
				ret.ok = false;
35
				ret.error = std::string("  Exception caught: ") + e.what();
Jesse Beder's avatar
Jesse Beder committed
36
			}
Jesse Beder's avatar
Jesse Beder committed
37
			
Jesse Beder's avatar
Jesse Beder committed
38
			if(!ret.ok) {
Jesse Beder's avatar
Jesse Beder committed
39
				std::cout << "Spec test " << index << " failed: " << name << "\n";
Jesse Beder's avatar
Jesse Beder committed
40
				std::cout << ret.error << "\n";
Jesse Beder's avatar
Jesse Beder committed
41
			}
Jesse Beder's avatar
Jesse Beder committed
42
43
44
45
			
			if(ret.ok)
				passed++;
			total++;
Jesse Beder's avatar
Jesse Beder committed
46
47
48
49
		}
	}

	namespace Spec {
50
		// 2.1
Jesse Beder's avatar
Jesse Beder committed
51
		TEST SeqScalars() {
Jesse Beder's avatar
Jesse Beder committed
52
53
54
55
			std::string input =
				"- Mark McGwire\n"
				"- Sammy Sosa\n"
				"- Ken Griffey";
56
57

			PARSE(doc, input);
58
			YAML_ASSERT(doc.size() == 3);
59
60
61
			YAML_ASSERT(doc[0].to<std::string>() == "Mark McGwire");
			YAML_ASSERT(doc[1].to<std::string>() == "Sammy Sosa");
			YAML_ASSERT(doc[2].to<std::string>() == "Ken Griffey");
Jesse Beder's avatar
Jesse Beder committed
62
63
64
			return true;
		}
		
65
		// 2.2
Jesse Beder's avatar
Jesse Beder committed
66
		TEST MappingScalarsToScalars() {
Jesse Beder's avatar
Jesse Beder committed
67
68
69
70
71
			std::string input =
				"hr:  65    # Home runs\n"
				"avg: 0.278 # Batting average\n"
				"rbi: 147   # Runs Batted In";

72
			PARSE(doc, input);
73
			YAML_ASSERT(doc.size() == 3);
74
75
76
			YAML_ASSERT(doc["hr"].to<std::string>() == "65");
			YAML_ASSERT(doc["avg"].to<std::string>() == "0.278");
			YAML_ASSERT(doc["rbi"].to<std::string>() == "147");
Jesse Beder's avatar
Jesse Beder committed
77
78
			return true;
		}
Jesse Beder's avatar
Jesse Beder committed
79
		
80
		// 2.3
Jesse Beder's avatar
Jesse Beder committed
81
82
83
84
85
86
87
88
89
90
		TEST MappingScalarsToSequences() {
			std::string input =
				"american:\n"
				"- Boston Red Sox\n"
				"- Detroit Tigers\n"
				"- New York Yankees\n"
				"national:\n"
				"- New York Mets\n"
				"- Chicago Cubs\n"
				"- Atlanta Braves";
91
92

			PARSE(doc, input);
Jesse Beder's avatar
Jesse Beder committed
93
94
			YAML_ASSERT(doc.size() == 2);
			YAML_ASSERT(doc["american"].size() == 3);
95
96
97
			YAML_ASSERT(doc["american"][0].to<std::string>() == "Boston Red Sox");
			YAML_ASSERT(doc["american"][1].to<std::string>() == "Detroit Tigers");
			YAML_ASSERT(doc["american"][2].to<std::string>() == "New York Yankees");
Jesse Beder's avatar
Jesse Beder committed
98
			YAML_ASSERT(doc["national"].size() == 3);
99
100
101
			YAML_ASSERT(doc["national"][0].to<std::string>() == "New York Mets");
			YAML_ASSERT(doc["national"][1].to<std::string>() == "Chicago Cubs");
			YAML_ASSERT(doc["national"][2].to<std::string>() == "Atlanta Braves");
Jesse Beder's avatar
Jesse Beder committed
102
103
104
			return true;
		}
		
105
		// 2.4
Jesse Beder's avatar
Jesse Beder committed
106
107
108
109
110
111
112
113
114
115
116
		TEST SequenceOfMappings()
		{
			std::string input =
				"-\n"
				"  name: Mark McGwire\n"
				"  hr:   65\n"
				"  avg:  0.278\n"
				"-\n"
				"  name: Sammy Sosa\n"
				"  hr:   63\n"
				"  avg:  0.288";
117
118

			PARSE(doc, input);
Jesse Beder's avatar
Jesse Beder committed
119
120
			YAML_ASSERT(doc.size() == 2);
			YAML_ASSERT(doc[0].size() == 3);
121
122
123
			YAML_ASSERT(doc[0]["name"].to<std::string>() == "Mark McGwire");
			YAML_ASSERT(doc[0]["hr"].to<std::string>() == "65");
			YAML_ASSERT(doc[0]["avg"].to<std::string>() == "0.278");
Jesse Beder's avatar
Jesse Beder committed
124
			YAML_ASSERT(doc[1].size() == 3);
125
126
127
			YAML_ASSERT(doc[1]["name"].to<std::string>() == "Sammy Sosa");
			YAML_ASSERT(doc[1]["hr"].to<std::string>() == "63");
			YAML_ASSERT(doc[1]["avg"].to<std::string>() == "0.288");
Jesse Beder's avatar
Jesse Beder committed
128
129
130
			return true;
		}
		
131
		// 2.5
Jesse Beder's avatar
Jesse Beder committed
132
133
134
135
136
137
		TEST SequenceOfSequences()
		{
			std::string input =
				"- [name        , hr, avg  ]\n"
				"- [Mark McGwire, 65, 0.278]\n"
				"- [Sammy Sosa  , 63, 0.288]";
138
139

			PARSE(doc, input);
Jesse Beder's avatar
Jesse Beder committed
140
141
			YAML_ASSERT(doc.size() == 3);
			YAML_ASSERT(doc[0].size() == 3);
142
143
144
			YAML_ASSERT(doc[0][0].to<std::string>() == "name");
			YAML_ASSERT(doc[0][1].to<std::string>() == "hr");
			YAML_ASSERT(doc[0][2].to<std::string>() == "avg");
Jesse Beder's avatar
Jesse Beder committed
145
			YAML_ASSERT(doc[1].size() == 3);
146
147
148
			YAML_ASSERT(doc[1][0].to<std::string>() == "Mark McGwire");
			YAML_ASSERT(doc[1][1].to<std::string>() == "65");
			YAML_ASSERT(doc[1][2].to<std::string>() == "0.278");
Jesse Beder's avatar
Jesse Beder committed
149
			YAML_ASSERT(doc[2].size() == 3);
150
151
152
			YAML_ASSERT(doc[2][0].to<std::string>() == "Sammy Sosa");
			YAML_ASSERT(doc[2][1].to<std::string>() == "63");
			YAML_ASSERT(doc[2][2].to<std::string>() == "0.288");
Jesse Beder's avatar
Jesse Beder committed
153
154
155
			return true;
		}
		
156
		// 2.6
Jesse Beder's avatar
Jesse Beder committed
157
158
159
160
161
162
163
164
		TEST MappingOfMappings()
		{
			std::string input =
				"Mark McGwire: {hr: 65, avg: 0.278}\n"
				"Sammy Sosa: {\n"
				"    hr: 63,\n"
				"    avg: 0.288\n"
				"  }";
165
166

			PARSE(doc, input);
Jesse Beder's avatar
Jesse Beder committed
167
168
			YAML_ASSERT(doc.size() == 2);
			YAML_ASSERT(doc["Mark McGwire"].size() == 2);
169
170
			YAML_ASSERT(doc["Mark McGwire"]["hr"].to<std::string>() == "65");
			YAML_ASSERT(doc["Mark McGwire"]["avg"].to<std::string>() == "0.278");
Jesse Beder's avatar
Jesse Beder committed
171
			YAML_ASSERT(doc["Sammy Sosa"].size() == 2);
172
173
			YAML_ASSERT(doc["Sammy Sosa"]["hr"].to<std::string>() == "63");
			YAML_ASSERT(doc["Sammy Sosa"]["avg"].to<std::string>() == "0.288");
Jesse Beder's avatar
Jesse Beder committed
174
175
176
			return true;
		}
		
177
		// 2.7
Jesse Beder's avatar
Jesse Beder committed
178
179
180
181
182
183
184
185
186
187
188
189
190
		TEST TwoDocumentsInAStream()
		{
			std::string input =
				"# Ranking of 1998 home runs\n"
				"---\n"
				"- Mark McGwire\n"
				"- Sammy Sosa\n"
				"- Ken Griffey\n"
				"\n"
				"# Team ranking\n"
				"---\n"
				"- Chicago Cubs\n"
				"- St Louis Cardinals";
191
192

			PARSE(doc, input);
Jesse Beder's avatar
Jesse Beder committed
193
			YAML_ASSERT(doc.size() == 3);
194
195
196
			YAML_ASSERT(doc[0].to<std::string>() == "Mark McGwire");
			YAML_ASSERT(doc[1].to<std::string>() == "Sammy Sosa");
			YAML_ASSERT(doc[2].to<std::string>() == "Ken Griffey");
197
198

			PARSE_NEXT(doc);
Jesse Beder's avatar
Jesse Beder committed
199
			YAML_ASSERT(doc.size() == 2);
200
201
			YAML_ASSERT(doc[0].to<std::string>() == "Chicago Cubs");
			YAML_ASSERT(doc[1].to<std::string>() == "St Louis Cardinals");
Jesse Beder's avatar
Jesse Beder committed
202
203
204
			return true;
		}
		
205
		// 2.8
Jesse Beder's avatar
Jesse Beder committed
206
207
208
209
210
211
212
213
214
215
216
217
218
		TEST PlayByPlayFeed()
		{
			std::string input =
				"---\n"
				"time: 20:03:20\n"
				"player: Sammy Sosa\n"
				"action: strike (miss)\n"
				"...\n"
				"---\n"
				"time: 20:03:47\n"
				"player: Sammy Sosa\n"
				"action: grand slam\n"
				"...";
219
220

			PARSE(doc, input);
Jesse Beder's avatar
Jesse Beder committed
221
			YAML_ASSERT(doc.size() == 3);
222
223
224
			YAML_ASSERT(doc["time"].to<std::string>() == "20:03:20");
			YAML_ASSERT(doc["player"].to<std::string>() == "Sammy Sosa");
			YAML_ASSERT(doc["action"].to<std::string>() == "strike (miss)");
225
226

			PARSE_NEXT(doc);
Jesse Beder's avatar
Jesse Beder committed
227
			YAML_ASSERT(doc.size() == 3);
228
229
230
			YAML_ASSERT(doc["time"].to<std::string>() == "20:03:47");
			YAML_ASSERT(doc["player"].to<std::string>() == "Sammy Sosa");
			YAML_ASSERT(doc["action"].to<std::string>() == "grand slam");
Jesse Beder's avatar
Jesse Beder committed
231
232
233
			return true;
		}
		
234
		// 2.9
Jesse Beder's avatar
Jesse Beder committed
235
236
237
238
239
240
241
242
243
244
245
		TEST SingleDocumentWithTwoComments()
		{
			std::string input =
				"---\n"
				"hr: # 1998 hr ranking\n"
				"  - Mark McGwire\n"
				"  - Sammy Sosa\n"
				"rbi:\n"
				"  # 1998 rbi ranking\n"
				"  - Sammy Sosa\n"
				"  - Ken Griffey";
246
247

			PARSE(doc, input);
Jesse Beder's avatar
Jesse Beder committed
248
249
			YAML_ASSERT(doc.size() == 2);
			YAML_ASSERT(doc["hr"].size() == 2);
250
251
			YAML_ASSERT(doc["hr"][0].to<std::string>() == "Mark McGwire");
			YAML_ASSERT(doc["hr"][1].to<std::string>() == "Sammy Sosa");
Jesse Beder's avatar
Jesse Beder committed
252
			YAML_ASSERT(doc["rbi"].size() == 2);
253
254
			YAML_ASSERT(doc["rbi"][0].to<std::string>() == "Sammy Sosa");
			YAML_ASSERT(doc["rbi"][1].to<std::string>() == "Ken Griffey");
Jesse Beder's avatar
Jesse Beder committed
255
256
257
			return true;
		}
		
258
		// 2.10
Jesse Beder's avatar
Jesse Beder committed
259
260
261
262
263
264
265
266
267
268
269
		TEST SimpleAnchor()
		{
			std::string input =
				"---\n"
				"hr:\n"
				"  - Mark McGwire\n"
				"  # Following node labeled SS\n"
				"  - &SS Sammy Sosa\n"
				"rbi:\n"
				"  - *SS # Subsequent occurrence\n"
				"  - Ken Griffey";
270
271

			PARSE(doc, input);
Jesse Beder's avatar
Jesse Beder committed
272
273
			YAML_ASSERT(doc.size() == 2);
			YAML_ASSERT(doc["hr"].size() == 2);
274
275
			YAML_ASSERT(doc["hr"][0].to<std::string>() == "Mark McGwire");
			YAML_ASSERT(doc["hr"][1].to<std::string>() == "Sammy Sosa");
Jesse Beder's avatar
Jesse Beder committed
276
			YAML_ASSERT(doc["rbi"].size() == 2);
277
278
			YAML_ASSERT(doc["rbi"][0].to<std::string>() == "Sammy Sosa");
			YAML_ASSERT(doc["rbi"][1].to<std::string>() == "Ken Griffey");
Jesse Beder's avatar
Jesse Beder committed
279
			return true;
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
		}
		
		struct Pair {
			Pair() {}
			Pair(const std::string& f, const std::string& s): first(f), second(s) {}
			std::string first, second;
		};
		
		bool operator == (const Pair& p, const Pair& q) {
			return p.first == q.first && p.second == q.second;
		}
		
		void operator >> (const YAML::Node& node, Pair& p) {
			node[0] >> p.first;
			node[1] >> p.second;
		}
		
297
		// 2.11
298
299
300
301
302
303
304
305
306
307
308
309
310
		TEST MappingBetweenSequences()
		{
			std::string input =
				"? - Detroit Tigers\n"
				"  - Chicago cubs\n"
				":\n"
				"  - 2001-07-23\n"
				"\n"
				"? [ New York Yankees,\n"
				"    Atlanta Braves ]\n"
				": [ 2001-07-02, 2001-08-12,\n"
				"    2001-08-14 ]";

311
			PARSE(doc, input);
312
			YAML_ASSERT(doc.size() == 2);
313
			YAML_ASSERT(doc[Pair("Detroit Tigers", "Chicago cubs")].size() == 1);
314
			YAML_ASSERT(doc[Pair("Detroit Tigers", "Chicago cubs")][0].to<std::string>() == "2001-07-23");
315
			YAML_ASSERT(doc[Pair("New York Yankees", "Atlanta Braves")].size() == 3);
316
317
318
			YAML_ASSERT(doc[Pair("New York Yankees", "Atlanta Braves")][0].to<std::string>() == "2001-07-02");
			YAML_ASSERT(doc[Pair("New York Yankees", "Atlanta Braves")][1].to<std::string>() == "2001-08-12");
			YAML_ASSERT(doc[Pair("New York Yankees", "Atlanta Braves")][2].to<std::string>() == "2001-08-14");
319
320
			return true;
		}
321
		
322
		// 2.12
323
324
325
326
327
328
329
330
331
332
333
		TEST CompactNestedMapping()
		{
			std::string input =
				"---\n"
				"# Products purchased\n"
				"- item    : Super Hoop\n"
				"  quantity: 1\n"
				"- item    : Basketball\n"
				"  quantity: 4\n"
				"- item    : Big Shoes\n"
				"  quantity: 1";
334
335

			PARSE(doc, input);
336
337
			YAML_ASSERT(doc.size() == 3);
			YAML_ASSERT(doc[0].size() == 2);
338
339
			YAML_ASSERT(doc[0]["item"].to<std::string>() == "Super Hoop");
			YAML_ASSERT(doc[0]["quantity"].to<int>() == 1);
340
			YAML_ASSERT(doc[1].size() == 2);
341
342
			YAML_ASSERT(doc[1]["item"].to<std::string>() == "Basketball");
			YAML_ASSERT(doc[1]["quantity"].to<int>() == 4);
343
			YAML_ASSERT(doc[2].size() == 2);
344
345
			YAML_ASSERT(doc[2]["item"].to<std::string>() == "Big Shoes");
			YAML_ASSERT(doc[2]["quantity"].to<int>() == 1);
346
347
348
			return true;
		}
		
349
		// 2.13
350
351
352
353
354
355
356
		TEST InLiteralsNewlinesArePreserved()
		{
			std::string input =
				"# ASCII Art\n"
				"--- |\n"
				"  \\//||\\/||\n"
				"  // ||  ||__";
357
358

			PARSE(doc, input);
359
			YAML_ASSERT(doc.to<std::string>() ==
360
361
362
363
						"\\//||\\/||\n"
						"// ||  ||__");
			return true;
		}
364
365
366
367
368
369
370
371
372
		
		// 2.14
		TEST InFoldedScalarsNewlinesBecomeSpaces()
		{
			std::string input =
				"--- >\n"
				"  Mark McGwire's\n"
				"  year was crippled\n"
				"  by a knee injury.";
373
374

			PARSE(doc, input);
375
			YAML_ASSERT(doc.to<std::string>() == "Mark McGwire's year was crippled by a knee injury.");
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
			return true;
		}
		
		// 2.15
		TEST FoldedNewlinesArePreservedForMoreIndentedAndBlankLines()
		{
			std::string input =
				">\n"
				" Sammy Sosa completed another\n"
				" fine season with great stats.\n"
				" \n"
				"   63 Home Runs\n"
				"   0.288 Batting Average\n"
				" \n"
				" What a year!";
391
392

			PARSE(doc, input);
393
			YAML_ASSERT(doc.to<std::string>() ==
Jesse Beder's avatar
Jesse Beder committed
394
						"Sammy Sosa completed another fine season with great stats.\n\n"
395
						"  63 Home Runs\n"
Jesse Beder's avatar
Jesse Beder committed
396
						"  0.288 Batting Average\n\n"
397
398
399
400
401
402
403
404
405
406
407
408
409
410
						"What a year!");
			return true;
		}
		
		// 2.16
		TEST IndentationDeterminesScope()
		{
			std::string input =
				"name: Mark McGwire\n"
				"accomplishment: >\n"
				"  Mark set a major league\n"
				"  home run record in 1998.\n"
				"stats: |\n"
				"  65 Home Runs\n"
411
				"  0.278 Batting Average\n";
412
413

			PARSE(doc, input);
414
			YAML_ASSERT(doc.size() == 3);
415
416
417
			YAML_ASSERT(doc["name"].to<std::string>() == "Mark McGwire");
			YAML_ASSERT(doc["accomplishment"].to<std::string>() == "Mark set a major league home run record in 1998.\n");
			YAML_ASSERT(doc["stats"].to<std::string>() == "65 Home Runs\n0.278 Batting Average\n");
418
419
420
421
422
423
424
425
426
427
428
429
430
431
			return true;
		}
		
		// 2.17
		TEST QuotedScalars()
		{
			std::string input =
				"unicode: \"Sosa did fine.\\u263A\"\n"
				"control: \"\\b1998\\t1999\\t2000\\n\"\n"
				"hex esc: \"\\x0d\\x0a is \\r\\n\"\n"
				"\n"
				"single: '\"Howdy!\" he cried.'\n"
				"quoted: ' # Not a ''comment''.'\n"
				"tie-fighter: '|\\-*-/|'";
432
433

			PARSE(doc, input);
434
			YAML_ASSERT(doc.size() == 6);
435
436
437
438
439
440
			YAML_ASSERT(doc["unicode"].to<std::string>() == "Sosa did fine.\xe2\x98\xba");
			YAML_ASSERT(doc["control"].to<std::string>() == "\b1998\t1999\t2000\n");
			YAML_ASSERT(doc["hex esc"].to<std::string>() == "\x0d\x0a is \r\n");
			YAML_ASSERT(doc["single"].to<std::string>() == "\"Howdy!\" he cried.");
			YAML_ASSERT(doc["quoted"].to<std::string>() == " # Not a 'comment'.");
			YAML_ASSERT(doc["tie-fighter"].to<std::string>() == "|\\-*-/|");
441
442
443
444
445
446
447
448
449
450
451
452
453
			return true;
		}
		
		// 2.18
		TEST MultiLineFlowScalars()
		{
			std::string input =
				"plain:\n"
				"  This unquoted scalar\n"
				"  spans many lines.\n"
				"\n"
				"quoted: \"So does this\n"
				"  quoted scalar.\\n\"";
454
455

			PARSE(doc, input);
456
			YAML_ASSERT(doc.size() == 2);
457
458
			YAML_ASSERT(doc["plain"].to<std::string>() == "This unquoted scalar spans many lines.");
			YAML_ASSERT(doc["quoted"].to<std::string>() == "So does this quoted scalar.\n");
459
460
461
			return true;
		}
		
Jesse Beder's avatar
Jesse Beder committed
462
		// TODO: 2.19 - 2.22 schema tags
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
		
		// 2.23
		TEST VariousExplicitTags()
		{
			std::string input =
				"---\n"
				"not-date: !!str 2002-04-28\n"
				"\n"
				"picture: !!binary |\n"
				" R0lGODlhDAAMAIQAAP//9/X\n"
				" 17unp5WZmZgAAAOfn515eXv\n"
				" Pz7Y6OjuDg4J+fn5OTk6enp\n"
				" 56enmleECcgggoBADs=\n"
				"\n"
				"application specific tag: !something |\n"
				" The semantics of the tag\n"
				" above may be different for\n"
				" different documents.";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 3);
484
			YAML_ASSERT(doc["not-date"].Tag() == "tag:yaml.org,2002:str");
485
			YAML_ASSERT(doc["not-date"].to<std::string>() == "2002-04-28");
486
			YAML_ASSERT(doc["picture"].Tag() == "tag:yaml.org,2002:binary");
487
			YAML_ASSERT(doc["picture"].to<std::string>() ==
488
489
490
491
492
				"R0lGODlhDAAMAIQAAP//9/X\n"
				"17unp5WZmZgAAAOfn515eXv\n"
				"Pz7Y6OjuDg4J+fn5OTk6enp\n"
				"56enmleECcgggoBADs=\n"
			);
493
			YAML_ASSERT(doc["application specific tag"].Tag() == "!something");
494
			YAML_ASSERT(doc["application specific tag"].to<std::string>() ==
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
				"The semantics of the tag\n"
				"above may be different for\n"
				"different documents."
			);
			return true;
		}
		
		// 2.24
		TEST GlobalTags()
		{
			std::string input =
				"%TAG ! tag:clarkevans.com,2002:\n"
				"--- !shape\n"
				"  # Use the ! handle for presenting\n"
				"  # tag:clarkevans.com,2002:circle\n"
				"- !circle\n"
				"  center: &ORIGIN {x: 73, y: 129}\n"
				"  radius: 7\n"
				"- !line\n"
				"  start: *ORIGIN\n"
				"  finish: { x: 89, y: 102 }\n"
				"- !label\n"
				"  start: *ORIGIN\n"
				"  color: 0xFFEEBB\n"
				"  text: Pretty vector drawing.";
			
			PARSE(doc, input);
522
			YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:shape");
523
			YAML_ASSERT(doc.size() == 3);
524
			YAML_ASSERT(doc[0].Tag() == "tag:clarkevans.com,2002:circle");
525
526
			YAML_ASSERT(doc[0].size() == 2);
			YAML_ASSERT(doc[0]["center"].size() == 2);
527
528
529
			YAML_ASSERT(doc[0]["center"]["x"].to<int>() == 73);
			YAML_ASSERT(doc[0]["center"]["y"].to<int>() == 129);
			YAML_ASSERT(doc[0]["radius"].to<int>() == 7);
530
			YAML_ASSERT(doc[1].Tag() == "tag:clarkevans.com,2002:line");
531
532
			YAML_ASSERT(doc[1].size() == 2);
			YAML_ASSERT(doc[1]["start"].size() == 2);
533
534
			YAML_ASSERT(doc[1]["start"]["x"].to<int>() == 73);
			YAML_ASSERT(doc[1]["start"]["y"].to<int>() == 129);
535
			YAML_ASSERT(doc[1]["finish"].size() == 2);
536
537
			YAML_ASSERT(doc[1]["finish"]["x"].to<int>() == 89);
			YAML_ASSERT(doc[1]["finish"]["y"].to<int>() == 102);
538
			YAML_ASSERT(doc[2].Tag() == "tag:clarkevans.com,2002:label");
539
540
			YAML_ASSERT(doc[2].size() == 3);
			YAML_ASSERT(doc[2]["start"].size() == 2);
541
542
543
544
			YAML_ASSERT(doc[2]["start"]["x"].to<int>() == 73);
			YAML_ASSERT(doc[2]["start"]["y"].to<int>() == 129);
			YAML_ASSERT(doc[2]["color"].to<std::string>() == "0xFFEEBB");
			YAML_ASSERT(doc[2]["text"].to<std::string>() == "Pretty vector drawing.");
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
			return true;
		}
		
		// 2.25
		TEST UnorderedSets()
		{
			std::string input =
				"# Sets are represented as a\n"
				"# Mapping where each key is\n"
				"# associated with a null value\n"
				"--- !!set\n"
				"? Mark McGwire\n"
				"? Sammy Sosa\n"
				"? Ken Griffey";
			
			PARSE(doc, input);
561
			YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:set");
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
			YAML_ASSERT(doc.size() == 3);
			YAML_ASSERT(IsNull(doc["Mark McGwire"]));
			YAML_ASSERT(IsNull(doc["Sammy Sosa"]));
			YAML_ASSERT(IsNull(doc["Ken Griffey"]));
			return true;
		}
		
		// 2.26
		TEST OrderedMappings()
		{
			std::string input =
				"# Ordered maps are represented as\n"
				"# A sequence of mappings, with\n"
				"# each mapping having one key\n"
				"--- !!omap\n"
				"- Mark McGwire: 65\n"
				"- Sammy Sosa: 63\n"
				"- Ken Griffey: 58";
			
			PARSE(doc, input);
582
			YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:omap");
583
584
			YAML_ASSERT(doc.size() == 3);
			YAML_ASSERT(doc[0].size() == 1);
585
			YAML_ASSERT(doc[0]["Mark McGwire"].to<int>() == 65);
586
			YAML_ASSERT(doc[1].size() == 1);
587
			YAML_ASSERT(doc[1]["Sammy Sosa"].to<int>() == 63);
588
			YAML_ASSERT(doc[2].size() == 1);
589
			YAML_ASSERT(doc[2]["Ken Griffey"].to<int>() == 58);
590
591
			return true;
		}
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
		
		// 2.27
		TEST Invoice()
		{
			std::string input =
				"--- !<tag:clarkevans.com,2002:invoice>\n"
				"invoice: 34843\n"
				"date   : 2001-01-23\n"
				"bill-to: &id001\n"
				"    given  : Chris\n"
				"    family : Dumars\n"
				"    address:\n"
				"        lines: |\n"
				"            458 Walkman Dr.\n"
				"            Suite #292\n"
				"        city    : Royal Oak\n"
				"        state   : MI\n"
				"        postal  : 48046\n"
				"ship-to: *id001\n"
				"product:\n"
				"    - sku         : BL394D\n"
				"      quantity    : 4\n"
				"      description : Basketball\n"
				"      price       : 450.00\n"
				"    - sku         : BL4438H\n"
				"      quantity    : 1\n"
				"      description : Super Hoop\n"
				"      price       : 2392.00\n"
				"tax  : 251.42\n"
				"total: 4443.52\n"
				"comments:\n"
				"    Late afternoon is best.\n"
				"    Backup contact is Nancy\n"
				"    Billsmer @ 338-4338.";
626
627

			PARSE(doc, input);
628
			YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:invoice");
629
			YAML_ASSERT(doc.size() == 8);
630
631
			YAML_ASSERT(doc["invoice"].to<int>() == 34843);
			YAML_ASSERT(doc["date"].to<std::string>() == "2001-01-23");
632
			YAML_ASSERT(doc["bill-to"].size() == 3);
633
634
			YAML_ASSERT(doc["bill-to"]["given"].to<std::string>() == "Chris");
			YAML_ASSERT(doc["bill-to"]["family"].to<std::string>() == "Dumars");
635
			YAML_ASSERT(doc["bill-to"]["address"].size() == 4);
636
637
638
639
			YAML_ASSERT(doc["bill-to"]["address"]["lines"].to<std::string>() == "458 Walkman Dr.\nSuite #292\n");
			YAML_ASSERT(doc["bill-to"]["address"]["city"].to<std::string>() == "Royal Oak");
			YAML_ASSERT(doc["bill-to"]["address"]["state"].to<std::string>() == "MI");
			YAML_ASSERT(doc["bill-to"]["address"]["postal"].to<std::string>() == "48046");
640
			YAML_ASSERT(doc["ship-to"].size() == 3);
641
642
			YAML_ASSERT(doc["ship-to"]["given"].to<std::string>() == "Chris");
			YAML_ASSERT(doc["ship-to"]["family"].to<std::string>() == "Dumars");
643
			YAML_ASSERT(doc["ship-to"]["address"].size() == 4);
644
645
646
647
			YAML_ASSERT(doc["ship-to"]["address"]["lines"].to<std::string>() == "458 Walkman Dr.\nSuite #292\n");
			YAML_ASSERT(doc["ship-to"]["address"]["city"].to<std::string>() == "Royal Oak");
			YAML_ASSERT(doc["ship-to"]["address"]["state"].to<std::string>() == "MI");
			YAML_ASSERT(doc["ship-to"]["address"]["postal"].to<std::string>() == "48046");
648
649
			YAML_ASSERT(doc["product"].size() == 2);
			YAML_ASSERT(doc["product"][0].size() == 4);
650
651
652
653
			YAML_ASSERT(doc["product"][0]["sku"].to<std::string>() == "BL394D");
			YAML_ASSERT(doc["product"][0]["quantity"].to<int>() == 4);
			YAML_ASSERT(doc["product"][0]["description"].to<std::string>() == "Basketball");
			YAML_ASSERT(doc["product"][0]["price"].to<std::string>() == "450.00");
654
			YAML_ASSERT(doc["product"][1].size() == 4);
655
656
657
658
659
660
661
			YAML_ASSERT(doc["product"][1]["sku"].to<std::string>() == "BL4438H");
			YAML_ASSERT(doc["product"][1]["quantity"].to<int>() == 1);
			YAML_ASSERT(doc["product"][1]["description"].to<std::string>() == "Super Hoop");
			YAML_ASSERT(doc["product"][1]["price"].to<std::string>() == "2392.00");
			YAML_ASSERT(doc["tax"].to<std::string>() == "251.42");
			YAML_ASSERT(doc["total"].to<std::string>() == "4443.52");
			YAML_ASSERT(doc["comments"].to<std::string>() == "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.");
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
			return true;
		}
		
		// 2.28
		TEST LogFile()
		{
			std::string input =
				"---\n"
				"Time: 2001-11-23 15:01:42 -5\n"
				"User: ed\n"
				"Warning:\n"
				"  This is an error message\n"
				"  for the log file\n"
				"---\n"
				"Time: 2001-11-23 15:02:31 -5\n"
				"User: ed\n"
				"Warning:\n"
				"  A slightly different error\n"
				"  message.\n"
				"---\n"
				"Date: 2001-11-23 15:03:17 -5\n"
				"User: ed\n"
				"Fatal:\n"
				"  Unknown variable \"bar\"\n"
				"Stack:\n"
				"  - file: TopClass.py\n"
				"    line: 23\n"
				"    code: |\n"
				"      x = MoreObject(\"345\\n\")\n"
				"  - file: MoreClass.py\n"
				"    line: 58\n"
				"    code: |-\n"
				"      foo = bar";
695
696

			PARSE(doc, input);
697
			YAML_ASSERT(doc.size() == 3);
698
699
700
			YAML_ASSERT(doc["Time"].to<std::string>() == "2001-11-23 15:01:42 -5");
			YAML_ASSERT(doc["User"].to<std::string>() == "ed");
			YAML_ASSERT(doc["Warning"].to<std::string>() == "This is an error message for the log file");
701
702

			PARSE_NEXT(doc);
703
			YAML_ASSERT(doc.size() == 3);
704
705
706
			YAML_ASSERT(doc["Time"].to<std::string>() == "2001-11-23 15:02:31 -5");
			YAML_ASSERT(doc["User"].to<std::string>() == "ed");
			YAML_ASSERT(doc["Warning"].to<std::string>() == "A slightly different error message.");
707
708

			PARSE_NEXT(doc);
709
			YAML_ASSERT(doc.size() == 4);
710
711
712
			YAML_ASSERT(doc["Date"].to<std::string>() == "2001-11-23 15:03:17 -5");
			YAML_ASSERT(doc["User"].to<std::string>() == "ed");
			YAML_ASSERT(doc["Fatal"].to<std::string>() == "Unknown variable \"bar\"");
713
714
			YAML_ASSERT(doc["Stack"].size() == 2);
			YAML_ASSERT(doc["Stack"][0].size() == 3);
715
716
717
			YAML_ASSERT(doc["Stack"][0]["file"].to<std::string>() == "TopClass.py");
			YAML_ASSERT(doc["Stack"][0]["line"].to<std::string>() == "23");
			YAML_ASSERT(doc["Stack"][0]["code"].to<std::string>() == "x = MoreObject(\"345\\n\")\n");
718
			YAML_ASSERT(doc["Stack"][1].size() == 3);
719
720
721
			YAML_ASSERT(doc["Stack"][1]["file"].to<std::string>() == "MoreClass.py");
			YAML_ASSERT(doc["Stack"][1]["line"].to<std::string>() == "58");
			YAML_ASSERT(doc["Stack"][1]["code"].to<std::string>() == "foo = bar");
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
			return true;
		}
		
		// TODO: 5.1 - 5.2 BOM
		
		// 5.3
		TEST BlockStructureIndicators()
		{
			std::string input =
				"sequence:\n"
				"- one\n"
				"- two\n"
				"mapping:\n"
				"  ? sky\n"
				"  : blue\n"
				"  sea : green";
738
739

			PARSE(doc, input);
740
741
			YAML_ASSERT(doc.size() == 2);
			YAML_ASSERT(doc["sequence"].size() == 2);
742
743
			YAML_ASSERT(doc["sequence"][0].to<std::string>() == "one");
			YAML_ASSERT(doc["sequence"][1].to<std::string>() == "two");
744
			YAML_ASSERT(doc["mapping"].size() == 2);
745
746
			YAML_ASSERT(doc["mapping"]["sky"].to<std::string>() == "blue");
			YAML_ASSERT(doc["mapping"]["sea"].to<std::string>() == "green");
747
748
749
750
751
752
753
754
755
			return true;
		}
		
		// 5.4
		TEST FlowStructureIndicators()
		{
			std::string input =
				"sequence: [ one, two, ]\n"
				"mapping: { sky: blue, sea: green }";
756
757

			PARSE(doc, input);
758
759
			YAML_ASSERT(doc.size() == 2);
			YAML_ASSERT(doc["sequence"].size() == 2);
760
761
			YAML_ASSERT(doc["sequence"][0].to<std::string>() == "one");
			YAML_ASSERT(doc["sequence"][1].to<std::string>() == "two");
762
			YAML_ASSERT(doc["mapping"].size() == 2);
763
764
			YAML_ASSERT(doc["mapping"]["sky"].to<std::string>() == "blue");
			YAML_ASSERT(doc["mapping"]["sea"].to<std::string>() == "green");
765
766
767
			return true;
		}
		
Jesse Beder's avatar
Jesse Beder committed
768
769
770
771
772
773
774
775
776
777
		// 5.5
		TEST CommentIndicator()
		{
			std::string input =
				"# Comment only.";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 0);
			return true;
		}
778
779
780
781
782
783
784
		
		// 5.6
		TEST NodePropertyIndicators()
		{
			std::string input =
				"anchored: !local &anchor value\n"
				"alias: *anchor";
785
786

			PARSE(doc, input);
787
			YAML_ASSERT(doc.size() == 2);
788
789
			YAML_ASSERT(doc["anchored"].to<std::string>() == "value"); // TODO: assert tag
			YAML_ASSERT(doc["alias"].to<std::string>() == "value");
790
791
792
793
794
795
796
797
798
799
800
801
802
			return true;
		}
		
		// 5.7
		TEST BlockScalarIndicators()
		{
			std::string input =
				"literal: |\n"
				"  some\n"
				"  text\n"
				"folded: >\n"
				"  some\n"
				"  text\n";
803
804

			PARSE(doc, input);
805
			YAML_ASSERT(doc.size() == 2);
806
807
			YAML_ASSERT(doc["literal"].to<std::string>() == "some\ntext\n");
			YAML_ASSERT(doc["folded"].to<std::string>() == "some text\n");
808
809
810
811
812
813
814
815
816
			return true;
		}
		
		// 5.8
		TEST QuotedScalarIndicators()
		{
			std::string input =
				"single: 'text'\n"
				"double: \"text\"";
817
818

			PARSE(doc, input);
819
			YAML_ASSERT(doc.size() == 2);
820
821
			YAML_ASSERT(doc["single"].to<std::string>() == "text");
			YAML_ASSERT(doc["double"].to<std::string>() == "text");
822
823
824
825
826
827
828
829
830
831
832
833
834
			return true;
		}
		
		// TODO: 5.9 directive
		// TODO: 5.10 reserved indicator
		
		// 5.11
		TEST LineBreakCharacters()
		{
			std::string input =
				"|\n"
				"  Line break (no glyph)\n"
				"  Line break (glyphed)\n";
835
836

			PARSE(doc, input);
837
			YAML_ASSERT(doc.to<std::string>() == "Line break (no glyph)\nLine break (glyphed)\n");
838
839
840
841
842
843
844
845
846
847
848
849
850
			return true;
		}
		
		// 5.12
		TEST TabsAndSpaces()
		{
			std::string input =
				"# Tabs and spaces\n"
				"quoted: \"Quoted\t\"\n"
				"block:	|\n"
				"  void main() {\n"
				"  \tprintf(\"Hello, world!\\n\");\n"
				"  }";
851
852

			PARSE(doc, input);
853
			YAML_ASSERT(doc.size() == 2);
854
855
			YAML_ASSERT(doc["quoted"].to<std::string>() == "Quoted\t");
			YAML_ASSERT(doc["block"].to<std::string>() ==
856
857
858
859
860
						"void main() {\n"
						"\tprintf(\"Hello, world!\\n\");\n"
						"}");
			return true;
		}
861
862
863
864
865
866
867
868
869
870
		
		// 5.13
		TEST EscapedCharacters()
		{
			std::string input =
				"\"Fun with \\\\\n"
				"\\\" \\a \\b \\e \\f \\\n"
				"\\n \\r \\t \\v \\0 \\\n"
				"\\  \\_ \\N \\L \\P \\\n"
				"\\x41 \\u0041 \\U00000041\"";
871
872

			PARSE(doc, input);
873
			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");
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
			return true;
		}
		
		// 5.14
		TEST InvalidEscapedCharacters()
		{
			std::string input =
				"Bad escapes:\n"
				"  \"\\c\n"
				"  \\xq-\"";
			
			std::stringstream stream(input);
			try {
				YAML::Parser parser(stream);
				YAML::Node doc;
				parser.GetNextDocument(doc);
			} catch(const YAML::ParserException& e) {
891
				YAML_ASSERT(e.msg == std::string(YAML::ErrorMsg::INVALID_ESCAPE) + "c");
892
893
894
895
896
				return true;
			}
			
			return false;
		}
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
		
		// 6.1
		TEST IndentationSpaces()
		{
			std::string input =
				"  # Leading comment line spaces are\n"
				"   # neither content nor indentation.\n"
				"    \n"
				"Not indented:\n"
				" By one space: |\n"
				"    By four\n"
				"      spaces\n"
				" Flow style: [    # Leading spaces\n"
				"   By two,        # in flow style\n"
				"  Also by two,    # are neither\n"
				"  \tStill by two   # content nor\n"
				"    ]             # indentation.";
914
915

			PARSE(doc, input);
916
917
			YAML_ASSERT(doc.size() == 1);
			YAML_ASSERT(doc["Not indented"].size() == 2);
918
			YAML_ASSERT(doc["Not indented"]["By one space"].to<std::string>() == "By four\n  spaces\n");
919
			YAML_ASSERT(doc["Not indented"]["Flow style"].size() == 3);
920
921
922
			YAML_ASSERT(doc["Not indented"]["Flow style"][0].to<std::string>() == "By two");
			YAML_ASSERT(doc["Not indented"]["Flow style"][1].to<std::string>() == "Also by two");
			YAML_ASSERT(doc["Not indented"]["Flow style"][2].to<std::string>() == "Still by two");
923
924
925
926
927
928
929
930
931
932
933
			return true;
		}
		
		// 6.2
		TEST IndentationIndicators()
		{
			std::string input =
				"? a\n"
				": -\tb\n"
				"  -  -\tc\n"
				"     - d";
934
935

			PARSE(doc, input);
936
937
			YAML_ASSERT(doc.size() == 1);
			YAML_ASSERT(doc["a"].size() == 2);
938
			YAML_ASSERT(doc["a"][0].to<std::string>() == "b");
939
			YAML_ASSERT(doc["a"][1].size() == 2);
940
941
			YAML_ASSERT(doc["a"][1][0].to<std::string>() == "c");
			YAML_ASSERT(doc["a"][1][1].to<std::string>() == "d");
942
943
944
945
946
947
948
949
950
951
			return true;
		}
		
		// 6.3
		TEST SeparationSpaces()
		{
			std::string input =
				"- foo:\t bar\n"
				"- - baz\n"
				"  -\tbaz";
952
953

			PARSE(doc, input);
954
955
			YAML_ASSERT(doc.size() == 2);
			YAML_ASSERT(doc[0].size() == 1);
956
			YAML_ASSERT(doc[0]["foo"].to<std::string>() == "bar");
957
			YAML_ASSERT(doc[1].size() == 2);
958
959
			YAML_ASSERT(doc[1][0].to<std::string>() == "baz");
			YAML_ASSERT(doc[1][1].to<std::string>() == "baz");
960
961
962
963
964
965
966
967
968
969
970
971
972
973
			return true;
		}
		
		// 6.4
		TEST LinePrefixes()
		{
			std::string input =
				"plain: text\n"
				"  lines\n"
				"quoted: \"text\n"
				"  \tlines\"\n"
				"block: |\n"
				"  text\n"
				"   \tlines\n";
974
975

			PARSE(doc, input);
976
			YAML_ASSERT(doc.size() == 3);
977
978
979
			YAML_ASSERT(doc["plain"].to<std::string>() == "text lines");
			YAML_ASSERT(doc["quoted"].to<std::string>() == "text lines");
			YAML_ASSERT(doc["block"].to<std::string>() == "text\n \tlines\n");
980
981
982
983
984
985
986
987
988
989
990
991
992
993
			return true;
		}
		
		// 6.5
		TEST EmptyLines()
		{
			std::string input =
				"Folding:\n"
				"  \"Empty line\n"
				"   \t\n"
				"  as a line feed\"\n"
				"Chomping: |\n"
				"  Clipped empty lines\n"
				" ";
994
995

			PARSE(doc, input);
996
			YAML_ASSERT(doc.size() == 2);
997
998
			YAML_ASSERT(doc["Folding"].to<std::string>() == "Empty line\nas a line feed");
			YAML_ASSERT(doc["Chomping"].to<std::string>() == "Clipped empty lines\n");
999
1000
			return true;
		}
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
		
		// 6.6
		TEST LineFolding()
		{
			std::string input =
				">-\n"
				"  trimmed\n"
				"  \n"
				" \n"
				"\n"
				"  as\n"
				"  space";
1013
1014

			PARSE(doc, input);
1015
			YAML_ASSERT(doc.to<std::string>() == "trimmed\n\n\nas space");
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
			return true;
		}
		
		// 6.7
		TEST BlockFolding()
		{
			std::string input =
				">\n"
				"  foo \n"
				" \n"
				"  \t bar\n"
				"\n"
				"  baz\n";
1029
1030

			PARSE(doc, input);
1031
			YAML_ASSERT(doc.to<std::string>() == "foo \n\n\t bar\n\nbaz\n");
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
			return true;
		}
		
		// 6.8
		TEST FlowFolding()
		{
			std::string input =
				"\"\n"
				"  foo \n"
				" \n"
				"  \t bar\n"
				"\n"
				"  baz\n"
				"\"";
1046
1047

			PARSE(doc, input);			
1048
			YAML_ASSERT(doc.to<std::string>() == " foo\nbar\nbaz ");
1049
1050
			return true;
		}
1051
1052
1053
1054
1055
1056
1057
		
		// 6.9
		TEST SeparatedComment()
		{
			std::string input =
				"key:    # Comment\n"
				"  value";
1058
1059

			PARSE(doc, input);
1060
			YAML_ASSERT(doc.size() == 1);
1061
			YAML_ASSERT(doc["key"].to<std::string>() == "value");
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
			return true;
		}
		
		// 6.10
		TEST CommentLines()
		{
			std::string input =
				"  # Comment\n"
				"   \n"
				"\n";
			
Jesse Beder's avatar
Jesse Beder committed
1073
1074
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 0);
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
			return true;
		}
		
		// 6.11
		TEST MultiLineComments()
		{
			std::string input =
				"key:    # Comment\n"
				"        # lines\n"
				"  value\n"
				"\n";
1086
1087

			PARSE(doc, input);
1088
			YAML_ASSERT(doc.size() == 1);
1089
			YAML_ASSERT(doc["key"].to<std::string>() == "value");
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
			return true;
		}

		struct StringMap {
			typedef std::map<std::string, std::string> Map;
			Map _;
		};
		
		bool operator == (const StringMap& m, const StringMap& n) {
			return m._ == n._;
		}
		
		void operator >> (const YAML::Node& node, StringMap& m) {
			m._.clear();
			for(YAML::Iterator it=node.begin();it!=node.end();++it) {
1105
1106
				std::string key = it.first().to<std::string>();
				std::string value = it.second().to<std::string>();
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
				m._[key] = value;
			}
		}

		
		// 6.12
		TEST SeparationSpacesII()
		{
			std::string input =
				"{ first: Sammy, last: Sosa }:\n"
				"# Statistics:\n"
				"  hr:  # Home runs\n"
				"     65\n"
				"  avg: # Average\n"
				"   0.278";
1122
1123

			PARSE(doc, input);
1124
1125
1126
			std::map<std::string, std::string> key;
			key["first"] = "Sammy";
			key["last"] = "Sosa";
1127
1128
			YAML_ASSERT(doc.size() == 1);
			YAML_ASSERT(doc[key].size() == 2);
1129
1130
			YAML_ASSERT(doc[key]["hr"].to<int>() == 65);
			YAML_ASSERT(doc[key]["avg"].to<std::string>() == "0.278");
1131
1132
1133
			return true;
		}
		
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
		// 6.13
		TEST ReservedDirectives()
		{
			std::string input =
				"%FOO  bar baz # Should be ignored\n"
				"               # with a warning.\n"
				"--- \"foo\"";

			PARSE(doc, input);
			return true;
		}
		
		// 6.14
		TEST YAMLDirective()
		{
			std::string input =
				"%YAML 1.3 # Attempt parsing\n"
				"           # with a warning\n"
				"---\n"
				"\"foo\"";

			PARSE(doc, input);
			return true;
		}
		
		// 6.15
		TEST InvalidRepeatedYAMLDirective()
		{
			std::string input =
				"%YAML 1.2\n"
				"%YAML 1.1\n"
				"foo";

			try {
				PARSE(doc, input);
			} catch(const YAML::ParserException& e) {
				if(e.msg == YAML::ErrorMsg::REPEATED_YAML_DIRECTIVE)
					return true;

				throw;
			}
			
			return "  No exception was thrown";
		}
		
		// 6.16
		TEST TagDirective()
		{
			std::string input =
				"%TAG !yaml! tag:yaml.org,2002:\n"
				"---\n"
				"!yaml!str \"foo\"";
			
			PARSE(doc, input);
1188
			YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:str");
1189
			YAML_ASSERT(doc.to<std::string>() == "foo");
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
			return true;
		}
		
		// 6.17
		TEST InvalidRepeatedTagDirective()
		{
			std::string input =
				"%TAG ! !foo\n"
				"%TAG ! !foo\n"
				"bar";

			try {
				PARSE(doc, input);
			} catch(const YAML::ParserException& e) {
				if(e.msg == YAML::ErrorMsg::REPEATED_TAG_DIRECTIVE)
					return true;
				
				throw;
			}
	
			return "  No exception was thrown";
		}

		// 6.18
		TEST PrimaryTagHandle()
		{
			std::string input =
				"# Private\n"
				"!foo \"bar\"\n"
				"...\n"
				"# Global\n"
				"%TAG ! tag:example.com,2000:app/\n"
				"---\n"
				"!foo \"bar\"";

			PARSE(doc, input);
1226
			YAML_ASSERT(doc.Tag() == "!foo");
1227
			YAML_ASSERT(doc.to<std::string>() == "bar");
1228
1229

			PARSE_NEXT(doc);
1230
			YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo");
1231
			YAML_ASSERT(doc.to<std::string>() == "bar");
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
			return true;
		}
		
		// 6.19
		TEST SecondaryTagHandle()
		{
			std::string input =
				"%TAG !! tag:example.com,2000:app/\n"
				"---\n"
				"!!int 1 - 3 # Interval, not integer";
			
			PARSE(doc, input);
1244
			YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/int");
1245
			YAML_ASSERT(doc.to<std::string>() == "1 - 3");
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
			return true;
		}
		
		// 6.20
		TEST TagHandles()
		{
			std::string input =
				"%TAG !e! tag:example.com,2000:app/\n"
				"---\n"
				"!e!foo \"bar\"";
			
			PARSE(doc, input);
1258
			YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo");
1259
			YAML_ASSERT(doc.to<std::string>() == "bar");
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
			return true;
		}
		
		// 6.21
		TEST LocalTagPrefix()
		{
			std::string input =
				"%TAG !m! !my-\n"
				"--- # Bulb here\n"
				"!m!light fluorescent\n"
				"...\n"
				"%TAG !m! !my-\n"
				"--- # Color here\n"
				"!m!light green";
			
			PARSE(doc, input);
1276
			YAML_ASSERT(doc.Tag() == "!my-light");
1277
			YAML_ASSERT(doc.to<std::string>() == "fluorescent");
1278
1279
			
			PARSE_NEXT(doc);
1280
			YAML_ASSERT(doc.Tag() == "!my-light");
1281
			YAML_ASSERT(doc.to<std::string>() == "green");
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
			return true;
		}
		
		// 6.22
		TEST GlobalTagPrefix()
		{
			std::string input =
				"%TAG !e! tag:example.com,2000:app/\n"
				"---\n"
				"- !e!foo \"bar\"";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 1);
1295
			YAML_ASSERT(doc[0].Tag() == "tag:example.com,2000:app/foo");
1296
			YAML_ASSERT(doc[0].to<std::string>() == "bar");
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
			return true;
		}
		
		// 6.23
		TEST NodeProperties()
		{
			std::string input =
				"!!str &a1 \"foo\":\n"
				"  !!str bar\n"
				"&a2 baz : *a1";

			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 2);
			for(YAML::Iterator it=doc.begin();it!=doc.end();++it) {
1311
				if(it.first().to<std::string>() == "foo") {
1312
1313
					YAML_ASSERT(it.first().Tag() == "tag:yaml.org,2002:str");
					YAML_ASSERT(it.second().Tag() == "tag:yaml.org,2002:str");
1314
1315
1316
					YAML_ASSERT(it.second().to<std::string>() == "bar");
				} else if(it.first().to<std::string>() == "baz") {
					YAML_ASSERT(it.second().to<std::string>() == "foo");
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
				} else
					return "  unknown key";
			}
			
			return true;
		}
		
		// 6.24
		TEST VerbatimTags()
		{
			std::string input =
				"!<tag:yaml.org,2002:str> foo :\n"
				"  !<!bar> baz";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 1);
			for(YAML::Iterator it=doc.begin();it!=doc.end();++it) {
1334
				YAML_ASSERT(it.first().Tag() == "tag:yaml.org,2002:str");
1335
				YAML_ASSERT(it.first().to<std::string>() == "foo");
1336
				YAML_ASSERT(it.second().Tag() == "!bar");
1337
				YAML_ASSERT(it.second().to<std::string>() == "baz");
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
			}
			return true;
		}
		
		// 6.25
		TEST InvalidVerbatimTags()
		{
			std::string input =
				"- !<!> foo\n"
				"- !<$:?> bar\n";

			PARSE(doc, input);
			return "  not implemented yet"; // TODO: check tags (but we probably will say these are valid, I think)
		}
		
		// 6.26
		TEST TagShorthands()
		{
			std::string input =
				"%TAG !e! tag:example.com,2000:app/\n"
				"---\n"
				"- !local foo\n"
				"- !!str bar\n"
				"- !e!tag%21 baz\n";

			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 3);
1365
			YAML_ASSERT(doc[0].Tag() == "!local");
1366
			YAML_ASSERT(doc[0].to<std::string>() == "foo");
1367
			YAML_ASSERT(doc[1].Tag() == "tag:yaml.org,2002:str");
1368
			YAML_ASSERT(doc[1].to<std::string>() == "bar");
1369
			YAML_ASSERT(doc[2].Tag() == "tag:example.com,2000:app/tag%21");
1370
			YAML_ASSERT(doc[2].to<std::string>() == "baz");
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
			return true;
		}
		
		// 6.27
		TEST InvalidTagShorthands()
		{
			std::string input1 =
				"%TAG !e! tag:example,2000:app/\n"
				"---\n"
				"- !e! foo";

			bool threw = false;
			try {
				PARSE(doc, input1);
			} catch(const YAML::ParserException& e) {
				threw = true;
				if(e.msg != YAML::ErrorMsg::TAG_WITH_NO_SUFFIX)
					throw;
			}
			
			if(!threw)
				return "  No exception was thrown for a tag with no suffix";

			std::string input2 =
				"%TAG !e! tag:example,2000:app/\n"
				"---\n"
				"- !h!bar baz";

			PARSE(doc, input2); // TODO: should we reject this one (since !h! is not declared)?
			return "  not implemented yet";
		}
		
		// 6.28
		TEST NonSpecificTags()
		{
			std::string input =
				"# Assuming conventional resolution:\n"
				"- \"12\"\n"
				"- 12\n"
				"- ! 12";

			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 3);
1414
1415
1416
			YAML_ASSERT(doc[0].to<std::string>() == "12"); // TODO: check tags. How?
			YAML_ASSERT(doc[1].to<int>() == 12);
			YAML_ASSERT(doc[2].to<std::string>() == "12");
1417
1418
			return true;
		}
1419
1420
1421
1422
1423
1424
1425

		// 6.29
		TEST NodeAnchors()
		{
			std::string input =
				"First occurrence: &anchor Value\n"
				"Second occurrence: *anchor";
1426
1427

			PARSE(doc, input);
1428
			YAML_ASSERT(doc.size() == 2);
1429
1430
			YAML_ASSERT(doc["First occurrence"].to<std::string>() == "Value");
			YAML_ASSERT(doc["Second occurrence"].to<std::string>() == "Value");
1431
1432
			return true;
		}
1433
1434
1435
1436
1437
1438
1439
1440
1441
		
		// 7.1
		TEST AliasNodes()
		{
			std::string input =
				"First occurrence: &anchor Foo\n"
				"Second occurrence: *anchor\n"
				"Override anchor: &anchor Bar\n"
				"Reuse anchor: *anchor";
1442
1443

			PARSE(doc, input);
1444
			YAML_ASSERT(doc.size() == 4);
1445
1446
1447
1448
			YAML_ASSERT(doc["First occurrence"].to<std::string>() == "Foo");
			YAML_ASSERT(doc["Second occurrence"].to<std::string>() == "Foo");
			YAML_ASSERT(doc["Override anchor"].to<std::string>() == "Bar");
			YAML_ASSERT(doc["Reuse anchor"].to<std::string>() == "Bar");
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
			return true;
		}
		
		// 7.2
		TEST EmptyNodes()
		{
			std::string input =
				"{\n"
				"  foo : !!str,\n"
				"  !!str : bar,\n"
				"}";
1460
1461

			PARSE(doc, input);
1462
			YAML_ASSERT(doc.size() == 2);
1463
			for(YAML::Iterator it=doc.begin();it!=doc.end();++it) {
1464
				if(it.first().to<std::string>() == "foo") {
1465
					YAML_ASSERT(it.second().Tag() == "tag:yaml.org,2002:str");
1466
1467
					YAML_ASSERT(it.second().to<std::string>() == "");
				} else if(it.first().to<std::string>() == "") {
1468
					YAML_ASSERT(it.first().Tag() == "tag:yaml.org,2002:str");
1469
					YAML_ASSERT(it.second().to<std::string>() == "bar");
1470
1471
1472
				} else
					return "  unexpected key";
			}
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
			return true;
		}
		
		// 7.3
		TEST CompletelyEmptyNodes()
		{
			std::string input =
				"{\n"
				"  ? foo :,\n"
				"  : bar,\n"
				"}\n";
1484
1485

			PARSE(doc, input);
1486
1487
			YAML_ASSERT(doc.size() == 2);
			YAML_ASSERT(IsNull(doc["foo"]));
1488
			YAML_ASSERT(doc[YAML::Null].to<std::string>() == "bar");
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
			return true;
		}
		
		// 7.4
		TEST DoubleQuotedImplicitKeys()
		{
			std::string input =
				"\"implicit block key\" : [\n"
				"  \"implicit flow key\" : value,\n"
				" ]";
1499
1500
1501
1502
1503

			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 1);
			YAML_ASSERT(doc["implicit block key"].size() == 1);
			YAML_ASSERT(doc["implicit block key"][0].size() == 1);
1504
			YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"].to<std::string>() == "value");
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
			return true;
		}
		
		// 7.5
		TEST DoubleQuotedLineBreaks()
		{
			std::string input =
				"\"folded \n"
				"to a space,\t\n"
				" \n"
				"to a line feed, or \t\\\n"
				" \\ \tnon-content\"";

			PARSE(doc, input);
1519
			YAML_ASSERT(doc.to<std::string>() == "folded to a space,\nto a line feed, or \t \tnon-content");
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
			return true;
		}
		
		// 7.6
		TEST DoubleQuotedLines()
		{
			std::string input =
				"\" 1st non-empty\n"
				"\n"
				" 2nd non-empty \n"
				"\t3rd non-empty \"";

			PARSE(doc, input);
1533
			YAML_ASSERT(doc.to<std::string>() == " 1st non-empty\n2nd non-empty 3rd non-empty ");
1534
1535
1536
1537
1538
1539
1540
1541
1542
			return true;
		}
		
		// 7.7
		TEST SingleQuotedCharacters()
		{
			std::string input = " 'here''s to \"quotes\"'";

			PARSE(doc, input);
1543
			YAML_ASSERT(doc.to<std::string>() == "here's to \"quotes\"");
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
			return true;
		}
		
		// 7.8
		TEST SingleQuotedImplicitKeys()
		{
			std::string input =
				"'implicit block key' : [\n"
				"  'implicit flow key' : value,\n"
				" ]";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 1);
			YAML_ASSERT(doc["implicit block key"].size() == 1);
			YAML_ASSERT(doc["implicit block key"][0].size() == 1);
1559
			YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"].to<std::string>() == "value");
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
			return true;
		}
		
		// 7.9
		TEST SingleQuotedLines()
		{
			std::string input =
				"' 1st non-empty\n"
				"\n"
				" 2nd non-empty \n"
				"\t3rd non-empty '";
			
			PARSE(doc, input);
1573
			YAML_ASSERT(doc.to<std::string>() == " 1st non-empty\n2nd non-empty 3rd non-empty ");
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
			return true;
		}
		
		// 7.10
		TEST PlainCharacters()
		{
			std::string input =
				"# Outside flow collection:\n"
				"- ::vector\n"
				"- \": - ()\"\n"
				"- Up, up, and away!\n"
				"- -123\n"
				"- http://example.com/foo#bar\n"
				"# Inside flow collection:\n"
				"- [ ::vector,\n"
				"  \": - ()\",\n"
				"  \"Up, up, and away!\",\n"
				"  -123,\n"
				"  http://example.com/foo#bar ]";
1593
			
1594
1595
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 6);
1596
1597
1598
1599
1600
			YAML_ASSERT(doc[0].to<std::string>() == "::vector");
			YAML_ASSERT(doc[1].to<std::string>() == ": - ()");
			YAML_ASSERT(doc[2].to<std::string>() == "Up, up, and away!");
			YAML_ASSERT(doc[3].to<int>() == -123);
			YAML_ASSERT(doc[4].to<std::string>() == "http://example.com/foo#bar");
1601
			YAML_ASSERT(doc[5].size() == 5);
1602
1603
1604
1605
1606
			YAML_ASSERT(doc[5][0].to<std::string>() == "::vector");
			YAML_ASSERT(doc[5][1].to<std::string>() == ": - ()");
			YAML_ASSERT(doc[5][2].to<std::string>() == "Up, up, and away!");
			YAML_ASSERT(doc[5][3].to<int>() == -123);
			YAML_ASSERT(doc[5][4].to<std::string>() == "http://example.com/foo#bar");
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
			return true;
		}
		
		// 7.11
		TEST PlainImplicitKeys()
		{
			std::string input =
				"implicit block key : [\n"
				"  implicit flow key : value,\n"
				" ]";

			PARSE(doc, input);
1619
1620
1621
			YAML_ASSERT(doc.size() == 1);
			YAML_ASSERT(doc["implicit block key"].size() == 1);
			YAML_ASSERT(doc["implicit block key"][0].size() == 1);
1622
			YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"].to<std::string>() == "value");
1623
1624
			return true;
		}
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
		
		// 7.12
		TEST PlainLines()
		{
			std::string input =
				"1st non-empty\n"
				"\n"
				" 2nd non-empty \n"
				"\t3rd non-empty";
			
			PARSE(doc, input);
1636
			YAML_ASSERT(doc.to<std::string>() == "1st non-empty\n2nd non-empty 3rd non-empty");
1637
1638
			return true;
		}
Jesse Beder's avatar
Jesse Beder committed
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
		
		// 7.13
		TEST FlowSequence()
		{
			std::string input =
				"- [ one, two, ]\n"
				"- [three ,four]";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 2);
			YAML_ASSERT(doc[0].size() == 2);
1650
1651
			YAML_ASSERT(doc[0][0].to<std::string>() == "one");
			YAML_ASSERT(doc[0][1].to<std::string>() == "two");
Jesse Beder's avatar
Jesse Beder committed
1652
			YAML_ASSERT(doc[1].size() == 2);
1653
1654
			YAML_ASSERT(doc[1][0].to<std::string>() == "three");
			YAML_ASSERT(doc[1][1].to<std::string>() == "four");
Jesse Beder's avatar
Jesse Beder committed
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
			return true;
		}
		
		// 7.14
		TEST FlowSequenceEntries()
		{
			std::string input =
				"[\n"
				"\"double\n"
				" quoted\", 'single\n"
				"           quoted',\n"
				"plain\n"
				" text, [ nested ],\n"
				"single: pair,\n"
				"]";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 5);
1673
1674
1675
			YAML_ASSERT(doc[0].to<std::string>() == "double quoted");
			YAML_ASSERT(doc[1].to<std::string>() == "single quoted");
			YAML_ASSERT(doc[2].to<std::string>() == "plain text");
Jesse Beder's avatar
Jesse Beder committed
1676
			YAML_ASSERT(doc[3].size() == 1);
1677
			YAML_ASSERT(doc[3][0].to<std::string>() == "nested");
Jesse Beder's avatar
Jesse Beder committed
1678
			YAML_ASSERT(doc[4].size() == 1);
1679
			YAML_ASSERT(doc[4]["single"].to<std::string>() == "pair");
Jesse Beder's avatar
Jesse Beder committed
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
			return true;
		}
		
		// 7.15
		TEST FlowMappings()
		{
			std::string input =
				"- { one : two , three: four , }\n"
				"- {five: six,seven : eight}";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 2);
			YAML_ASSERT(doc[0].size() == 2);
1693
1694
			YAML_ASSERT(doc[0]["one"].to<std::string>() == "two");
			YAML_ASSERT(doc[0]["three"].to<std::string>() == "four");
Jesse Beder's avatar
Jesse Beder committed
1695
			YAML_ASSERT(doc[1].size() == 2);
1696
1697
			YAML_ASSERT(doc[1]["five"].to<std::string>() == "six");
			YAML_ASSERT(doc[1]["seven"].to<std::string>() == "eight");
Jesse Beder's avatar
Jesse Beder committed
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
			return true;
		}
		
		// 7.16
		TEST FlowMappingEntries()
		{
			std::string input =
				"{\n"
				"? explicit: entry,\n"
				"implicit: entry,\n"
				"?\n"
				"}";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 3);
1713
1714
			YAML_ASSERT(doc["explicit"].to<std::string>() == "entry");
			YAML_ASSERT(doc["implicit"].to<std::string>() == "entry");
Jesse Beder's avatar
Jesse Beder committed
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
			YAML_ASSERT(IsNull(doc[YAML::Null]));
			return true;
		}
		
		// 7.17
		TEST FlowMappingSeparateValues()
		{
			std::string input =
				"{\n"
				"unquoted : \"separate\",\n"
				"http://foo.com,\n"
				"omitted value:,\n"
				": omitted key,\n"
				"}";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 4);
1732
			YAML_ASSERT(doc["unquoted"].to<std::string>() == "separate");
Jesse Beder's avatar
Jesse Beder committed
1733
1734
			YAML_ASSERT(IsNull(doc["http://foo.com"]));
			YAML_ASSERT(IsNull(doc["omitted value"]));
1735
			YAML_ASSERT(doc[YAML::Null].to<std::string>() == "omitted key");
Jesse Beder's avatar
Jesse Beder committed
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
			return true;
		}
		
		// 7.18
		TEST FlowMappingAdjacentValues()
		{
			std::string input =
				"{\n"
				"\"adjacent\":value,\n"
				"\"readable\":value,\n"
				"\"empty\":\n"
				"}";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 3);
1751
1752
			YAML_ASSERT(doc["adjacent"].to<std::string>() == "value");
			YAML_ASSERT(doc["readable"].to<std::string>() == "value");
Jesse Beder's avatar
Jesse Beder committed
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
			YAML_ASSERT(IsNull(doc["empty"]));
			return true;
		}
		
		// 7.19
		TEST SinglePairFlowMappings()
		{
			std::string input =
				"[\n"
				"foo: bar\n"
				"]";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 1);
			YAML_ASSERT(doc[0].size() == 1);
1768
			YAML_ASSERT(doc[0]["foo"].to<std::string>() == "bar");
Jesse Beder's avatar
Jesse Beder committed
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
			return true;
		}
		
		// 7.20
		TEST SinglePairExplicitEntry()
		{
			std::string input =
				"[\n"
				"? foo\n"
				" bar : baz\n"
				"]";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 1);
			YAML_ASSERT(doc[0].size() == 1);
1784
			YAML_ASSERT(doc[0]["foo bar"].to<std::string>() == "baz");
Jesse Beder's avatar
Jesse Beder committed
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
			return true;
		}
		
		// 7.21
		TEST SinglePairImplicitEntries()
		{
			std::string input =
				"- [ YAML : separate ]\n"
				"- [ : empty key entry ]\n"
				"- [ {JSON: like}:adjacent ]";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 3);
			YAML_ASSERT(doc[0].size() == 1);
			YAML_ASSERT(doc[0][0].size() == 1);
1800
			YAML_ASSERT(doc[0][0]["YAML"].to<std::string>() == "separate");
Jesse Beder's avatar
Jesse Beder committed
1801
1802
			YAML_ASSERT(doc[1].size() == 1);
			YAML_ASSERT(doc[1][0].size() == 1);
1803
			YAML_ASSERT(doc[1][0][YAML::Null].to<std::string>() == "empty key entry");
Jesse Beder's avatar
Jesse Beder committed
1804
1805
1806
1807
			YAML_ASSERT(doc[2].size() == 1);
			YAML_ASSERT(doc[2][0].size() == 1);
			StringMap key;
			key._["JSON"] = "like";
1808
			YAML_ASSERT(doc[2][0][key].to<std::string>() == "adjacent");
Jesse Beder's avatar
Jesse Beder committed
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
			return true;
		}
		
		// 7.22
		TEST InvalidImplicitKeys()
		{
			std::string input =
				"[ foo\n"
				" bar: invalid,"; // Note: we don't check (on purpose) the >1K chars for an implicit key
			
			try {
				PARSE(doc, input);
			} catch(const YAML::Exception& e) {
Jesse Beder's avatar
Jesse Beder committed
1822
				if(e.msg == YAML::ErrorMsg::END_OF_SEQ_FLOW)
Jesse Beder's avatar
Jesse Beder committed
1823
1824
1825
1826
1827
1828
					return true;
				
				throw;
			}
			return "  no exception thrown";
		}
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
		
		// 7.23
		TEST FlowContent()
		{
			std::string input =
				"- [ a, b ]\n"
				"- { a: b }\n"
				"- \"a\"\n"
				"- 'b'\n"
				"- c";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 5);
			YAML_ASSERT(doc[0].size() == 2);
1843
1844
			YAML_ASSERT(doc[0][0].to<std::string>() == "a");
			YAML_ASSERT(doc[0][1].to<std::string>() == "b");
1845
			YAML_ASSERT(doc[1].size() == 1);
1846
1847
1848
1849
			YAML_ASSERT(doc[1]["a"].to<std::string>() == "b");
			YAML_ASSERT(doc[2].to<std::string>() == "a");
			YAML_ASSERT(doc[3].to<char>() == 'b');
			YAML_ASSERT(doc[4].to<std::string>() == "c");
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
			return true;
		}
		
		// 7.24
		TEST FlowNodes()
		{
			std::string input =
				"- !!str \"a\"\n"
				"- 'b'\n"
				"- &anchor \"c\"\n"
				"- *anchor\n"
				"- !!str";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 5);
1865
			YAML_ASSERT(doc[0].Tag() == "tag:yaml.org,2002:str");
1866
1867
1868
1869
			YAML_ASSERT(doc[0].to<std::string>() == "a");
			YAML_ASSERT(doc[1].to<char>() == 'b');
			YAML_ASSERT(doc[2].to<std::string>() == "c");
			YAML_ASSERT(doc[3].to<std::string>() == "c");
1870
			YAML_ASSERT(doc[4].Tag() == "tag:yaml.org,2002:str");
1871
			YAML_ASSERT(doc[4].to<std::string>() == "");
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
			return true;
		}
		
		// 8.1
		TEST BlockScalarHeader()
		{
			std::string input =
				"- | # Empty header\n"
				" literal\n"
				"- >1 # Indentation indicator\n"
				"  folded\n"
				"- |+ # Chomping indicator\n"
				" keep\n"
				"\n"
				"- >1- # Both indicators\n"
				"  strip\n";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 4);
1891
1892
1893
1894
			YAML_ASSERT(doc[0].to<std::string>() == "literal\n");
			YAML_ASSERT(doc[1].to<std::string>() == " folded\n");
			YAML_ASSERT(doc[2].to<std::string>() == "keep\n\n");
			YAML_ASSERT(doc[3].to<std::string>() == " strip");
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
			return true;
		}
		
		// 8.2
		TEST BlockIndentationHeader()
		{
			std::string input =
				"- |\n"
				" detected\n"
				"- >\n"
				" \n"
				"  \n"
				"  # detected\n"
				"- |1\n"
				"  explicit\n"
				"- >\n"
				" \t\n"
				" detected\n";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 4);
1916
1917
1918
1919
			YAML_ASSERT(doc[0].to<std::string>() == "detected\n");
			YAML_ASSERT(doc[1].to<std::string>() == "\n\n# detected\n");
			YAML_ASSERT(doc[2].to<std::string>() == " explicit\n");
			YAML_ASSERT(doc[3].to<std::string>() == "\t\ndetected\n");
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
			return true;
		}
		
		// 8.3
		TEST InvalidBlockScalarIndentationIndicators()
		{
			{
				std::string input =
					"- |\n"
					"  \n"
					" text";
			
				bool threw = false;
				try {
					PARSE(doc, input);
				} catch(const YAML::Exception& e) {
					if(e.msg != YAML::ErrorMsg::END_OF_SEQ)
						throw;
					
					threw = true;
				}
				
				if(!threw)
					return "  no exception thrown for less indented auto-detecting indentation for a literal block scalar";
			}
			
			{
				std::string input =
					"- >\n"
					"  text\n"
					" text";
			
				bool threw = false;
				try {
					PARSE(doc, input);
				} catch(const YAML::Exception& e) {
					if(e.msg != YAML::ErrorMsg::END_OF_SEQ)
						throw;
					
					threw = true;
				}
				
				if(!threw)
					return "  no exception thrown for less indented auto-detecting indentation for a folded block scalar";
			}
			
			{
				std::string input =
					"- |2\n"
					" text";
			
				bool threw = false;
				try {
					PARSE(doc, input);
				} catch(const YAML::Exception& e) {
					if(e.msg != YAML::ErrorMsg::END_OF_SEQ)
						throw;
					
					threw = true;
				}
				
				if(!threw)
					return "  no exception thrown for less indented explicit indentation for a literal block scalar";
			}
			
			return true;
		}
		
		// 8.4
		TEST ChompingFinalLineBreak()
		{
			std::string input =
				"strip: |-\n"
				"  text\n"
				"clip: |\n"
				"  text\n"
				"keep: |+\n"
				"  text\n";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 3);
2001
2002
2003
			YAML_ASSERT(doc["strip"].to<std::string>() == "text");
			YAML_ASSERT(doc["clip"].to<std::string>() == "text\n");
			YAML_ASSERT(doc["keep"].to<std::string>() == "text\n");
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
			return true;
		}
		
		// 8.5
		TEST ChompingTrailingLines()
		{
			std::string input =
				" # Strip\n"
				"  # Comments:\n"
				"strip: |-\n"
				"  # text\n"
				"  \n"
				" # Clip\n"
				"  # comments:\n"
				"\n"
				"clip: |\n"
				"  # text\n"
				" \n"
				" # Keep\n"
				"  # comments:\n"
				"\n"
				"keep: |+\n"
				"  # text\n"
				"\n"
				" # Trail\n"
				"  # Comments\n";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 3);
2033
2034
2035
			YAML_ASSERT(doc["strip"].to<std::string>() == "# text");
			YAML_ASSERT(doc["clip"].to<std::string>() == "# text\n");
			YAML_ASSERT(doc["keep"].to<std::string>() == "# text\n");
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
			return true;
		}
		
		// 8.6
		TEST EmptyScalarChomping()
		{
			std::string input =
				"strip: >-\n"
				"\n"
				"clip: >\n"
				"\n"
				"keep: |+\n"
				"\n";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 3);
2052
2053
2054
			YAML_ASSERT(doc["strip"].to<std::string>() == "");
			YAML_ASSERT(doc["clip"].to<std::string>() == "");
			YAML_ASSERT(doc["keep"].to<std::string>() == "\n");
2055
2056
			return true;
		}
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
		
		// 8.7
		TEST LiteralScalar()
		{
			std::string input =
				"|\n"
				" literal\n"
				" \ttext\n"
				"\n";
			
			PARSE(doc, input);
2068
			YAML_ASSERT(doc.to<std::string>() == "literal\n\ttext\n");
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
			return true;
		}
		
		// 8.8
		TEST LiteralContent()
		{
			std::string input =
				"|\n"
				" \n"
				"  \n"
				"  literal\n"
				"   \n"
				"  \n"
				"  text\n"
				"\n"
				" # Comment\n";
			
			PARSE(doc, input);
2087
			YAML_ASSERT(doc.to<std::string>() == "\n\nliteral\n \n\ntext\n");
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
			return true;
		}
		
		// 8.9
		TEST FoldedScalar()
		{
			std::string input =
				">\n"
				" folded\n"
				" text\n"
				"\n";
			
			PARSE(doc, input);
2101
			YAML_ASSERT(doc.to<std::string>() == "folded text\n");
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
			return true;
		}
		
		// 8.10
		TEST FoldedLines()
		{
			std::string input =
				">\n"
				"\n"
				" folded\n"
				" line\n"
				"\n"
				" next\n"
				" line\n"
				"   * bullet\n"
				"\n"
				"   * list\n"
				"   * lines\n"
				"\n"
				" last\n"
				" line\n"
				"\n"
				"# Comment\n";
			
			PARSE(doc, input);
2127
			YAML_ASSERT(doc.to<std::string>() == "\nfolded line\nnext line\n  * bullet\n\n  * list\n  * lines\n\nlast line\n");
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
			return true;
		}
		
		// 8.11
		TEST MoreIndentedLines()
		{
			return true; // same as 8.10
		}
		
		// 8.12
		TEST EmptySeparationLines()
		{
			return true; // same as 8.10
		}
		
		// 8.13
		TEST FinalEmptyLines()
		{
			return true; // same as 8.10
		}
		
		// 8.14
		TEST BlockSequence()
		{
			std::string input =
				"block sequence:\n"
				"  - one\n"
				"  - two : three\n";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 1);
			YAML_ASSERT(doc["block sequence"].size() == 2);
2160
			YAML_ASSERT(doc["block sequence"][0].to<std::string>() == "one");
2161
			YAML_ASSERT(doc["block sequence"][1].size() == 1);
2162
			YAML_ASSERT(doc["block sequence"][1]["two"].to<std::string>() == "three");
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
			return true;
		}
		
		// 8.15
		TEST BlockSequenceEntryTypes()
		{
			std::string input =
				"- # Empty\n"
				"- |\n"
				" block node\n"
				"- - one # Compact\n"
				"  - two # sequence\n"
				"- one: two # Compact mapping\n";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 4);
			YAML_ASSERT(YAML::IsNull(doc[0]));
2180
			YAML_ASSERT(doc[1].to<std::string>() == "block node\n");
2181
			YAML_ASSERT(doc[2].size() == 2);
2182
2183
			YAML_ASSERT(doc[2][0].to<std::string>() == "one");
			YAML_ASSERT(doc[2][1].to<std::string>() == "two");
2184
			YAML_ASSERT(doc[3].size() == 1);
2185
			YAML_ASSERT(doc[3]["one"].to<std::string>() == "two");
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
			return true;
		}
		
		// 8.16
		TEST BlockMappings()
		{
			std::string input =
				"block mapping:\n"
				" key: value\n";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 1);
			YAML_ASSERT(doc["block mapping"].size() == 1);
2199
			YAML_ASSERT(doc["block mapping"]["key"].to<std::string>() == "value");
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
			return true;
		}
		
		// 8.17
		TEST ExplicitBlockMappingEntries()
		{
			std::string input =
				"? explicit key # Empty value\n"
				"? |\n"
				"  block key\n"
				": - one # Explicit compact\n"
				"  - two # block value\n";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 2);
			YAML_ASSERT(IsNull(doc["explicit key"]));
			YAML_ASSERT(doc["block key\n"].size() == 2);
2217
2218
			YAML_ASSERT(doc["block key\n"][0].to<std::string>() == "one");
			YAML_ASSERT(doc["block key\n"][1].to<std::string>() == "two");
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
			return true;
		}
		
		// 8.18
		TEST ImplicitBlockMappingEntries()
		{
			std::string input =
				"plain key: in-line value\n"
				":  # Both empty\n"
				"\"quoted key\":\n"
				"- entry\n";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 3);
2233
			YAML_ASSERT(doc["plain key"].to<std::string>() == "in-line value");
2234
2235
			YAML_ASSERT(IsNull(doc[YAML::Null]));
			YAML_ASSERT(doc["quoted key"].size() == 1);
2236
			YAML_ASSERT(doc["quoted key"][0].to<std::string>() == "entry");
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
			return true;
		}
		
		// 8.19
		TEST CompactBlockMappings()
		{
			std::string input =
				"- sun: yellow\n"
				"- ? earth: blue\n"
				"  : moon: white\n";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 2);
			YAML_ASSERT(doc[0].size() == 1);
2251
			YAML_ASSERT(doc[0]["sun"].to<std::string>() == "yellow");
2252
2253
2254
2255
			YAML_ASSERT(doc[1].size() == 1);
			std::map<std::string, std::string> key;
			key["earth"] = "blue";
			YAML_ASSERT(doc[1][key].size() == 1);
2256
			YAML_ASSERT(doc[1][key]["moon"].to<std::string>() == "white");
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
			return true;
		}
		
		// 8.20
		TEST BlockNodeTypes()
		{
			std::string input =
				"-\n"
				"  \"flow in block\"\n"
				"- >\n"
				" Block scalar\n"
				"- !!map # Block collection\n"
				"  foo : bar\n";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 3);
2273
2274
			YAML_ASSERT(doc[0].to<std::string>() == "flow in block");
			YAML_ASSERT(doc[1].to<std::string>() == "Block scalar\n");
2275
			YAML_ASSERT(doc[2].size() == 1);
2276
			YAML_ASSERT(doc[2]["foo"].to<std::string>() == "bar");
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
			return true;
		}
		
		// 8.21
		TEST BlockScalarNodes()
		{
			std::string input =
				"literal: |2\n"
				"  value\n"
				"folded:\n"
				"   !foo\n"
				"  >1\n"
				" value\n";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 2);
2293
2294
			YAML_ASSERT(doc["literal"].to<std::string>() == "value");
			YAML_ASSERT(doc["folded"].to<std::string>() == "value");
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
			YAML_ASSERT(doc["folded"].Tag() == "!foo");
			return true;
		}
		
		// 8.22
		TEST BlockCollectionNodes()
		{
			std::string input =
				"sequence: !!seq\n"
				"- entry\n"
				"- !!seq\n"
				" - nested\n"
				"mapping: !!map\n"
				" foo: bar\n";
			
			PARSE(doc, input);
			YAML_ASSERT(doc.size() == 2);
			YAML_ASSERT(doc["sequence"].size() == 2);
2313
			YAML_ASSERT(doc["sequence"][0].to<std::string>() == "entry");
2314
			YAML_ASSERT(doc["sequence"][1].size() == 1);
2315
			YAML_ASSERT(doc["sequence"][1][0].to<std::string>() == "nested");
2316
			YAML_ASSERT(doc["mapping"].size() == 1);
2317
			YAML_ASSERT(doc["mapping"]["foo"].to<std::string>() == "bar");
2318
2319
			return true;
		}
Jesse Beder's avatar
Jesse Beder committed
2320
2321
2322
2323
	}

	bool RunSpecTests()
	{
Jesse Beder's avatar
Jesse Beder committed
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
		int passed = 0;
		int total = 0;
		RunSpecTest(&Spec::SeqScalars, "2.1", "Sequence of Scalars", passed, total);
		RunSpecTest(&Spec::MappingScalarsToScalars, "2.2", "Mapping Scalars to Scalars", passed, total);
		RunSpecTest(&Spec::MappingScalarsToSequences, "2.3", "Mapping Scalars to Sequences", passed, total);
		RunSpecTest(&Spec::SequenceOfMappings, "2.4", "Sequence of Mappings", passed, total);
		RunSpecTest(&Spec::SequenceOfSequences, "2.5", "Sequence of Sequences", passed, total);
		RunSpecTest(&Spec::MappingOfMappings, "2.6", "Mapping of Mappings", passed, total);
		RunSpecTest(&Spec::TwoDocumentsInAStream, "2.7", "Two Documents in a Stream", passed, total);
		RunSpecTest(&Spec::PlayByPlayFeed, "2.8", "Play by Play Feed from a Game", passed, total);
		RunSpecTest(&Spec::SingleDocumentWithTwoComments, "2.9", "Single Document with Two Comments", passed, total);
		RunSpecTest(&Spec::SimpleAnchor, "2.10", "Node for \"Sammy Sosa\" appears twice in this document", passed, total);
		RunSpecTest(&Spec::MappingBetweenSequences, "2.11", "Mapping between Sequences", passed, total);
		RunSpecTest(&Spec::CompactNestedMapping, "2.12", "Compact Nested Mapping", passed, total);
		RunSpecTest(&Spec::InLiteralsNewlinesArePreserved, "2.13", "In literals, newlines are preserved", passed, total);
		RunSpecTest(&Spec::InFoldedScalarsNewlinesBecomeSpaces, "2.14", "In folded scalars, newlines become spaces", passed, total);
		RunSpecTest(&Spec::FoldedNewlinesArePreservedForMoreIndentedAndBlankLines, "2.15", "Folded newlines are preserved for \"more indented\" and blank lines", passed, total);
		RunSpecTest(&Spec::IndentationDeterminesScope, "2.16", "Indentation determines scope", passed, total);
		RunSpecTest(&Spec::QuotedScalars, "2.17", "Quoted scalars", passed, total);
		RunSpecTest(&Spec::MultiLineFlowScalars, "2.18", "Multi-line flow scalars", passed, total);
		
2345
2346
2347
2348
		RunSpecTest(&Spec::VariousExplicitTags, "2.23", "Various Explicit Tags", passed, total);
		RunSpecTest(&Spec::GlobalTags, "2.24", "Global Tags", passed, total);
		RunSpecTest(&Spec::UnorderedSets, "2.25", "Unordered Sets", passed, total);
		RunSpecTest(&Spec::OrderedMappings, "2.26", "Ordered Mappings", passed, total);
Jesse Beder's avatar
Jesse Beder committed
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
		RunSpecTest(&Spec::Invoice, "2.27", "Invoice", passed, total);
		RunSpecTest(&Spec::LogFile, "2.28", "Log File", passed, total);
		
		RunSpecTest(&Spec::BlockStructureIndicators, "5.3", "Block Structure Indicators", passed, total);
		RunSpecTest(&Spec::FlowStructureIndicators, "5.4", "Flow Structure Indicators", passed, total);
		RunSpecTest(&Spec::NodePropertyIndicators, "5.6", "Node Property Indicators", passed, total);
		RunSpecTest(&Spec::BlockScalarIndicators, "5.7", "Block Scalar Indicators", passed, total);
		RunSpecTest(&Spec::QuotedScalarIndicators, "5.8", "Quoted Scalar Indicators", passed, total);
		RunSpecTest(&Spec::LineBreakCharacters, "5.11", "Line Break Characters", passed, total);
		RunSpecTest(&Spec::TabsAndSpaces, "5.12", "Tabs and Spaces", passed, total);
		RunSpecTest(&Spec::EscapedCharacters, "5.13", "Escaped Characters", passed, total);
		RunSpecTest(&Spec::InvalidEscapedCharacters, "5.14", "Invalid Escaped Characters", passed, total);
		
		RunSpecTest(&Spec::IndentationSpaces, "6.1", "Indentation Spaces", passed, total);
		RunSpecTest(&Spec::IndentationIndicators, "6.2", "Indentation Indicators", passed, total);
		RunSpecTest(&Spec::SeparationSpaces, "6.3", "Separation Spaces", passed, total);
		RunSpecTest(&Spec::LinePrefixes, "6.4", "Line Prefixes", passed, total);
		RunSpecTest(&Spec::EmptyLines, "6.5", "Empty Lines", passed, total);
2367
2368
2369
		RunSpecTest(&Spec::LineFolding, "6.6", "Line Folding", passed, total);
		RunSpecTest(&Spec::BlockFolding, "6.7", "Block Folding", passed, total);
		RunSpecTest(&Spec::FlowFolding, "6.8", "Flow Folding", passed, total);
2370
2371
		RunSpecTest(&Spec::SeparatedComment, "6.9", "Separated Comment", passed, total);
		RunSpecTest(&Spec::CommentLines, "6.10", "Comment Lines", passed, total);
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
		RunSpecTest(&Spec::MultiLineComments, "6.11", "Multi-Line Comments", passed, total);
		RunSpecTest(&Spec::SeparationSpacesII, "6.12", "Separation Spaces", passed, total);
		RunSpecTest(&Spec::ReservedDirectives, "6.13", "Reserved Directives", passed, total);
		RunSpecTest(&Spec::YAMLDirective, "6.14", "YAML Directive", passed, total);
		RunSpecTest(&Spec::InvalidRepeatedYAMLDirective, "6.15", "Invalid Repeated YAML Directive", passed, total);
		RunSpecTest(&Spec::TagDirective, "6.16", "Tag Directive", passed, total);
		RunSpecTest(&Spec::InvalidRepeatedTagDirective, "6.17", "Invalid Repeated Tag Directive", passed, total);
		RunSpecTest(&Spec::PrimaryTagHandle, "6.18", "Primary Tag Handle", passed, total);
		RunSpecTest(&Spec::SecondaryTagHandle, "6.19", "SecondaryTagHandle", passed, total);
		RunSpecTest(&Spec::TagHandles, "6.20", "TagHandles", passed, total);
		RunSpecTest(&Spec::LocalTagPrefix, "6.21", "LocalTagPrefix", passed, total);
		RunSpecTest(&Spec::GlobalTagPrefix, "6.22", "GlobalTagPrefix", passed, total);
		RunSpecTest(&Spec::NodeProperties, "6.23", "NodeProperties", passed, total);
		RunSpecTest(&Spec::VerbatimTags, "6.24", "Verbatim Tags", passed, total);
		RunSpecTest(&Spec::InvalidVerbatimTags, "6.25", "Invalid Verbatim Tags", passed, total);
		RunSpecTest(&Spec::TagShorthands, "6.26", "Tag Shorthands", passed, total);
		RunSpecTest(&Spec::InvalidTagShorthands, "6.27", "Invalid Tag Shorthands", passed, total);
		RunSpecTest(&Spec::NonSpecificTags, "6.28", "Non Specific Tags", passed, total);
2390
		RunSpecTest(&Spec::NodeAnchors, "6.29", "Node Anchors", passed, total);
2391
2392
2393
2394
2395
		
		RunSpecTest(&Spec::AliasNodes, "7.1", "Alias Nodes", passed, total);
		RunSpecTest(&Spec::EmptyNodes, "7.2", "Empty Nodes", passed, total);
		RunSpecTest(&Spec::CompletelyEmptyNodes, "7.3", "Completely Empty Nodes", passed, total);
		RunSpecTest(&Spec::DoubleQuotedImplicitKeys, "7.4", "Double Quoted Implicit Keys", passed, total);
2396
2397
2398
2399
2400
2401
2402
2403
		RunSpecTest(&Spec::DoubleQuotedLineBreaks, "7.5", "Double Quoted Line Breaks", passed, total);
		RunSpecTest(&Spec::DoubleQuotedLines, "7.6", "Double Quoted Lines", passed, total);
		RunSpecTest(&Spec::SingleQuotedCharacters, "7.7", "Single Quoted Characters", passed, total);
		RunSpecTest(&Spec::SingleQuotedImplicitKeys, "7.8", "Single Quoted Implicit Keys", passed, total);
		RunSpecTest(&Spec::SingleQuotedLines, "7.9", "Single Quoted Lines", passed, total);
		RunSpecTest(&Spec::PlainCharacters, "7.10", "Plain Characters", passed, total);
		RunSpecTest(&Spec::PlainImplicitKeys, "7.11", "Plain Implicit Keys", passed, total);
		RunSpecTest(&Spec::PlainLines, "7.12", "Plain Lines", passed, total);
Jesse Beder's avatar
Jesse Beder committed
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
		RunSpecTest(&Spec::FlowSequence, "7.13", "Flow Sequence", passed, total);
		RunSpecTest(&Spec::FlowSequenceEntries, "7.14", "Flow Sequence Entries", passed, total);
		RunSpecTest(&Spec::FlowMappings, "7.15", "Flow Mappings", passed, total);
		RunSpecTest(&Spec::FlowMappingEntries, "7.16", "Flow Mapping Entries", passed, total);
		RunSpecTest(&Spec::FlowMappingSeparateValues, "7.17", "Flow Mapping Separate Values", passed, total);
		RunSpecTest(&Spec::FlowMappingAdjacentValues, "7.18", "Flow Mapping Adjacent Values", passed, total);
		RunSpecTest(&Spec::SinglePairFlowMappings, "7.19", "Single Pair Flow Mappings", passed, total);
		RunSpecTest(&Spec::SinglePairExplicitEntry, "7.20", "Single Pair Explicit Entry", passed, total);
		RunSpecTest(&Spec::SinglePairImplicitEntries, "7.21", "Single Pair Implicit Entries", passed, total);
		RunSpecTest(&Spec::InvalidImplicitKeys, "7.22", "Invalid Implicit Keys", passed, total);
2414
2415
2416
2417
2418
2419
2420
		RunSpecTest(&Spec::FlowContent, "7.23", "Flow Content", passed, total);
		RunSpecTest(&Spec::FlowNodes, "7.24", "FlowNodes", passed, total);
		
		RunSpecTest(&Spec::BlockScalarHeader, "8.1", "Block Scalar Header", passed, total);
		RunSpecTest(&Spec::BlockIndentationHeader, "8.2", "Block Indentation Header", passed, total);
		RunSpecTest(&Spec::InvalidBlockScalarIndentationIndicators, "8.3", "Invalid Block Scalar Indentation Indicators", passed, total);
		RunSpecTest(&Spec::ChompingFinalLineBreak, "8.4", "Chomping Final Line Break", passed, total);
2421
2422
		RunSpecTest(&Spec::ChompingTrailingLines, "8.5", "Chomping Trailing Lines", passed, total);
		RunSpecTest(&Spec::EmptyScalarChomping, "8.6", "Empty Scalar Chomping", passed, total);
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
		RunSpecTest(&Spec::LiteralScalar, "8.7", "Literal Scalar", passed, total);
		RunSpecTest(&Spec::LiteralContent, "8.8", "Literal Content", passed, total);
		RunSpecTest(&Spec::FoldedScalar, "8.9", "Folded Scalar", passed, total);
		RunSpecTest(&Spec::FoldedLines, "8.10", "Folded Lines", passed, total);
		RunSpecTest(&Spec::MoreIndentedLines, "8.11", "More Indented Lines", passed, total);
		RunSpecTest(&Spec::EmptySeparationLines, "8.12", "Empty Separation Lines", passed, total);
		RunSpecTest(&Spec::FinalEmptyLines, "8.13", "Final Empty Lines", passed, total);
		RunSpecTest(&Spec::BlockSequence, "8.14", "Block Sequence", passed, total);
		RunSpecTest(&Spec::BlockSequenceEntryTypes, "8.15", "Block Sequence Entry Types", passed, total);
		RunSpecTest(&Spec::BlockMappings, "8.16", "Block Mappings", passed, total);
		RunSpecTest(&Spec::ExplicitBlockMappingEntries, "8.17", "Explicit Block Mapping Entries", passed, total);
		RunSpecTest(&Spec::ImplicitBlockMappingEntries, "8.18", "Implicit Block Mapping Entries", passed, total);
		RunSpecTest(&Spec::CompactBlockMappings, "8.19", "Compact Block Mappings", passed, total);
		RunSpecTest(&Spec::BlockNodeTypes, "8.20", "Block Node Types", passed, total);
		RunSpecTest(&Spec::BlockScalarNodes, "8.21", "Block Scalar Nodes", passed, total);
		RunSpecTest(&Spec::BlockCollectionNodes, "8.22", "Block Collection Nodes", passed, total);
Jesse Beder's avatar
Jesse Beder committed
2439
2440
2441

		std::cout << "Spec tests: " << passed << "/" << total << " passed\n";
		return passed == total;
Jesse Beder's avatar
Jesse Beder committed
2442
2443
2444
2445
	}
	
}