diff options
Diffstat (limited to 'external_libs/yaml-cpp/test/old-api')
-rw-r--r-- | external_libs/yaml-cpp/test/old-api/parsertests.cpp | 1237 | ||||
-rw-r--r-- | external_libs/yaml-cpp/test/old-api/spectests.cpp | 1456 |
2 files changed, 2693 insertions, 0 deletions
diff --git a/external_libs/yaml-cpp/test/old-api/parsertests.cpp b/external_libs/yaml-cpp/test/old-api/parsertests.cpp new file mode 100644 index 00000000..de7f1238 --- /dev/null +++ b/external_libs/yaml-cpp/test/old-api/parsertests.cpp @@ -0,0 +1,1237 @@ +#include "tests.h" +#include "yaml-cpp/yaml.h" +#include <sstream> +#include <algorithm> +#include <iostream> + +namespace Test +{ + namespace Parser { + void SimpleScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = "Hello, World!"; + desiredOutput = "Hello, World!"; + } + + void MultiLineScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = + "normal scalar, but\n" + "over several lines"; + desiredOutput = "normal scalar, but over several lines"; + } + + void LiteralScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = + "|\n" + " literal scalar - so we can draw ASCII:\n" + " \n" + " - -\n" + " | - |\n" + " -----\n"; + desiredOutput = + "literal scalar - so we can draw ASCII:\n" + "\n" + " - -\n" + " | - |\n" + " -----\n"; + } + + void FoldedScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = + ">\n" + " and a folded scalar... so we\n" + " can just keep writing various\n" + " things. And if we want to keep indentation:\n" + " \n" + " we just indent a little\n" + " see, this stays indented"; + desiredOutput = + "and a folded scalar... so we" + " can just keep writing various" + " things. And if we want to keep indentation:\n" + "\n" + " we just indent a little\n" + " see, this stays indented"; + } + + void ChompedFoldedScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = + ">-\n" + " Here's a folded scalar\n" + " that gets chomped."; + desiredOutput = + "Here's a folded scalar" + " that gets chomped."; + } + + void ChompedLiteralScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = + "|-\n" + " Here's a literal scalar\n" + " that gets chomped."; + desiredOutput = + "Here's a literal scalar\n" + "that gets chomped."; + } + + void FoldedScalarWithIndent(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = + ">2\n" + " Here's a folded scalar\n" + " that starts with some indentation."; + desiredOutput = + " Here's a folded scalar\n" + "that starts with some indentation."; + } + + void ColonScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = "::vector"; + desiredOutput = "::vector"; + } + + void QuotedScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = "\": - ()\""; + desiredOutput = ": - ()"; + } + + void CommaScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = "Up, up, and away!"; + desiredOutput = "Up, up, and away!"; + } + + void DashScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = "-123"; + desiredOutput = "-123"; + } + + void URLScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = "http://example.com/foo#bar"; + desiredOutput = "http://example.com/foo#bar"; + } + + bool SimpleSeq() + { + std::string input = + "- eggs\n" + "- bread\n" + "- milk"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + std::string output; + if(doc[0].to<std::string>() != "eggs") + return false; + if(doc[1].to<std::string>() != "bread") + return false; + if(doc[2].to<std::string>() != "milk") + return false; + + return true; + } + + bool SimpleMap() + { + std::string input = + "name: Prince Fielder\n" + "position: 1B\n" + "bats: L"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + std::string output; + doc["name"] >> output; + if(output != "Prince Fielder") + return false; + doc["position"] >> output; + if(output != "1B") + return false; + doc["bats"] >> output; + if(output != "L") + return false; + + return true; + } + + bool FlowSeq() + { + std::string input = "[ 2 , 3, 5 , 7, 11]"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + int output; + doc[0] >> output; + if(output != 2) + return false; + doc[1] >> output; + if(output != 3) + return false; + doc[2] >> output; + if(output != 5) + return false; + doc[3] >> output; + if(output != 7) + return false; + doc[4] >> output; + if(output != 11) + return false; + + return true; + } + + bool FlowMap() + { + std::string input = "{hr: 65, avg: 0.278}"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + std::string output; + doc["hr"] >> output; + if(output != "65") + return false; + doc["avg"] >> output; + if(output != "0.278") + return false; + + return true; + } + + bool FlowMapWithOmittedKey() + { + std::string input = "{: omitted key}"; + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + std::string output; + doc[YAML::Null] >> output; + if(output != "omitted key") + return false; + + return true; + } + + bool FlowMapWithOmittedValue() + { + std::string input = "{a: b, c:, d:}"; + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + std::string output; + doc["a"] >> output; + if(output != "b") + return false; + if(!IsNull(doc["c"])) + return false; + if(!IsNull(doc["d"])) + return false; + + return true; + } + + bool FlowMapWithSoloEntry() + { + std::string input = "{a: b, c, d: e}"; + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + std::string output; + doc["a"] >> output; + if(output != "b") + return false; + if(!IsNull(doc["c"])) + return false; + doc["d"] >> output; + if(output != "e") + return false; + + return true; + } + + bool FlowMapEndingWithSoloEntry() + { + std::string input = "{a: b, c}"; + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + std::string output; + doc["a"] >> output; + if(output != "b") + return false; + if(!IsNull(doc["c"])) + return false; + + return true; + } + + bool QuotedSimpleKeys() + { + std::string KeyValue[3] = { "\"double\": double\n", "'single': single\n", "plain: plain\n" }; + + int perm[3] = { 0, 1, 2 }; + do { + std::string input = KeyValue[perm[0]] + KeyValue[perm[1]] + KeyValue[perm[2]]; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + std::string output; + doc["double"] >> output; + if(output != "double") + return false; + doc["single"] >> output; + if(output != "single") + return false; + doc["plain"] >> output; + if(output != "plain") + return false; + } while(std::next_permutation(perm, perm + 3)); + + return true; + } + + bool CompressedMapAndSeq() + { + std::string input = "key:\n- one\n- two"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + const YAML::Node& seq = doc["key"]; + if(seq.size() != 2) + return false; + + std::string output; + seq[0] >> output; + if(output != "one") + return false; + seq[1] >> output; + if(output != "two") + return false; + + return true; + } + + bool NullBlockSeqEntry() + { + std::string input = "- hello\n-\n- world"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + std::string output; + doc[0] >> output; + if(output != "hello") + return false; + if(!IsNull(doc[1])) + return false; + doc[2] >> output; + if(output != "world") + return false; + + return true; + } + + bool NullBlockMapKey() + { + std::string input = ": empty key"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + std::string output; + doc[YAML::Null] >> output; + if(output != "empty key") + return false; + + return true; + } + + bool NullBlockMapValue() + { + std::string input = "empty value:"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + if(!IsNull(doc["empty value"])) + return false; + + return true; + } + + bool SimpleAlias() + { + std::string input = "- &alias test\n- *alias"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + std::string output; + doc[0] >> output; + if(output != "test") + return false; + + doc[1] >> output; + if(output != "test") + return false; + + if(doc.size() != 2) + return false; + + return true; + } + + bool AliasWithNull() + { + std::string input = "- &alias\n- *alias"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + if(!IsNull(doc[0])) + return false; + + if(!IsNull(doc[1])) + return false; + + if(doc.size() != 2) + return false; + + return true; + } + + bool AnchorInSimpleKey() + { + std::string input = "- &a b: c\n- *a"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + if(doc.size() != 2) + return false; + + std::string output; + doc[0]["b"] >> output; + if(output != "c") + return false; + + doc[1] >> output; + if(output != "b") + return false; + + return true; + } + + bool AliasAsSimpleKey() + { + std::string input = "- &a b\n- *a : c"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + if(doc.size() != 2) + return false; + + std::string output; + doc[0] >> output; + if(output != "b") + return false; + + doc[1]["b"] >> output; + if(output != "c") + return false; + + return true; + } + + bool ExplicitDoc() + { + std::string input = "---\n- one\n- two"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + if(doc.size() != 2) + return false; + + std::string output; + doc[0] >> output; + if(output != "one") + return false; + doc[1] >> output; + if(output != "two") + return false; + + return true; + } + + bool MultipleDocs() + { + std::string input = "---\nname: doc1\n---\nname: doc2"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + std::string output; + doc["name"] >> output; + if(output != "doc1") + return false; + + if(!parser) + return false; + + parser.GetNextDocument(doc); + doc["name"] >> output; + if(output != "doc2") + return false; + + return true; + } + + bool ExplicitEndDoc() + { + std::string input = "- one\n- two\n...\n..."; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + if(doc.size() != 2) + return false; + + std::string output; + doc[0] >> output; + if(output != "one") + return false; + doc[1] >> output; + if(output != "two") + return false; + + return true; + } + + bool MultipleDocsWithSomeExplicitIndicators() + { + std::string input = + "- one\n- two\n...\n" + "---\nkey: value\n...\n...\n" + "- three\n- four\n" + "---\nkey: value"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + std::string output; + + parser.GetNextDocument(doc); + if(doc.size() != 2) + return false; + doc[0] >> output; + if(output != "one") + return false; + doc[1] >> output; + if(output != "two") + return false; + + parser.GetNextDocument(doc); + doc["key"] >> output; + if(output != "value") + return false; + + parser.GetNextDocument(doc); + if(doc.size() != 2) + return false; + doc[0] >> output; + if(output != "three") + return false; + doc[1] >> output; + if(output != "four") + return false; + + parser.GetNextDocument(doc); + doc["key"] >> output; + if(output != "value") + return false; + + return true; + } + + bool BlockKeyWithNullValue() + { + std::string input = + "key:\n" + "just a key: value"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + + parser.GetNextDocument(doc); + if(doc.size() != 2) + return false; + if(!IsNull(doc["key"])) + return false; + if(doc["just a key"].to<std::string>() != "value") + return false; + + return true; + } + + bool Bases() + { + std::string input = + "- 15\n" + "- 0x10\n" + "- 030\n" + "- 0xffffffff\n"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + + parser.GetNextDocument(doc); + if(doc.size() != 4) + return false; + if(doc[0].to<int>() != 15) + return false; + if(doc[1].to<int>() != 0x10) + return false; + if(doc[2].to<int>() != 030) + return false; + if(doc[3].to<unsigned>() != 0xffffffff) + return false; + return true; + } + + bool KeyNotFound() + { + std::string input = "key: value"; + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + try { + doc["bad key"]; + } catch(const YAML::Exception& e) { + if(e.msg != std::string(YAML::ErrorMsg::KEY_NOT_FOUND) + ": bad key") + throw; + } + + try { + doc[5]; + } catch(const YAML::Exception& e) { + if(e.msg != std::string(YAML::ErrorMsg::KEY_NOT_FOUND) + ": 5") + throw; + } + + try { + doc[2.5]; + } catch(const YAML::Exception& e) { + if(e.msg != std::string(YAML::ErrorMsg::KEY_NOT_FOUND) + ": 2.5") + throw; + } + + return true; + } + + bool DuplicateKey() + { + std::string input = "{a: 1, b: 2, c: 3, a: 4}"; + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + if(doc["a"].to<int>() != 4) + return false; + if(doc["b"].to<int>() != 2) + return false; + if(doc["c"].to<int>() != 3) + return false; + return true; + } + + void PrepareNodeForTagExam(YAML::Node& doc, const std::string& input) + { + std::stringstream stream(input); + YAML::Parser parser(stream); + parser.GetNextDocument(doc); + } + + struct TagMismatch: public std::exception { + TagMismatch(const std::string& actualTag, const std::string& expectedTag) { + std::stringstream output; + output << "Tag has value \"" << actualTag << "\" but \"" << expectedTag << "\" was expected"; + what_ = output.str(); + } + virtual ~TagMismatch() throw() {} + virtual const char *what() const throw() { return what_.c_str(); } + + private: + std::string what_; + }; + + bool ExpectedTagValue(YAML::Node& node, const char* tag) + { + if(node.Tag() == tag) + return true; + + throw TagMismatch(node.Tag(), tag); + } + + bool DefaultPlainScalarTag() + { + YAML::Node node; + PrepareNodeForTagExam(node, "--- 12"); + + return ExpectedTagValue(node, "?"); + } + + bool DefaultSingleQuotedScalarTag() + { + YAML::Node node; + PrepareNodeForTagExam(node, "--- '12'"); + + return ExpectedTagValue(node, "!"); + } + + bool ExplicitNonSpecificPlainScalarTag() + { + YAML::Node node; + PrepareNodeForTagExam(node, "--- ! 12"); + + return ExpectedTagValue(node, "!"); + } + + bool BasicLocalTag() + { + YAML::Node node; + PrepareNodeForTagExam(node, "--- !foo 12"); + + return ExpectedTagValue(node, "!foo"); + } + + bool VerbatimLocalTag() + { + YAML::Node node; + PrepareNodeForTagExam(node, "--- !<!foo> 12"); + + return ExpectedTagValue(node, "!foo"); + } + + bool StandardShortcutTag() + { + YAML::Node node; + PrepareNodeForTagExam(node, "--- !!int 12"); + + return ExpectedTagValue(node, "tag:yaml.org,2002:int"); + } + + bool VerbatimURITag() + { + YAML::Node node; + PrepareNodeForTagExam(node, "--- !<tag:yaml.org,2002:int> 12"); + + return ExpectedTagValue(node, "tag:yaml.org,2002:int"); + } + + bool DefaultSequenceTag() + { + YAML::Node node; + PrepareNodeForTagExam(node, "--- [12]"); + + return ExpectedTagValue(node, "?"); + } + + bool ExplicitNonSpecificSequenceTag() + { + YAML::Node node; + PrepareNodeForTagExam(node, "--- ! [12]"); + + return ExpectedTagValue(node, "!"); + } + + bool Infinity() + { + std::string input = + "- .inf\n" + "- .Inf\n" + "- .INF\n" + "- +.inf\n" + "- +.Inf\n" + "- +.INF\n" + "- -.inf\n" + "- -.Inf\n" + "- -.INF\n"; + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + for(unsigned i=0;i<doc.size();i++) + if(doc[i].to<double>() != (i < 6 ? +1 : -1) * std::numeric_limits<double>::infinity()) + return false; + for(unsigned i=0;i<doc.size();i++) + if(doc[i].to<long double>() != (i < 6 ? +1 : -1) * std::numeric_limits<long double>::infinity()) + return false; + for(unsigned i=0;i<doc.size();i++) + if(doc[i].to<float>() != (i < 6 ? +1 : -1) * std::numeric_limits<float>::infinity()) + return false; + return true; + } + + bool NaN() + { + std::string input = + "- .nan\n" + "- .NaN\n" + "- .NAN\n"; + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + for(unsigned i=0;i<doc.size();i++) { + double d; + doc[i] >> d; + if(d == d) + return false; + } + for(unsigned i=0;i<doc.size();i++) { + long double d; + doc[i] >> d; + if(d == d) + return false; + } + for(unsigned i=0;i<doc.size();i++) { + float d; + doc[i] >> d; + if(d == d) + return false; + } + return true; + } + + bool NonConstKey() + { + std::string input = "{a: 1}"; + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + std::vector<char> key(2); + key[0] = 'a'; + key[1] = '\0'; + if(doc[&key[0]].to<int>() != 1) + return false; + return true; + } + + bool SingleChar() + { + std::string input = "5"; + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + return doc.to<int>() == 5; + } + + bool QuotedNewline() + { + std::string input = "foo: \"\\n\""; + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + return doc["foo"].to<std::string>() == "\n"; + } + + bool DoubleAsInt() + { + std::string input = "1.5"; + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + try { + doc.to<int>(); + } catch(const YAML::InvalidScalar& e) { + return true; + } + + return false; + } + + bool Binary() + { + std::string input = "[!!binary \"SGVsbG8sIFdvcmxkIQ==\", !!binary \"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4K\"]"; + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + if(doc[0].to<YAML::Binary>() != YAML::Binary(reinterpret_cast<const unsigned char*>("Hello, World!"), 13)) + return false; + if(doc[1].to<YAML::Binary>() != YAML::Binary(reinterpret_cast<const unsigned char*>("Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.\n"), 270)) + return false; + return true; + } + } + + namespace { + void RunScalarParserTest(void (*test)(std::string&, std::string&), const std::string& name, int& passed, int& total) { + std::string error; + std::string inputScalar, desiredOutput; + std::string output; + bool ok = true; + try { + test(inputScalar, desiredOutput); + std::stringstream stream(inputScalar); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + doc >> output; + } catch(const YAML::Exception& e) { + ok = false; + error = e.what(); + } + if(ok && output == desiredOutput) { + passed++; + } else { + std::cout << "Parser test failed: " << name << "\n"; + if(error != "") + std::cout << "Caught exception: " << error << "\n"; + else { + std::cout << "Output:\n" << output << "<<<\n"; + std::cout << "Desired output:\n" << desiredOutput << "<<<\n"; + } + } + total++; + } + + void RunParserTest(bool (*test)(), const std::string& name, int& passed, int& total) { + std::string error; + bool ok = true; + try { + ok = test(); + } catch(const YAML::Exception& e) { + ok = false; + error = e.what(); + } catch(const Parser::TagMismatch& e) { + ok = false; + error = e.what(); + } + if(ok) { + passed++; + } else { + std::cout << "Parser test failed: " << name << "\n"; + if(error != "") + std::cout << " Caught exception: " << error << "\n"; + } + total++; + } + + typedef void (*EncodingFn)(std::ostream&, int); + + inline char Byte(int ch) + { + return static_cast<char>(static_cast<unsigned char>(static_cast<unsigned int>(ch))); + } + + void EncodeToUtf8(std::ostream& stream, int ch) + { + if (ch <= 0x7F) + { + stream << Byte(ch); + } + else if (ch <= 0x7FF) + { + stream << Byte(0xC0 | (ch >> 6)); + stream << Byte(0x80 | (ch & 0x3F)); + } + else if (ch <= 0xFFFF) + { + stream << Byte(0xE0 | (ch >> 12)); + stream << Byte(0x80 | ((ch >> 6) & 0x3F)); + stream << Byte(0x80 | (ch & 0x3F)); + } + else if (ch <= 0x1FFFFF) + { + stream << Byte(0xF0 | (ch >> 18)); + stream << Byte(0x80 | ((ch >> 12) & 0x3F)); + stream << Byte(0x80 | ((ch >> 6) & 0x3F)); + stream << Byte(0x80 | (ch & 0x3F)); + } + } + + bool SplitUtf16HighChar(std::ostream& stream, EncodingFn encoding, int ch) + { + int biasedValue = ch - 0x10000; + if (biasedValue < 0) + { + return false; + } + int high = 0xD800 | (biasedValue >> 10); + int low = 0xDC00 | (biasedValue & 0x3FF); + encoding(stream, high); + encoding(stream, low); + return true; + } + + void EncodeToUtf16LE(std::ostream& stream, int ch) + { + if (!SplitUtf16HighChar(stream, &EncodeToUtf16LE, ch)) + { + stream << Byte(ch & 0xFF) << Byte(ch >> 8); + } + } + + void EncodeToUtf16BE(std::ostream& stream, int ch) + { + if (!SplitUtf16HighChar(stream, &EncodeToUtf16BE, ch)) + { + stream << Byte(ch >> 8) << Byte(ch & 0xFF); + } + } + + void EncodeToUtf32LE(std::ostream& stream, int ch) + { + stream << Byte(ch & 0xFF) << Byte((ch >> 8) & 0xFF) + << Byte((ch >> 16) & 0xFF) << Byte((ch >> 24) & 0xFF); + } + + void EncodeToUtf32BE(std::ostream& stream, int ch) + { + stream << Byte((ch >> 24) & 0xFF) << Byte((ch >> 16) & 0xFF) + << Byte((ch >> 8) & 0xFF) << Byte(ch & 0xFF); + } + + class EncodingTester + { + public: + EncodingTester(EncodingFn encoding, bool declareEncoding) + { + if (declareEncoding) + { + encoding(m_yaml, 0xFEFF); + } + + AddEntry(encoding, 0x0021, 0x007E); // Basic Latin + AddEntry(encoding, 0x00A1, 0x00FF); // Latin-1 Supplement + AddEntry(encoding, 0x0660, 0x06FF); // Arabic (largest contiguous block) + + // CJK unified ideographs (multiple lines) + AddEntry(encoding, 0x4E00, 0x4EFF); + AddEntry(encoding, 0x4F00, 0x4FFF); + AddEntry(encoding, 0x5000, 0x51FF); // 512 character line + AddEntry(encoding, 0x5200, 0x54FF); // 768 character line + AddEntry(encoding, 0x5500, 0x58FF); // 1024 character line + + AddEntry(encoding, 0x103A0, 0x103C3); // Old Persian + + m_yaml.seekg(0, std::ios::beg); + } + + std::istream& stream() {return m_yaml;} + const std::vector<std::string>& entries() {return m_entries;} + + private: + std::stringstream m_yaml; + std::vector<std::string> m_entries; + + void AddEntry(EncodingFn encoding, int startCh, int endCh) + { + encoding(m_yaml, '-'); + encoding(m_yaml, ' '); + encoding(m_yaml, '|'); + encoding(m_yaml, '\n'); + encoding(m_yaml, ' '); + encoding(m_yaml, ' '); + + std::stringstream entry; + for (int ch = startCh; ch <= endCh; ++ch) + { + encoding(m_yaml, ch); + EncodeToUtf8(entry, ch); + } + encoding(m_yaml, '\n'); + + m_entries.push_back(entry.str()); + } + }; + + void RunEncodingTest(EncodingFn encoding, bool declareEncoding, const std::string& name, int& passed, int& total) + { + EncodingTester tester(encoding, declareEncoding); + std::string error; + bool ok = true; + try { + YAML::Parser parser(tester.stream()); + YAML::Node doc; + parser.GetNextDocument(doc); + + YAML::Iterator itNode = doc.begin(); + std::vector<std::string>::const_iterator itEntry = tester.entries().begin(); + for (; (itNode != doc.end()) && (itEntry != tester.entries().end()); ++itNode, ++itEntry) + { + std::string stScalarValue; + if (!itNode->GetScalar(stScalarValue) && (stScalarValue == *itEntry)) + { + break; + } + } + + if ((itNode != doc.end()) || (itEntry != tester.entries().end())) + { + ok = false; + } + } catch(const YAML::Exception& e) { + ok = false; + error = e.msg; + } + if(ok) { + passed++; + } else { + std::cout << "Parser test failed: " << name << "\n"; + if(error != "") + std::cout << " Caught exception: " << error << "\n"; + } + total++; + } + } + + bool RunParserTests() + { + int passed = 0; + int total = 0; + RunScalarParserTest(&Parser::SimpleScalar, "simple scalar", passed, total); + RunScalarParserTest(&Parser::MultiLineScalar, "multi-line scalar", passed, total); + RunScalarParserTest(&Parser::LiteralScalar, "literal scalar", passed, total); + RunScalarParserTest(&Parser::FoldedScalar, "folded scalar", passed, total); + RunScalarParserTest(&Parser::ChompedFoldedScalar, "chomped folded scalar", passed, total); + RunScalarParserTest(&Parser::ChompedLiteralScalar, "chomped literal scalar", passed, total); + RunScalarParserTest(&Parser::FoldedScalarWithIndent, "folded scalar with indent", passed, total); + RunScalarParserTest(&Parser::ColonScalar, "colon scalar", passed, total); + RunScalarParserTest(&Parser::QuotedScalar, "quoted scalar", passed, total); + RunScalarParserTest(&Parser::CommaScalar, "comma scalar", passed, total); + RunScalarParserTest(&Parser::DashScalar, "dash scalar", passed, total); + RunScalarParserTest(&Parser::URLScalar, "url scalar", passed, total); + + RunParserTest(&Parser::SimpleSeq, "simple seq", passed, total); + RunParserTest(&Parser::SimpleMap, "simple map", passed, total); + RunParserTest(&Parser::FlowSeq, "flow seq", passed, total); + RunParserTest(&Parser::FlowMap, "flow map", passed, total); + RunParserTest(&Parser::FlowMapWithOmittedKey, "flow map with omitted key", passed, total); + RunParserTest(&Parser::FlowMapWithOmittedValue, "flow map with omitted value", passed, total); + RunParserTest(&Parser::FlowMapWithSoloEntry, "flow map with solo entry", passed, total); + RunParserTest(&Parser::FlowMapEndingWithSoloEntry, "flow map ending with solo entry", passed, total); + RunParserTest(&Parser::QuotedSimpleKeys, "quoted simple keys", passed, total); + RunParserTest(&Parser::CompressedMapAndSeq, "compressed map and seq", passed, total); + RunParserTest(&Parser::NullBlockSeqEntry, "null block seq entry", passed, total); + RunParserTest(&Parser::NullBlockMapKey, "null block map key", passed, total); + RunParserTest(&Parser::NullBlockMapValue, "null block map value", passed, total); + RunParserTest(&Parser::SimpleAlias, "simple alias", passed, total); + RunParserTest(&Parser::AliasWithNull, "alias with null", passed, total); + RunParserTest(&Parser::AnchorInSimpleKey, "anchor in simple key", passed, total); + RunParserTest(&Parser::AliasAsSimpleKey, "alias as simple key", passed, total); + RunParserTest(&Parser::ExplicitDoc, "explicit doc", passed, total); + RunParserTest(&Parser::MultipleDocs, "multiple docs", passed, total); + RunParserTest(&Parser::ExplicitEndDoc, "explicit end doc", passed, total); + RunParserTest(&Parser::MultipleDocsWithSomeExplicitIndicators, "multiple docs with some explicit indicators", passed, total); + RunParserTest(&Parser::BlockKeyWithNullValue, "block key with null value", passed, total); + RunParserTest(&Parser::Bases, "bases", passed, total); + RunParserTest(&Parser::KeyNotFound, "key not found", passed, total); + RunParserTest(&Parser::DuplicateKey, "duplicate key", passed, total); + RunParserTest(&Parser::DefaultPlainScalarTag, "default plain scalar tag", passed, total); + RunParserTest(&Parser::DefaultSingleQuotedScalarTag, "default single-quoted scalar tag", passed, total); + RunParserTest(&Parser::ExplicitNonSpecificPlainScalarTag, "explicit, non-specific plain scalar tag", passed, total); + RunParserTest(&Parser::BasicLocalTag, "basic local tag", passed, total); + RunParserTest(&Parser::VerbatimLocalTag, "verbatim local tag", passed, total); + RunParserTest(&Parser::StandardShortcutTag, "standard shortcut tag", passed, total); + RunParserTest(&Parser::VerbatimURITag, "verbatim URI tag", passed, total); + RunParserTest(&Parser::DefaultPlainScalarTag, "default plain scalar tag", passed, total); + RunParserTest(&Parser::DefaultSequenceTag, "default sequence tag", passed, total); + RunParserTest(&Parser::ExplicitNonSpecificSequenceTag, "explicit, non-specific sequence tag", passed, total); + RunParserTest(&Parser::Infinity, "infinity", passed, total); + RunParserTest(&Parser::NaN, "NaN", passed, total); + RunParserTest(&Parser::NonConstKey, "non const key", passed, total); + RunParserTest(&Parser::SingleChar, "single char", passed, total); + RunParserTest(&Parser::QuotedNewline, "quoted newline", passed, total); + RunParserTest(&Parser::DoubleAsInt, "double as int", passed, total); + RunParserTest(&Parser::Binary, "binary", passed, total); + + RunEncodingTest(&EncodeToUtf8, false, "UTF-8, no BOM", passed, total); + RunEncodingTest(&EncodeToUtf8, true, "UTF-8 with BOM", passed, total); + RunEncodingTest(&EncodeToUtf16LE, false, "UTF-16LE, no BOM", passed, total); + RunEncodingTest(&EncodeToUtf16LE, true, "UTF-16LE with BOM", passed, total); + RunEncodingTest(&EncodeToUtf16BE, false, "UTF-16BE, no BOM", passed, total); + RunEncodingTest(&EncodeToUtf16BE, true, "UTF-16BE with BOM", passed, total); + RunEncodingTest(&EncodeToUtf32LE, false, "UTF-32LE, no BOM", passed, total); + RunEncodingTest(&EncodeToUtf32LE, true, "UTF-32LE with BOM", passed, total); + RunEncodingTest(&EncodeToUtf32BE, false, "UTF-32BE, no BOM", passed, total); + RunEncodingTest(&EncodeToUtf32BE, true, "UTF-32BE with BOM", passed, total); + + std::cout << "Parser tests: " << passed << "/" << total << " passed\n"; + return passed == total; + } +} + diff --git a/external_libs/yaml-cpp/test/old-api/spectests.cpp b/external_libs/yaml-cpp/test/old-api/spectests.cpp new file mode 100644 index 00000000..fb5505be --- /dev/null +++ b/external_libs/yaml-cpp/test/old-api/spectests.cpp @@ -0,0 +1,1456 @@ +#include "spectests.h" +#include "specexamples.h" +#include "yaml-cpp/yaml.h" +#include <fstream> +#include <sstream> +#include <vector> +#include <iostream> + +#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<std::string>() == "Mark McGwire"); + YAML_ASSERT(doc[1].to<std::string>() == "Sammy Sosa"); + YAML_ASSERT(doc[2].to<std::string>() == "Ken Griffey"); + return true; + } + + // 2.2 + TEST MappingScalarsToScalars() { + PARSE(doc, ex2_2); + YAML_ASSERT(doc.size() == 3); + 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"); + 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<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"); + YAML_ASSERT(doc["national"].size() == 3); + 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"); + 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<std::string>() == "Mark McGwire"); + YAML_ASSERT(doc[0]["hr"].to<std::string>() == "65"); + YAML_ASSERT(doc[0]["avg"].to<std::string>() == "0.278"); + YAML_ASSERT(doc[1].size() == 3); + 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"); + 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<std::string>() == "name"); + YAML_ASSERT(doc[0][1].to<std::string>() == "hr"); + YAML_ASSERT(doc[0][2].to<std::string>() == "avg"); + YAML_ASSERT(doc[1].size() == 3); + 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"); + YAML_ASSERT(doc[2].size() == 3); + 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"); + 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<std::string>() == "65"); + YAML_ASSERT(doc["Mark McGwire"]["avg"].to<std::string>() == "0.278"); + YAML_ASSERT(doc["Sammy Sosa"].size() == 2); + YAML_ASSERT(doc["Sammy Sosa"]["hr"].to<std::string>() == "63"); + YAML_ASSERT(doc["Sammy Sosa"]["avg"].to<std::string>() == "0.288"); + return true; + } + + // 2.7 + TEST TwoDocumentsInAStream() + { + PARSE(doc, ex2_7); + YAML_ASSERT(doc.size() == 3); + 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"); + + PARSE_NEXT(doc); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc[0].to<std::string>() == "Chicago Cubs"); + YAML_ASSERT(doc[1].to<std::string>() == "St Louis Cardinals"); + return true; + } + + // 2.8 + TEST PlayByPlayFeed() + { + PARSE(doc, ex2_8); + YAML_ASSERT(doc.size() == 3); + 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)"); + + PARSE_NEXT(doc); + YAML_ASSERT(doc.size() == 3); + 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"); + 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<std::string>() == "Mark McGwire"); + YAML_ASSERT(doc["hr"][1].to<std::string>() == "Sammy Sosa"); + YAML_ASSERT(doc["rbi"].size() == 2); + YAML_ASSERT(doc["rbi"][0].to<std::string>() == "Sammy Sosa"); + YAML_ASSERT(doc["rbi"][1].to<std::string>() == "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<std::string>() == "Mark McGwire"); + YAML_ASSERT(doc["hr"][1].to<std::string>() == "Sammy Sosa"); + YAML_ASSERT(doc["rbi"].size() == 2); + YAML_ASSERT(doc["rbi"][0].to<std::string>() == "Sammy Sosa"); + YAML_ASSERT(doc["rbi"][1].to<std::string>() == "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<std::string>() == "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<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"); + 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<std::string>() == "Super Hoop"); + YAML_ASSERT(doc[0]["quantity"].to<int>() == 1); + YAML_ASSERT(doc[1].size() == 2); + YAML_ASSERT(doc[1]["item"].to<std::string>() == "Basketball"); + YAML_ASSERT(doc[1]["quantity"].to<int>() == 4); + YAML_ASSERT(doc[2].size() == 2); + YAML_ASSERT(doc[2]["item"].to<std::string>() == "Big Shoes"); + YAML_ASSERT(doc[2]["quantity"].to<int>() == 1); + return true; + } + + // 2.13 + TEST InLiteralsNewlinesArePreserved() + { + PARSE(doc, ex2_13); + YAML_ASSERT(doc.to<std::string>() == + "\\//||\\/||\n" + "// || ||__"); + return true; + } + + // 2.14 + TEST InFoldedScalarsNewlinesBecomeSpaces() + { + PARSE(doc, ex2_14); + YAML_ASSERT(doc.to<std::string>() == "Mark McGwire's year was crippled by a knee injury."); + return true; + } + + // 2.15 + TEST FoldedNewlinesArePreservedForMoreIndentedAndBlankLines() + { + PARSE(doc, ex2_15); + YAML_ASSERT(doc.to<std::string>() == + "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<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"); + return true; + } + + // 2.17 + TEST QuotedScalars() + { + PARSE(doc, ex2_17); + YAML_ASSERT(doc.size() == 6); + 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>() == "|\\-*-/|"); + return true; + } + + // 2.18 + TEST MultiLineFlowScalars() + { + PARSE(doc, ex2_18); + YAML_ASSERT(doc.size() == 2); + 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"); + 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<std::string>() == "2002-04-28"); + YAML_ASSERT(doc["picture"].Tag() == "tag:yaml.org,2002:binary"); + YAML_ASSERT(doc["picture"].to<std::string>() == + "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<std::string>() == + "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<int>() == 73); + YAML_ASSERT(doc[0]["center"]["y"].to<int>() == 129); + YAML_ASSERT(doc[0]["radius"].to<int>() == 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<int>() == 73); + YAML_ASSERT(doc[1]["start"]["y"].to<int>() == 129); + YAML_ASSERT(doc[1]["finish"].size() == 2); + YAML_ASSERT(doc[1]["finish"]["x"].to<int>() == 89); + YAML_ASSERT(doc[1]["finish"]["y"].to<int>() == 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<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."); + 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<int>() == 65); + YAML_ASSERT(doc[1].size() == 1); + YAML_ASSERT(doc[1]["Sammy Sosa"].to<int>() == 63); + YAML_ASSERT(doc[2].size() == 1); + YAML_ASSERT(doc[2]["Ken Griffey"].to<int>() == 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<int>() == 34843); + YAML_ASSERT(doc["date"].to<std::string>() == "2001-01-23"); + YAML_ASSERT(doc["bill-to"].size() == 3); + YAML_ASSERT(doc["bill-to"]["given"].to<std::string>() == "Chris"); + YAML_ASSERT(doc["bill-to"]["family"].to<std::string>() == "Dumars"); + YAML_ASSERT(doc["bill-to"]["address"].size() == 4); + 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"); + YAML_ASSERT(doc["ship-to"].size() == 3); + YAML_ASSERT(doc["ship-to"]["given"].to<std::string>() == "Chris"); + YAML_ASSERT(doc["ship-to"]["family"].to<std::string>() == "Dumars"); + YAML_ASSERT(doc["ship-to"]["address"].size() == 4); + 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"); + YAML_ASSERT(doc["product"].size() == 2); + YAML_ASSERT(doc["product"][0].size() == 4); + 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"); + YAML_ASSERT(doc["product"][1].size() == 4); + 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."); + return true; + } + + // 2.28 + TEST LogFile() + { + PARSE(doc, ex2_28); + YAML_ASSERT(doc.size() == 3); + 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"); + + PARSE_NEXT(doc); + YAML_ASSERT(doc.size() == 3); + 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."); + + PARSE_NEXT(doc); + YAML_ASSERT(doc.size() == 4); + 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\""); + YAML_ASSERT(doc["Stack"].size() == 2); + YAML_ASSERT(doc["Stack"][0].size() == 3); + 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"); + YAML_ASSERT(doc["Stack"][1].size() == 3); + 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"); + 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<std::string>() == "one"); + YAML_ASSERT(doc["sequence"][1].to<std::string>() == "two"); + YAML_ASSERT(doc["mapping"].size() == 2); + YAML_ASSERT(doc["mapping"]["sky"].to<std::string>() == "blue"); + YAML_ASSERT(doc["mapping"]["sea"].to<std::string>() == "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<std::string>() == "one"); + YAML_ASSERT(doc["sequence"][1].to<std::string>() == "two"); + YAML_ASSERT(doc["mapping"].size() == 2); + YAML_ASSERT(doc["mapping"]["sky"].to<std::string>() == "blue"); + YAML_ASSERT(doc["mapping"]["sea"].to<std::string>() == "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<std::string>() == "value"); // TODO: assert tag + YAML_ASSERT(doc["alias"].to<std::string>() == "value"); + return true; + } + + // 5.7 + TEST BlockScalarIndicators() + { + PARSE(doc, ex5_7); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["literal"].to<std::string>() == "some\ntext\n"); + YAML_ASSERT(doc["folded"].to<std::string>() == "some text\n"); + return true; + } + + // 5.8 + TEST QuotedScalarIndicators() + { + PARSE(doc, ex5_8); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["single"].to<std::string>() == "text"); + YAML_ASSERT(doc["double"].to<std::string>() == "text"); + return true; + } + + // TODO: 5.9 directive + // TODO: 5.10 reserved indicator + + // 5.11 + TEST LineBreakCharacters() + { + PARSE(doc, ex5_11); + YAML_ASSERT(doc.to<std::string>() == "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<std::string>() == "Quoted\t"); + YAML_ASSERT(doc["block"].to<std::string>() == + "void main() {\n" + "\tprintf(\"Hello, world!\\n\");\n" + "}"); + return true; + } + + // 5.13 + TEST EscapedCharacters() + { + PARSE(doc, ex5_13); + 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"); + 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<std::string>() == "By four\n spaces\n"); + YAML_ASSERT(doc["Not indented"]["Flow style"].size() == 3); + 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"); + 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<std::string>() == "b"); + YAML_ASSERT(doc["a"][1].size() == 2); + YAML_ASSERT(doc["a"][1][0].to<std::string>() == "c"); + YAML_ASSERT(doc["a"][1][1].to<std::string>() == "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<std::string>() == "bar"); + YAML_ASSERT(doc[1].size() == 2); + YAML_ASSERT(doc[1][0].to<std::string>() == "baz"); + YAML_ASSERT(doc[1][1].to<std::string>() == "baz"); + return true; + } + + // 6.4 + TEST LinePrefixes() + { + PARSE(doc, ex6_4); + YAML_ASSERT(doc.size() == 3); + 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"); + return true; + } + + // 6.5 + TEST EmptyLines() + { + PARSE(doc, ex6_5); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["Folding"].to<std::string>() == "Empty line\nas a line feed"); + YAML_ASSERT(doc["Chomping"].to<std::string>() == "Clipped empty lines\n"); + return true; + } + + // 6.6 + TEST LineFolding() + { + PARSE(doc, ex6_6); + YAML_ASSERT(doc.to<std::string>() == "trimmed\n\n\nas space"); + return true; + } + + // 6.7 + TEST BlockFolding() + { + PARSE(doc, ex6_7); + YAML_ASSERT(doc.to<std::string>() == "foo \n\n\t bar\n\nbaz\n"); + return true; + } + + // 6.8 + TEST FlowFolding() + { + PARSE(doc, ex6_8); + YAML_ASSERT(doc.to<std::string>() == " foo\nbar\nbaz "); + return true; + } + + // 6.9 + TEST SeparatedComment() + { + PARSE(doc, ex6_9); + YAML_ASSERT(doc.size() == 1); + YAML_ASSERT(doc["key"].to<std::string>() == "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<std::string>() == "value"); + 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) { + std::string key = it.first().to<std::string>(); + std::string value = it.second().to<std::string>(); + m._[key] = value; + } + } + + + // 6.12 + TEST SeparationSpacesII() + { + PARSE(doc, ex6_12); + std::map<std::string, std::string> key; + key["first"] = "Sammy"; + key["last"] = "Sosa"; + YAML_ASSERT(doc.size() == 1); + YAML_ASSERT(doc[key].size() == 2); + YAML_ASSERT(doc[key]["hr"].to<int>() == 65); + YAML_ASSERT(doc[key]["avg"].to<std::string>() == "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<std::string>() == "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<std::string>() == "bar"); + + PARSE_NEXT(doc); + YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo"); + YAML_ASSERT(doc.to<std::string>() == "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<std::string>() == "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<std::string>() == "bar"); + return true; + } + + // 6.21 + TEST LocalTagPrefix() + { + PARSE(doc, ex6_21); + YAML_ASSERT(doc.Tag() == "!my-light"); + YAML_ASSERT(doc.to<std::string>() == "fluorescent"); + + PARSE_NEXT(doc); + YAML_ASSERT(doc.Tag() == "!my-light"); + YAML_ASSERT(doc.to<std::string>() == "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<std::string>() == "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<std::string>() == "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<std::string>() == "bar"); + } else if(it.first().to<std::string>() == "baz") { + YAML_ASSERT(it.second().to<std::string>() == "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<std::string>() == "foo"); + YAML_ASSERT(it.second().Tag() == "!bar"); + YAML_ASSERT(it.second().to<std::string>() == "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<std::string>() == "foo"); + YAML_ASSERT(doc[1].Tag() == "tag:yaml.org,2002:str"); + YAML_ASSERT(doc[1].to<std::string>() == "bar"); + YAML_ASSERT(doc[2].Tag() == "tag:example.com,2000:app/tag%21"); + YAML_ASSERT(doc[2].to<std::string>() == "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<std::string>() == "12"); // TODO: check tags. How? + YAML_ASSERT(doc[1].to<int>() == 12); + YAML_ASSERT(doc[2].to<std::string>() == "12"); + return true; + } + + // 6.29 + TEST NodeAnchors() + { + PARSE(doc, ex6_29); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["First occurrence"].to<std::string>() == "Value"); + YAML_ASSERT(doc["Second occurrence"].to<std::string>() == "Value"); + return true; + } + + // 7.1 + TEST AliasNodes() + { + PARSE(doc, ex7_1); + YAML_ASSERT(doc.size() == 4); + 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"); + 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<std::string>() == "foo") { + YAML_ASSERT(it.second().Tag() == "tag:yaml.org,2002:str"); + YAML_ASSERT(it.second().to<std::string>() == ""); + } else if(it.first().to<std::string>() == "") { + YAML_ASSERT(it.first().Tag() == "tag:yaml.org,2002:str"); + YAML_ASSERT(it.second().to<std::string>() == "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<std::string>() == "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<std::string>() == "value"); + return true; + } + + // 7.5 + TEST DoubleQuotedLineBreaks() + { + PARSE(doc, ex7_5); + YAML_ASSERT(doc.to<std::string>() == "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<std::string>() == " 1st non-empty\n2nd non-empty 3rd non-empty "); + return true; + } + + // 7.7 + TEST SingleQuotedCharacters() + { + PARSE(doc, ex7_7); + YAML_ASSERT(doc.to<std::string>() == "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<std::string>() == "value"); + return true; + } + + // 7.9 + TEST SingleQuotedLines() + { + PARSE(doc, ex7_9); + YAML_ASSERT(doc.to<std::string>() == " 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<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"); + YAML_ASSERT(doc[5].size() == 5); + 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"); + 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<std::string>() == "value"); + return true; + } + + // 7.12 + TEST PlainLines() + { + PARSE(doc, ex7_12); + YAML_ASSERT(doc.to<std::string>() == "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<std::string>() == "one"); + YAML_ASSERT(doc[0][1].to<std::string>() == "two"); + YAML_ASSERT(doc[1].size() == 2); + YAML_ASSERT(doc[1][0].to<std::string>() == "three"); + YAML_ASSERT(doc[1][1].to<std::string>() == "four"); + return true; + } + + // 7.14 + TEST FlowSequenceEntries() + { + PARSE(doc, ex7_14); + YAML_ASSERT(doc.size() == 5); + 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"); + YAML_ASSERT(doc[3].size() == 1); + YAML_ASSERT(doc[3][0].to<std::string>() == "nested"); + YAML_ASSERT(doc[4].size() == 1); + YAML_ASSERT(doc[4]["single"].to<std::string>() == "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<std::string>() == "two"); + YAML_ASSERT(doc[0]["three"].to<std::string>() == "four"); + YAML_ASSERT(doc[1].size() == 2); + YAML_ASSERT(doc[1]["five"].to<std::string>() == "six"); + YAML_ASSERT(doc[1]["seven"].to<std::string>() == "eight"); + return true; + } + + // 7.16 + TEST FlowMappingEntries() + { + PARSE(doc, ex7_16); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc["explicit"].to<std::string>() == "entry"); + YAML_ASSERT(doc["implicit"].to<std::string>() == "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<std::string>() == "separate"); + YAML_ASSERT(IsNull(doc["http://foo.com"])); + YAML_ASSERT(IsNull(doc["omitted value"])); + YAML_ASSERT(doc[YAML::Null].to<std::string>() == "omitted key"); + return true; + } + + // 7.18 + TEST FlowMappingAdjacentValues() + { + PARSE(doc, ex7_18); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc["adjacent"].to<std::string>() == "value"); + YAML_ASSERT(doc["readable"].to<std::string>() == "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<std::string>() == "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<std::string>() == "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<std::string>() == "separate"); + YAML_ASSERT(doc[1].size() == 1); + YAML_ASSERT(doc[1][0].size() == 1); + YAML_ASSERT(doc[1][0][YAML::Null].to<std::string>() == "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<std::string>() == "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<std::string>() == "a"); + YAML_ASSERT(doc[0][1].to<std::string>() == "b"); + YAML_ASSERT(doc[1].size() == 1); + 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"); + 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<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"); + YAML_ASSERT(doc[4].Tag() == "tag:yaml.org,2002:str"); + YAML_ASSERT(doc[4].to<std::string>() == ""); + return true; + } + + // 8.1 + TEST BlockScalarHeader() + { + PARSE(doc, ex8_1); + YAML_ASSERT(doc.size() == 4); + 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"); + return true; + } + + // 8.2 + TEST BlockIndentationHeader() + { + PARSE(doc, ex8_2); + YAML_ASSERT(doc.size() == 4); + 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"); + 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<std::string>() == "text"); + YAML_ASSERT(doc["clip"].to<std::string>() == "text\n"); + YAML_ASSERT(doc["keep"].to<std::string>() == "text\n"); + return true; + } + + // 8.5 + TEST ChompingTrailingLines() + { + PARSE(doc, ex8_5); + YAML_ASSERT(doc.size() == 3); + 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"); // 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<std::string>() == ""); + YAML_ASSERT(doc["clip"].to<std::string>() == ""); + YAML_ASSERT(doc["keep"].to<std::string>() == "\n"); + return true; + } + + // 8.7 + TEST LiteralScalar() + { + PARSE(doc, ex8_7); + YAML_ASSERT(doc.to<std::string>() == "literal\n\ttext\n"); + return true; + } + + // 8.8 + TEST LiteralContent() + { + PARSE(doc, ex8_8); + YAML_ASSERT(doc.to<std::string>() == "\n\nliteral\n \n\ntext\n"); + return true; + } + + // 8.9 + TEST FoldedScalar() + { + PARSE(doc, ex8_9); + YAML_ASSERT(doc.to<std::string>() == "folded text\n"); + return true; + } + + // 8.10 + TEST FoldedLines() + { + PARSE(doc, ex8_10); + YAML_ASSERT(doc.to<std::string>() == "\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<std::string>() == "one"); + YAML_ASSERT(doc["block sequence"][1].size() == 1); + YAML_ASSERT(doc["block sequence"][1]["two"].to<std::string>() == "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<std::string>() == "block node\n"); + YAML_ASSERT(doc[2].size() == 2); + YAML_ASSERT(doc[2][0].to<std::string>() == "one"); + YAML_ASSERT(doc[2][1].to<std::string>() == "two"); + YAML_ASSERT(doc[3].size() == 1); + YAML_ASSERT(doc[3]["one"].to<std::string>() == "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<std::string>() == "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<std::string>() == "one"); + YAML_ASSERT(doc["block key\n"][1].to<std::string>() == "two"); + return true; + } + + // 8.18 + TEST ImplicitBlockMappingEntries() + { + PARSE(doc, ex8_18); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc["plain key"].to<std::string>() == "in-line value"); + YAML_ASSERT(IsNull(doc[YAML::Null])); + YAML_ASSERT(doc["quoted key"].size() == 1); + YAML_ASSERT(doc["quoted key"][0].to<std::string>() == "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<std::string>() == "yellow"); + YAML_ASSERT(doc[1].size() == 1); + std::map<std::string, std::string> key; + key["earth"] = "blue"; + YAML_ASSERT(doc[1][key].size() == 1); + YAML_ASSERT(doc[1][key]["moon"].to<std::string>() == "white"); + return true; + } + + // 8.20 + TEST BlockNodeTypes() + { + PARSE(doc, ex8_20); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc[0].to<std::string>() == "flow in block"); + YAML_ASSERT(doc[1].to<std::string>() == "Block scalar\n"); + YAML_ASSERT(doc[2].size() == 1); + YAML_ASSERT(doc[2]["foo"].to<std::string>() == "bar"); + return true; + } + + // 8.21 + TEST BlockScalarNodes() + { + PARSE(doc, ex8_21); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["literal"].to<std::string>() == "value"); // Note: I believe this is a bug in the YAML spec - it should be "value\n" + YAML_ASSERT(doc["folded"].to<std::string>() == "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<std::string>() == "entry"); + YAML_ASSERT(doc["sequence"][1].size() == 1); + YAML_ASSERT(doc["sequence"][1][0].to<std::string>() == "nested"); + YAML_ASSERT(doc["mapping"].size() == 1); + YAML_ASSERT(doc["mapping"]["foo"].to<std::string>() == "bar"); + return true; + } + } +} |