#include "spectests.h" #include "specexamples.h" #include "yaml-cpp/yaml.h" #include #include #include #include #define YAML_ASSERT(cond) do { if(!(cond)) return " Assert failed: " #cond; } while(false) #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) namespace Test { namespace Spec { // 2.1 TEST SeqScalars() { PARSE(doc, ex2_1); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc[0].to() == "Mark McGwire"); YAML_ASSERT(doc[1].to() == "Sammy Sosa"); YAML_ASSERT(doc[2].to() == "Ken Griffey"); return true; } // 2.2 TEST MappingScalarsToScalars() { PARSE(doc, ex2_2); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc["hr"].to() == "65"); YAML_ASSERT(doc["avg"].to() == "0.278"); YAML_ASSERT(doc["rbi"].to() == "147"); return true; } // 2.3 TEST MappingScalarsToSequences() { PARSE(doc, ex2_3); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["american"].size() == 3); YAML_ASSERT(doc["american"][0].to() == "Boston Red Sox"); YAML_ASSERT(doc["american"][1].to() == "Detroit Tigers"); YAML_ASSERT(doc["american"][2].to() == "New York Yankees"); YAML_ASSERT(doc["national"].size() == 3); YAML_ASSERT(doc["national"][0].to() == "New York Mets"); YAML_ASSERT(doc["national"][1].to() == "Chicago Cubs"); YAML_ASSERT(doc["national"][2].to() == "Atlanta Braves"); return true; } // 2.4 TEST SequenceOfMappings() { PARSE(doc, ex2_4); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc[0].size() == 3); YAML_ASSERT(doc[0]["name"].to() == "Mark McGwire"); YAML_ASSERT(doc[0]["hr"].to() == "65"); YAML_ASSERT(doc[0]["avg"].to() == "0.278"); YAML_ASSERT(doc[1].size() == 3); YAML_ASSERT(doc[1]["name"].to() == "Sammy Sosa"); YAML_ASSERT(doc[1]["hr"].to() == "63"); YAML_ASSERT(doc[1]["avg"].to() == "0.288"); return true; } // 2.5 TEST SequenceOfSequences() { PARSE(doc, ex2_5); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc[0].size() == 3); YAML_ASSERT(doc[0][0].to() == "name"); YAML_ASSERT(doc[0][1].to() == "hr"); YAML_ASSERT(doc[0][2].to() == "avg"); YAML_ASSERT(doc[1].size() == 3); YAML_ASSERT(doc[1][0].to() == "Mark McGwire"); YAML_ASSERT(doc[1][1].to() == "65"); YAML_ASSERT(doc[1][2].to() == "0.278"); YAML_ASSERT(doc[2].size() == 3); YAML_ASSERT(doc[2][0].to() == "Sammy Sosa"); YAML_ASSERT(doc[2][1].to() == "63"); YAML_ASSERT(doc[2][2].to() == "0.288"); return true; } // 2.6 TEST MappingOfMappings() { PARSE(doc, ex2_6); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["Mark McGwire"].size() == 2); YAML_ASSERT(doc["Mark McGwire"]["hr"].to() == "65"); YAML_ASSERT(doc["Mark McGwire"]["avg"].to() == "0.278"); YAML_ASSERT(doc["Sammy Sosa"].size() == 2); YAML_ASSERT(doc["Sammy Sosa"]["hr"].to() == "63"); YAML_ASSERT(doc["Sammy Sosa"]["avg"].to() == "0.288"); return true; } // 2.7 TEST TwoDocumentsInAStream() { PARSE(doc, ex2_7); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc[0].to() == "Mark McGwire"); YAML_ASSERT(doc[1].to() == "Sammy Sosa"); YAML_ASSERT(doc[2].to() == "Ken Griffey"); PARSE_NEXT(doc); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc[0].to() == "Chicago Cubs"); YAML_ASSERT(doc[1].to() == "St Louis Cardinals"); return true; } // 2.8 TEST PlayByPlayFeed() { PARSE(doc, ex2_8); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc["time"].to() == "20:03:20"); YAML_ASSERT(doc["player"].to() == "Sammy Sosa"); YAML_ASSERT(doc["action"].to() == "strike (miss)"); PARSE_NEXT(doc); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc["time"].to() == "20:03:47"); YAML_ASSERT(doc["player"].to() == "Sammy Sosa"); YAML_ASSERT(doc["action"].to() == "grand slam"); return true; } // 2.9 TEST SingleDocumentWithTwoComments() { PARSE(doc, ex2_9); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["hr"].size() == 2); YAML_ASSERT(doc["hr"][0].to() == "Mark McGwire"); YAML_ASSERT(doc["hr"][1].to() == "Sammy Sosa"); YAML_ASSERT(doc["rbi"].size() == 2); YAML_ASSERT(doc["rbi"][0].to() == "Sammy Sosa"); YAML_ASSERT(doc["rbi"][1].to() == "Ken Griffey"); return true; } // 2.10 TEST SimpleAnchor() { PARSE(doc, ex2_10); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["hr"].size() == 2); YAML_ASSERT(doc["hr"][0].to() == "Mark McGwire"); YAML_ASSERT(doc["hr"][1].to() == "Sammy Sosa"); YAML_ASSERT(doc["rbi"].size() == 2); YAML_ASSERT(doc["rbi"][0].to() == "Sammy Sosa"); YAML_ASSERT(doc["rbi"][1].to() == "Ken Griffey"); return true; } 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; } // 2.11 TEST MappingBetweenSequences() { PARSE(doc, ex2_11); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc[Pair("Detroit Tigers", "Chicago cubs")].size() == 1); YAML_ASSERT(doc[Pair("Detroit Tigers", "Chicago cubs")][0].to() == "2001-07-23"); YAML_ASSERT(doc[Pair("New York Yankees", "Atlanta Braves")].size() == 3); YAML_ASSERT(doc[Pair("New York Yankees", "Atlanta Braves")][0].to() == "2001-07-02"); YAML_ASSERT(doc[Pair("New York Yankees", "Atlanta Braves")][1].to() == "2001-08-12"); YAML_ASSERT(doc[Pair("New York Yankees", "Atlanta Braves")][2].to() == "2001-08-14"); return true; } // 2.12 TEST CompactNestedMapping() { PARSE(doc, ex2_12); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc[0].size() == 2); YAML_ASSERT(doc[0]["item"].to() == "Super Hoop"); YAML_ASSERT(doc[0]["quantity"].to() == 1); YAML_ASSERT(doc[1].size() == 2); YAML_ASSERT(doc[1]["item"].to() == "Basketball"); YAML_ASSERT(doc[1]["quantity"].to() == 4); YAML_ASSERT(doc[2].size() == 2); YAML_ASSERT(doc[2]["item"].to() == "Big Shoes"); YAML_ASSERT(doc[2]["quantity"].to() == 1); return true; } // 2.13 TEST InLiteralsNewlinesArePreserved() { PARSE(doc, ex2_13); YAML_ASSERT(doc.to() == "\\//||\\/||\n" "// || ||__"); return true; } // 2.14 TEST InFoldedScalarsNewlinesBecomeSpaces() { PARSE(doc, ex2_14); YAML_ASSERT(doc.to() == "Mark McGwire's year was crippled by a knee injury."); return true; } // 2.15 TEST FoldedNewlinesArePreservedForMoreIndentedAndBlankLines() { PARSE(doc, ex2_15); YAML_ASSERT(doc.to() == "Sammy Sosa completed another fine season with great stats.\n\n" " 63 Home Runs\n" " 0.288 Batting Average\n\n" "What a year!"); return true; } // 2.16 TEST IndentationDeterminesScope() { PARSE(doc, ex2_16); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc["name"].to() == "Mark McGwire"); YAML_ASSERT(doc["accomplishment"].to() == "Mark set a major league home run record in 1998.\n"); YAML_ASSERT(doc["stats"].to() == "65 Home Runs\n0.278 Batting Average\n"); return true; } // 2.17 TEST QuotedScalars() { PARSE(doc, ex2_17); YAML_ASSERT(doc.size() == 6); YAML_ASSERT(doc["unicode"].to() == "Sosa did fine.\xe2\x98\xba"); YAML_ASSERT(doc["control"].to() == "\b1998\t1999\t2000\n"); YAML_ASSERT(doc["hex esc"].to() == "\x0d\x0a is \r\n"); YAML_ASSERT(doc["single"].to() == "\"Howdy!\" he cried."); YAML_ASSERT(doc["quoted"].to() == " # Not a 'comment'."); YAML_ASSERT(doc["tie-fighter"].to() == "|\\-*-/|"); return true; } // 2.18 TEST MultiLineFlowScalars() { PARSE(doc, ex2_18); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["plain"].to() == "This unquoted scalar spans many lines."); YAML_ASSERT(doc["quoted"].to() == "So does this quoted scalar.\n"); return true; } // TODO: 2.19 - 2.22 schema tags // 2.23 TEST VariousExplicitTags() { PARSE(doc, ex2_23); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc["not-date"].Tag() == "tag:yaml.org,2002:str"); YAML_ASSERT(doc["not-date"].to() == "2002-04-28"); YAML_ASSERT(doc["picture"].Tag() == "tag:yaml.org,2002:binary"); YAML_ASSERT(doc["picture"].to() == "R0lGODlhDAAMAIQAAP//9/X\n" "17unp5WZmZgAAAOfn515eXv\n" "Pz7Y6OjuDg4J+fn5OTk6enp\n" "56enmleECcgggoBADs=\n" ); YAML_ASSERT(doc["application specific tag"].Tag() == "!something"); YAML_ASSERT(doc["application specific tag"].to() == "The semantics of the tag\n" "above may be different for\n" "different documents." ); return true; } // 2.24 TEST GlobalTags() { PARSE(doc, ex2_24); YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:shape"); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc[0].Tag() == "tag:clarkevans.com,2002:circle"); YAML_ASSERT(doc[0].size() == 2); YAML_ASSERT(doc[0]["center"].size() == 2); YAML_ASSERT(doc[0]["center"]["x"].to() == 73); YAML_ASSERT(doc[0]["center"]["y"].to() == 129); YAML_ASSERT(doc[0]["radius"].to() == 7); YAML_ASSERT(doc[1].Tag() == "tag:clarkevans.com,2002:line"); YAML_ASSERT(doc[1].size() == 2); YAML_ASSERT(doc[1]["start"].size() == 2); YAML_ASSERT(doc[1]["start"]["x"].to() == 73); YAML_ASSERT(doc[1]["start"]["y"].to() == 129); YAML_ASSERT(doc[1]["finish"].size() == 2); YAML_ASSERT(doc[1]["finish"]["x"].to() == 89); YAML_ASSERT(doc[1]["finish"]["y"].to() == 102); YAML_ASSERT(doc[2].Tag() == "tag:clarkevans.com,2002:label"); YAML_ASSERT(doc[2].size() == 3); YAML_ASSERT(doc[2]["start"].size() == 2); YAML_ASSERT(doc[2]["start"]["x"].to() == 73); YAML_ASSERT(doc[2]["start"]["y"].to() == 129); YAML_ASSERT(doc[2]["color"].to() == "0xFFEEBB"); YAML_ASSERT(doc[2]["text"].to() == "Pretty vector drawing."); return true; } // 2.25 TEST UnorderedSets() { PARSE(doc, ex2_25); YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:set"); 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() { PARSE(doc, ex2_26); YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:omap"); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc[0].size() == 1); YAML_ASSERT(doc[0]["Mark McGwire"].to() == 65); YAML_ASSERT(doc[1].size() == 1); YAML_ASSERT(doc[1]["Sammy Sosa"].to() == 63); YAML_ASSERT(doc[2].size() == 1); YAML_ASSERT(doc[2]["Ken Griffey"].to() == 58); return true; } // 2.27 TEST Invoice() { PARSE(doc, ex2_27); YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:invoice"); YAML_ASSERT(doc.size() == 8); YAML_ASSERT(doc["invoice"].to() == 34843); YAML_ASSERT(doc["date"].to() == "2001-01-23"); YAML_ASSERT(doc["bill-to"].size() == 3); YAML_ASSERT(doc["bill-to"]["given"].to() == "Chris"); YAML_ASSERT(doc["bill-to"]["family"].to() == "Dumars"); YAML_ASSERT(doc["bill-to"]["address"].size() == 4); YAML_ASSERT(doc["bill-to"]["address"]["lines"].to() == "458 Walkman Dr.\nSuite #292\n"); YAML_ASSERT(doc["bill-to"]["address"]["city"].to() == "Royal Oak"); YAML_ASSERT(doc["bill-to"]["address"]["state"].to() == "MI"); YAML_ASSERT(doc["bill-to"]["address"]["postal"].to() == "48046"); YAML_ASSERT(doc["ship-to"].size() == 3); YAML_ASSERT(doc["ship-to"]["given"].to() == "Chris"); YAML_ASSERT(doc["ship-to"]["family"].to() == "Dumars"); YAML_ASSERT(doc["ship-to"]["address"].size() == 4); YAML_ASSERT(doc["ship-to"]["address"]["lines"].to() == "458 Walkman Dr.\nSuite #292\n"); YAML_ASSERT(doc["ship-to"]["address"]["city"].to() == "Royal Oak"); YAML_ASSERT(doc["ship-to"]["address"]["state"].to() == "MI"); YAML_ASSERT(doc["ship-to"]["address"]["postal"].to() == "48046"); YAML_ASSERT(doc["product"].size() == 2); YAML_ASSERT(doc["product"][0].size() == 4); YAML_ASSERT(doc["product"][0]["sku"].to() == "BL394D"); YAML_ASSERT(doc["product"][0]["quantity"].to() == 4); YAML_ASSERT(doc["product"][0]["description"].to() == "Basketball"); YAML_ASSERT(doc["product"][0]["price"].to() == "450.00"); YAML_ASSERT(doc["product"][1].size() == 4); YAML_ASSERT(doc["product"][1]["sku"].to() == "BL4438H"); YAML_ASSERT(doc["product"][1]["quantity"].to() == 1); YAML_ASSERT(doc["product"][1]["description"].to() == "Super Hoop"); YAML_ASSERT(doc["product"][1]["price"].to() == "2392.00"); YAML_ASSERT(doc["tax"].to() == "251.42"); YAML_ASSERT(doc["total"].to() == "4443.52"); YAML_ASSERT(doc["comments"].to() == "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338."); return true; } // 2.28 TEST LogFile() { PARSE(doc, ex2_28); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc["Time"].to() == "2001-11-23 15:01:42 -5"); YAML_ASSERT(doc["User"].to() == "ed"); YAML_ASSERT(doc["Warning"].to() == "This is an error message for the log file"); PARSE_NEXT(doc); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc["Time"].to() == "2001-11-23 15:02:31 -5"); YAML_ASSERT(doc["User"].to() == "ed"); YAML_ASSERT(doc["Warning"].to() == "A slightly different error message."); PARSE_NEXT(doc); YAML_ASSERT(doc.size() == 4); YAML_ASSERT(doc["Date"].to() == "2001-11-23 15:03:17 -5"); YAML_ASSERT(doc["User"].to() == "ed"); YAML_ASSERT(doc["Fatal"].to() == "Unknown variable \"bar\""); YAML_ASSERT(doc["Stack"].size() == 2); YAML_ASSERT(doc["Stack"][0].size() == 3); YAML_ASSERT(doc["Stack"][0]["file"].to() == "TopClass.py"); YAML_ASSERT(doc["Stack"][0]["line"].to() == "23"); YAML_ASSERT(doc["Stack"][0]["code"].to() == "x = MoreObject(\"345\\n\")\n"); YAML_ASSERT(doc["Stack"][1].size() == 3); YAML_ASSERT(doc["Stack"][1]["file"].to() == "MoreClass.py"); YAML_ASSERT(doc["Stack"][1]["line"].to() == "58"); YAML_ASSERT(doc["Stack"][1]["code"].to() == "foo = bar"); return true; } // TODO: 5.1 - 5.2 BOM // 5.3 TEST BlockStructureIndicators() { PARSE(doc, ex5_3); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["sequence"].size() == 2); YAML_ASSERT(doc["sequence"][0].to() == "one"); YAML_ASSERT(doc["sequence"][1].to() == "two"); YAML_ASSERT(doc["mapping"].size() == 2); YAML_ASSERT(doc["mapping"]["sky"].to() == "blue"); YAML_ASSERT(doc["mapping"]["sea"].to() == "green"); return true; } // 5.4 TEST FlowStructureIndicators() { PARSE(doc, ex5_4); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["sequence"].size() == 2); YAML_ASSERT(doc["sequence"][0].to() == "one"); YAML_ASSERT(doc["sequence"][1].to() == "two"); YAML_ASSERT(doc["mapping"].size() == 2); YAML_ASSERT(doc["mapping"]["sky"].to() == "blue"); YAML_ASSERT(doc["mapping"]["sea"].to() == "green"); return true; } // 5.5 TEST CommentIndicator() { PARSE(doc, ex5_5); YAML_ASSERT(doc.size() == 0); return true; } // 5.6 TEST NodePropertyIndicators() { PARSE(doc, ex5_6); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["anchored"].to() == "value"); // TODO: assert tag YAML_ASSERT(doc["alias"].to() == "value"); return true; } // 5.7 TEST BlockScalarIndicators() { PARSE(doc, ex5_7); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["literal"].to() == "some\ntext\n"); YAML_ASSERT(doc["folded"].to() == "some text\n"); return true; } // 5.8 TEST QuotedScalarIndicators() { PARSE(doc, ex5_8); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["single"].to() == "text"); YAML_ASSERT(doc["double"].to() == "text"); return true; } // TODO: 5.9 directive // TODO: 5.10 reserved indicator // 5.11 TEST LineBreakCharacters() { PARSE(doc, ex5_11); YAML_ASSERT(doc.to() == "Line break (no glyph)\nLine break (glyphed)\n"); return true; } // 5.12 TEST TabsAndSpaces() { PARSE(doc, ex5_12); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["quoted"].to() == "Quoted\t"); YAML_ASSERT(doc["block"].to() == "void main() {\n" "\tprintf(\"Hello, world!\\n\");\n" "}"); return true; } // 5.13 TEST EscapedCharacters() { PARSE(doc, ex5_13); YAML_ASSERT(doc.to() == "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"); return true; } // 5.14 TEST InvalidEscapedCharacters() { std::stringstream stream(ex5_14); try { YAML::Parser parser(stream); YAML::Node doc; parser.GetNextDocument(doc); } catch(const YAML::ParserException& e) { YAML_ASSERT(e.msg == std::string(YAML::ErrorMsg::INVALID_ESCAPE) + "c"); return true; } return false; } // 6.1 TEST IndentationSpaces() { PARSE(doc, ex6_1); YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc["Not indented"].size() == 2); YAML_ASSERT(doc["Not indented"]["By one space"].to() == "By four\n spaces\n"); YAML_ASSERT(doc["Not indented"]["Flow style"].size() == 3); YAML_ASSERT(doc["Not indented"]["Flow style"][0].to() == "By two"); YAML_ASSERT(doc["Not indented"]["Flow style"][1].to() == "Also by two"); YAML_ASSERT(doc["Not indented"]["Flow style"][2].to() == "Still by two"); return true; } // 6.2 TEST IndentationIndicators() { PARSE(doc, ex6_2); YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc["a"].size() == 2); YAML_ASSERT(doc["a"][0].to() == "b"); YAML_ASSERT(doc["a"][1].size() == 2); YAML_ASSERT(doc["a"][1][0].to() == "c"); YAML_ASSERT(doc["a"][1][1].to() == "d"); return true; } // 6.3 TEST SeparationSpaces() { PARSE(doc, ex6_3); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc[0].size() == 1); YAML_ASSERT(doc[0]["foo"].to() == "bar"); YAML_ASSERT(doc[1].size() == 2); YAML_ASSERT(doc[1][0].to() == "baz"); YAML_ASSERT(doc[1][1].to() == "baz"); return true; } // 6.4 TEST LinePrefixes() { PARSE(doc, ex6_4); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc["plain"].to() == "text lines"); YAML_ASSERT(doc["quoted"].to() == "text lines"); YAML_ASSERT(doc["block"].to() == "text\n \tlines\n"); return true; } // 6.5 TEST EmptyLines() { PARSE(doc, ex6_5); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["Folding"].to() == "Empty line\nas a line feed"); YAML_ASSERT(doc["Chomping"].to() == "Clipped empty lines\n"); return true; } // 6.6 TEST LineFolding() { PARSE(doc, ex6_6); YAML_ASSERT(doc.to() == "trimmed\n\n\nas space"); return true; } // 6.7 TEST BlockFolding() { PARSE(doc, ex6_7); YAML_ASSERT(doc.to() == "foo \n\n\t bar\n\nbaz\n"); return true; } // 6.8 TEST FlowFolding() { PARSE(doc, ex6_8); YAML_ASSERT(doc.to() == " foo\nbar\nbaz "); return true; } // 6.9 TEST SeparatedComment() { PARSE(doc, ex6_9); YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc["key"].to() == "value"); return true; } // 6.10 TEST CommentLines() { PARSE(doc, ex6_10); YAML_ASSERT(doc.size() == 0); return true; } // 6.11 TEST MultiLineComments() { PARSE(doc, ex6_11); YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc["key"].to() == "value"); return true; } struct StringMap { typedef std::map 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) { std::string key = it.first().to(); std::string value = it.second().to(); m._[key] = value; } } // 6.12 TEST SeparationSpacesII() { PARSE(doc, ex6_12); std::map key; key["first"] = "Sammy"; key["last"] = "Sosa"; YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc[key].size() == 2); YAML_ASSERT(doc[key]["hr"].to() == 65); YAML_ASSERT(doc[key]["avg"].to() == "0.278"); return true; } // 6.13 TEST ReservedDirectives() { PARSE(doc, ex6_13); return true; } // 6.14 TEST YAMLDirective() { PARSE(doc, ex6_14); return true; } // 6.15 TEST InvalidRepeatedYAMLDirective() { try { PARSE(doc, ex6_15); } 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() { PARSE(doc, ex6_16); YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:str"); YAML_ASSERT(doc.to() == "foo"); return true; } // 6.17 TEST InvalidRepeatedTagDirective() { try { PARSE(doc, ex6_17); } 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() { PARSE(doc, ex6_18); YAML_ASSERT(doc.Tag() == "!foo"); YAML_ASSERT(doc.to() == "bar"); PARSE_NEXT(doc); YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo"); YAML_ASSERT(doc.to() == "bar"); return true; } // 6.19 TEST SecondaryTagHandle() { PARSE(doc, ex6_19); YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/int"); YAML_ASSERT(doc.to() == "1 - 3"); return true; } // 6.20 TEST TagHandles() { PARSE(doc, ex6_20); YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo"); YAML_ASSERT(doc.to() == "bar"); return true; } // 6.21 TEST LocalTagPrefix() { PARSE(doc, ex6_21); YAML_ASSERT(doc.Tag() == "!my-light"); YAML_ASSERT(doc.to() == "fluorescent"); PARSE_NEXT(doc); YAML_ASSERT(doc.Tag() == "!my-light"); YAML_ASSERT(doc.to() == "green"); return true; } // 6.22 TEST GlobalTagPrefix() { PARSE(doc, ex6_22); YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc[0].Tag() == "tag:example.com,2000:app/foo"); YAML_ASSERT(doc[0].to() == "bar"); return true; } // 6.23 TEST NodeProperties() { PARSE(doc, ex6_23); YAML_ASSERT(doc.size() == 2); for(YAML::Iterator it=doc.begin();it!=doc.end();++it) { if(it.first().to() == "foo") { YAML_ASSERT(it.first().Tag() == "tag:yaml.org,2002:str"); YAML_ASSERT(it.second().Tag() == "tag:yaml.org,2002:str"); YAML_ASSERT(it.second().to() == "bar"); } else if(it.first().to() == "baz") { YAML_ASSERT(it.second().to() == "foo"); } else return " unknown key"; } return true; } // 6.24 TEST VerbatimTags() { PARSE(doc, ex6_24); YAML_ASSERT(doc.size() == 1); for(YAML::Iterator it=doc.begin();it!=doc.end();++it) { YAML_ASSERT(it.first().Tag() == "tag:yaml.org,2002:str"); YAML_ASSERT(it.first().to() == "foo"); YAML_ASSERT(it.second().Tag() == "!bar"); YAML_ASSERT(it.second().to() == "baz"); } return true; } // 6.25 TEST InvalidVerbatimTags() { PARSE(doc, ex6_25); return " not implemented yet"; // TODO: check tags (but we probably will say these are valid, I think) } // 6.26 TEST TagShorthands() { PARSE(doc, ex6_26); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc[0].Tag() == "!local"); YAML_ASSERT(doc[0].to() == "foo"); YAML_ASSERT(doc[1].Tag() == "tag:yaml.org,2002:str"); YAML_ASSERT(doc[1].to() == "bar"); YAML_ASSERT(doc[2].Tag() == "tag:example.com,2000:app/tag%21"); YAML_ASSERT(doc[2].to() == "baz"); return true; } // 6.27 TEST InvalidTagShorthands() { bool threw = false; try { PARSE(doc, ex6_27a); } 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"; PARSE(doc, ex6_27b); // TODO: should we reject this one (since !h! is not declared)? return " not implemented yet"; } // 6.28 TEST NonSpecificTags() { PARSE(doc, ex6_28); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc[0].to() == "12"); // TODO: check tags. How? YAML_ASSERT(doc[1].to() == 12); YAML_ASSERT(doc[2].to() == "12"); return true; } // 6.29 TEST NodeAnchors() { PARSE(doc, ex6_29); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["First occurrence"].to() == "Value"); YAML_ASSERT(doc["Second occurrence"].to() == "Value"); return true; } // 7.1 TEST AliasNodes() { PARSE(doc, ex7_1); YAML_ASSERT(doc.size() == 4); YAML_ASSERT(doc["First occurrence"].to() == "Foo"); YAML_ASSERT(doc["Second occurrence"].to() == "Foo"); YAML_ASSERT(doc["Override anchor"].to() == "Bar"); YAML_ASSERT(doc["Reuse anchor"].to() == "Bar"); return true; } // 7.2 TEST EmptyNodes() { PARSE(doc, ex7_2); YAML_ASSERT(doc.size() == 2); for(YAML::Iterator it=doc.begin();it!=doc.end();++it) { if(it.first().to() == "foo") { YAML_ASSERT(it.second().Tag() == "tag:yaml.org,2002:str"); YAML_ASSERT(it.second().to() == ""); } else if(it.first().to() == "") { YAML_ASSERT(it.first().Tag() == "tag:yaml.org,2002:str"); YAML_ASSERT(it.second().to() == "bar"); } else return " unexpected key"; } return true; } // 7.3 TEST CompletelyEmptyNodes() { PARSE(doc, ex7_3); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(IsNull(doc["foo"])); YAML_ASSERT(doc[YAML::Null].to() == "bar"); return true; } // 7.4 TEST DoubleQuotedImplicitKeys() { PARSE(doc, ex7_4); YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc["implicit block key"].size() == 1); YAML_ASSERT(doc["implicit block key"][0].size() == 1); YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"].to() == "value"); return true; } // 7.5 TEST DoubleQuotedLineBreaks() { PARSE(doc, ex7_5); YAML_ASSERT(doc.to() == "folded to a space,\nto a line feed, or \t \tnon-content"); return true; } // 7.6 TEST DoubleQuotedLines() { PARSE(doc, ex7_6); YAML_ASSERT(doc.to() == " 1st non-empty\n2nd non-empty 3rd non-empty "); return true; } // 7.7 TEST SingleQuotedCharacters() { PARSE(doc, ex7_7); YAML_ASSERT(doc.to() == "here's to \"quotes\""); return true; } // 7.8 TEST SingleQuotedImplicitKeys() { PARSE(doc, ex7_8); YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc["implicit block key"].size() == 1); YAML_ASSERT(doc["implicit block key"][0].size() == 1); YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"].to() == "value"); return true; } // 7.9 TEST SingleQuotedLines() { PARSE(doc, ex7_9); YAML_ASSERT(doc.to() == " 1st non-empty\n2nd non-empty 3rd non-empty "); return true; } // 7.10 TEST PlainCharacters() { PARSE(doc, ex7_10); YAML_ASSERT(doc.size() == 6); YAML_ASSERT(doc[0].to() == "::vector"); YAML_ASSERT(doc[1].to() == ": - ()"); YAML_ASSERT(doc[2].to() == "Up, up, and away!"); YAML_ASSERT(doc[3].to() == -123); YAML_ASSERT(doc[4].to() == "http://example.com/foo#bar"); YAML_ASSERT(doc[5].size() == 5); YAML_ASSERT(doc[5][0].to() == "::vector"); YAML_ASSERT(doc[5][1].to() == ": - ()"); YAML_ASSERT(doc[5][2].to() == "Up, up, and away!"); YAML_ASSERT(doc[5][3].to() == -123); YAML_ASSERT(doc[5][4].to() == "http://example.com/foo#bar"); return true; } // 7.11 TEST PlainImplicitKeys() { PARSE(doc, ex7_11); YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc["implicit block key"].size() == 1); YAML_ASSERT(doc["implicit block key"][0].size() == 1); YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"].to() == "value"); return true; } // 7.12 TEST PlainLines() { PARSE(doc, ex7_12); YAML_ASSERT(doc.to() == "1st non-empty\n2nd non-empty 3rd non-empty"); return true; } // 7.13 TEST FlowSequence() { PARSE(doc, ex7_13); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc[0].size() == 2); YAML_ASSERT(doc[0][0].to() == "one"); YAML_ASSERT(doc[0][1].to() == "two"); YAML_ASSERT(doc[1].size() == 2); YAML_ASSERT(doc[1][0].to() == "three"); YAML_ASSERT(doc[1][1].to() == "four"); return true; } // 7.14 TEST FlowSequenceEntries() { PARSE(doc, ex7_14); YAML_ASSERT(doc.size() == 5); YAML_ASSERT(doc[0].to() == "double quoted"); YAML_ASSERT(doc[1].to() == "single quoted"); YAML_ASSERT(doc[2].to() == "plain text"); YAML_ASSERT(doc[3].size() == 1); YAML_ASSERT(doc[3][0].to() == "nested"); YAML_ASSERT(doc[4].size() == 1); YAML_ASSERT(doc[4]["single"].to() == "pair"); return true; } // 7.15 TEST FlowMappings() { PARSE(doc, ex7_15); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc[0].size() == 2); YAML_ASSERT(doc[0]["one"].to() == "two"); YAML_ASSERT(doc[0]["three"].to() == "four"); YAML_ASSERT(doc[1].size() == 2); YAML_ASSERT(doc[1]["five"].to() == "six"); YAML_ASSERT(doc[1]["seven"].to() == "eight"); return true; } // 7.16 TEST FlowMappingEntries() { PARSE(doc, ex7_16); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc["explicit"].to() == "entry"); YAML_ASSERT(doc["implicit"].to() == "entry"); YAML_ASSERT(IsNull(doc[YAML::Null])); return true; } // 7.17 TEST FlowMappingSeparateValues() { PARSE(doc, ex7_17); YAML_ASSERT(doc.size() == 4); YAML_ASSERT(doc["unquoted"].to() == "separate"); YAML_ASSERT(IsNull(doc["http://foo.com"])); YAML_ASSERT(IsNull(doc["omitted value"])); YAML_ASSERT(doc[YAML::Null].to() == "omitted key"); return true; } // 7.18 TEST FlowMappingAdjacentValues() { PARSE(doc, ex7_18); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc["adjacent"].to() == "value"); YAML_ASSERT(doc["readable"].to() == "value"); YAML_ASSERT(IsNull(doc["empty"])); return true; } // 7.19 TEST SinglePairFlowMappings() { PARSE(doc, ex7_19); YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc[0].size() == 1); YAML_ASSERT(doc[0]["foo"].to() == "bar"); return true; } // 7.20 TEST SinglePairExplicitEntry() { PARSE(doc, ex7_20); YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc[0].size() == 1); YAML_ASSERT(doc[0]["foo bar"].to() == "baz"); return true; } // 7.21 TEST SinglePairImplicitEntries() { PARSE(doc, ex7_21); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc[0].size() == 1); YAML_ASSERT(doc[0][0].size() == 1); YAML_ASSERT(doc[0][0]["YAML"].to() == "separate"); YAML_ASSERT(doc[1].size() == 1); YAML_ASSERT(doc[1][0].size() == 1); YAML_ASSERT(doc[1][0][YAML::Null].to() == "empty key entry"); YAML_ASSERT(doc[2].size() == 1); YAML_ASSERT(doc[2][0].size() == 1); StringMap key; key._["JSON"] = "like"; YAML_ASSERT(doc[2][0][key].to() == "adjacent"); return true; } // 7.22 TEST InvalidImplicitKeys() { try { PARSE(doc, ex7_22); } catch(const YAML::Exception& e) { if(e.msg == YAML::ErrorMsg::END_OF_SEQ_FLOW) return true; throw; } return " no exception thrown"; } // 7.23 TEST FlowContent() { PARSE(doc, ex7_23); YAML_ASSERT(doc.size() == 5); YAML_ASSERT(doc[0].size() == 2); YAML_ASSERT(doc[0][0].to() == "a"); YAML_ASSERT(doc[0][1].to() == "b"); YAML_ASSERT(doc[1].size() == 1); YAML_ASSERT(doc[1]["a"].to() == "b"); YAML_ASSERT(doc[2].to() == "a"); YAML_ASSERT(doc[3].to() == 'b'); YAML_ASSERT(doc[4].to() == "c"); return true; } // 7.24 TEST FlowNodes() { PARSE(doc, ex7_24); YAML_ASSERT(doc.size() == 5); YAML_ASSERT(doc[0].Tag() == "tag:yaml.org,2002:str"); YAML_ASSERT(doc[0].to() == "a"); YAML_ASSERT(doc[1].to() == 'b'); YAML_ASSERT(doc[2].to() == "c"); YAML_ASSERT(doc[3].to() == "c"); YAML_ASSERT(doc[4].Tag() == "tag:yaml.org,2002:str"); YAML_ASSERT(doc[4].to() == ""); return true; } // 8.1 TEST BlockScalarHeader() { PARSE(doc, ex8_1); YAML_ASSERT(doc.size() == 4); YAML_ASSERT(doc[0].to() == "literal\n"); YAML_ASSERT(doc[1].to() == " folded\n"); YAML_ASSERT(doc[2].to() == "keep\n\n"); YAML_ASSERT(doc[3].to() == " strip"); return true; } // 8.2 TEST BlockIndentationHeader() { PARSE(doc, ex8_2); YAML_ASSERT(doc.size() == 4); YAML_ASSERT(doc[0].to() == "detected\n"); YAML_ASSERT(doc[1].to() == "\n\n# detected\n"); YAML_ASSERT(doc[2].to() == " explicit\n"); YAML_ASSERT(doc[3].to() == "\t\ndetected\n"); return true; } // 8.3 TEST InvalidBlockScalarIndentationIndicators() { { bool threw = false; try { PARSE(doc, ex8_3a); } 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"; } { bool threw = false; try { PARSE(doc, ex8_3b); } 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"; } { bool threw = false; try { PARSE(doc, ex8_3c); } 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() { PARSE(doc, ex8_4); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc["strip"].to() == "text"); YAML_ASSERT(doc["clip"].to() == "text\n"); YAML_ASSERT(doc["keep"].to() == "text\n"); return true; } // 8.5 TEST ChompingTrailingLines() { PARSE(doc, ex8_5); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc["strip"].to() == "# text"); YAML_ASSERT(doc["clip"].to() == "# text\n"); YAML_ASSERT(doc["keep"].to() == "# text\n"); // Note: I believe this is a bug in the YAML spec - it should be "# text\n\n" return true; } // 8.6 TEST EmptyScalarChomping() { PARSE(doc, ex8_6); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc["strip"].to() == ""); YAML_ASSERT(doc["clip"].to() == ""); YAML_ASSERT(doc["keep"].to() == "\n"); return true; } // 8.7 TEST LiteralScalar() { PARSE(doc, ex8_7); YAML_ASSERT(doc.to() == "literal\n\ttext\n"); return true; } // 8.8 TEST LiteralContent() { PARSE(doc, ex8_8); YAML_ASSERT(doc.to() == "\n\nliteral\n \n\ntext\n"); return true; } // 8.9 TEST FoldedScalar() { PARSE(doc, ex8_9); YAML_ASSERT(doc.to() == "folded text\n"); return true; } // 8.10 TEST FoldedLines() { PARSE(doc, ex8_10); YAML_ASSERT(doc.to() == "\nfolded line\nnext line\n * bullet\n\n * list\n * lines\n\nlast line\n"); 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() { PARSE(doc, ex8_14); YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc["block sequence"].size() == 2); YAML_ASSERT(doc["block sequence"][0].to() == "one"); YAML_ASSERT(doc["block sequence"][1].size() == 1); YAML_ASSERT(doc["block sequence"][1]["two"].to() == "three"); return true; } // 8.15 TEST BlockSequenceEntryTypes() { PARSE(doc, ex8_15); YAML_ASSERT(doc.size() == 4); YAML_ASSERT(YAML::IsNull(doc[0])); YAML_ASSERT(doc[1].to() == "block node\n"); YAML_ASSERT(doc[2].size() == 2); YAML_ASSERT(doc[2][0].to() == "one"); YAML_ASSERT(doc[2][1].to() == "two"); YAML_ASSERT(doc[3].size() == 1); YAML_ASSERT(doc[3]["one"].to() == "two"); return true; } // 8.16 TEST BlockMappings() { PARSE(doc, ex8_16); YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc["block mapping"].size() == 1); YAML_ASSERT(doc["block mapping"]["key"].to() == "value"); return true; } // 8.17 TEST ExplicitBlockMappingEntries() { PARSE(doc, ex8_17); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(IsNull(doc["explicit key"])); YAML_ASSERT(doc["block key\n"].size() == 2); YAML_ASSERT(doc["block key\n"][0].to() == "one"); YAML_ASSERT(doc["block key\n"][1].to() == "two"); return true; } // 8.18 TEST ImplicitBlockMappingEntries() { PARSE(doc, ex8_18); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc["plain key"].to() == "in-line value"); YAML_ASSERT(IsNull(doc[YAML::Null])); YAML_ASSERT(doc["quoted key"].size() == 1); YAML_ASSERT(doc["quoted key"][0].to() == "entry"); return true; } // 8.19 TEST CompactBlockMappings() { PARSE(doc, ex8_19); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc[0].size() == 1); YAML_ASSERT(doc[0]["sun"].to() == "yellow"); YAML_ASSERT(doc[1].size() == 1); std::map key; key["earth"] = "blue"; YAML_ASSERT(doc[1][key].size() == 1); YAML_ASSERT(doc[1][key]["moon"].to() == "white"); return true; } // 8.20 TEST BlockNodeTypes() { PARSE(doc, ex8_20); YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc[0].to() == "flow in block"); YAML_ASSERT(doc[1].to() == "Block scalar\n"); YAML_ASSERT(doc[2].size() == 1); YAML_ASSERT(doc[2]["foo"].to() == "bar"); return true; } // 8.21 TEST BlockScalarNodes() { PARSE(doc, ex8_21); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["literal"].to() == "value"); // Note: I believe this is a bug in the YAML spec - it should be "value\n" YAML_ASSERT(doc["folded"].to() == "value"); YAML_ASSERT(doc["folded"].Tag() == "!foo"); return true; } // 8.22 TEST BlockCollectionNodes() { PARSE(doc, ex8_22); YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["sequence"].size() == 2); YAML_ASSERT(doc["sequence"][0].to() == "entry"); YAML_ASSERT(doc["sequence"][1].size() == 1); YAML_ASSERT(doc["sequence"][1][0].to() == "nested"); YAML_ASSERT(doc["mapping"].size() == 1); YAML_ASSERT(doc["mapping"]["foo"].to() == "bar"); return true; } } }