- initial import
This commit is contained in:
1690
test/integration/emitter_test.cpp
Normal file
1690
test/integration/emitter_test.cpp
Normal file
File diff suppressed because it is too large
Load Diff
182
test/integration/encoding_test.cpp
Normal file
182
test/integration/encoding_test.cpp
Normal file
@@ -0,0 +1,182 @@
|
||||
#include <sstream>
|
||||
|
||||
#include "handler_test.h"
|
||||
#include "yaml-cpp/yaml.h" // IWYU pragma: keep
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::InSequence;
|
||||
|
||||
namespace YAML {
|
||||
namespace {
|
||||
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 EncodingTest : public HandlerTest {
|
||||
protected:
|
||||
void SetUpEncoding(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);
|
||||
}
|
||||
|
||||
void Run() {
|
||||
InSequence sequence;
|
||||
EXPECT_CALL(handler, OnDocumentStart(_));
|
||||
EXPECT_CALL(handler, OnSequenceStart(_, "?", 0, EmitterStyle::Block));
|
||||
for (std::size_t i = 0; i < m_entries.size(); i++) {
|
||||
EXPECT_CALL(handler, OnScalar(_, "!", 0, m_entries[i]));
|
||||
}
|
||||
EXPECT_CALL(handler, OnSequenceEnd());
|
||||
EXPECT_CALL(handler, OnDocumentEnd());
|
||||
|
||||
Parse(m_yaml.str());
|
||||
}
|
||||
|
||||
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');
|
||||
EncodeToUtf8(entry, '\n');
|
||||
|
||||
m_entries.push_back(entry.str());
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(EncodingTest, UTF8_noBOM) {
|
||||
SetUpEncoding(&EncodeToUtf8, false);
|
||||
Run();
|
||||
}
|
||||
|
||||
TEST_F(EncodingTest, UTF8_BOM) {
|
||||
SetUpEncoding(&EncodeToUtf8, true);
|
||||
Run();
|
||||
}
|
||||
|
||||
TEST_F(EncodingTest, UTF16LE_noBOM) {
|
||||
SetUpEncoding(&EncodeToUtf16LE, false);
|
||||
Run();
|
||||
}
|
||||
|
||||
TEST_F(EncodingTest, UTF16LE_BOM) {
|
||||
SetUpEncoding(&EncodeToUtf16LE, true);
|
||||
Run();
|
||||
}
|
||||
|
||||
TEST_F(EncodingTest, UTF16BE_noBOM) {
|
||||
SetUpEncoding(&EncodeToUtf16BE, false);
|
||||
Run();
|
||||
}
|
||||
|
||||
TEST_F(EncodingTest, UTF16BE_BOM) {
|
||||
SetUpEncoding(&EncodeToUtf16BE, true);
|
||||
Run();
|
||||
}
|
||||
|
||||
TEST_F(EncodingTest, UTF32LE_noBOM) {
|
||||
SetUpEncoding(&EncodeToUtf32LE, false);
|
||||
Run();
|
||||
}
|
||||
|
||||
TEST_F(EncodingTest, UTF32LE_BOM) {
|
||||
SetUpEncoding(&EncodeToUtf32LE, true);
|
||||
Run();
|
||||
}
|
||||
|
||||
TEST_F(EncodingTest, UTF32BE_noBOM) {
|
||||
SetUpEncoding(&EncodeToUtf32BE, false);
|
||||
Run();
|
||||
}
|
||||
|
||||
TEST_F(EncodingTest, UTF32BE_BOM) {
|
||||
SetUpEncoding(&EncodeToUtf32BE, true);
|
||||
Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
61
test/integration/error_messages_test.cpp
Normal file
61
test/integration/error_messages_test.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "yaml-cpp/yaml.h" // IWYU pragma: keep
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#define EXPECT_THROW_EXCEPTION(exception_type, statement, message) \
|
||||
ASSERT_THROW(statement, exception_type); \
|
||||
try { \
|
||||
statement; \
|
||||
} catch (const exception_type& e) { \
|
||||
EXPECT_EQ(e.msg, message); \
|
||||
}
|
||||
|
||||
namespace YAML {
|
||||
namespace {
|
||||
|
||||
TEST(ErrorMessageTest, BadSubscriptErrorMessage) {
|
||||
const char *example_yaml = "first:\n"
|
||||
" second: 1\n"
|
||||
" third: 2\n";
|
||||
|
||||
Node doc = Load(example_yaml);
|
||||
|
||||
// Test that printable key is part of error message
|
||||
EXPECT_THROW_EXCEPTION(YAML::BadSubscript, doc["first"]["second"]["fourth"],
|
||||
"operator[] call on a scalar (key: \"fourth\")");
|
||||
|
||||
EXPECT_THROW_EXCEPTION(YAML::BadSubscript, doc["first"]["second"][37],
|
||||
"operator[] call on a scalar (key: \"37\")");
|
||||
|
||||
|
||||
// Non-printable key is not included in error message
|
||||
EXPECT_THROW_EXCEPTION(YAML::BadSubscript,
|
||||
doc["first"]["second"][std::vector<int>()],
|
||||
"operator[] call on a scalar");
|
||||
|
||||
EXPECT_THROW_EXCEPTION(YAML::BadSubscript, doc["first"]["second"][Node()],
|
||||
"operator[] call on a scalar");
|
||||
}
|
||||
|
||||
TEST(ErrorMessageTest, Ex9_1_InvalidNodeErrorMessage) {
|
||||
const char *example_yaml = "first:\n"
|
||||
" second: 1\n"
|
||||
" third: 2\n";
|
||||
|
||||
const Node doc = Load(example_yaml);
|
||||
|
||||
// Test that printable key is part of error message
|
||||
EXPECT_THROW_EXCEPTION(YAML::InvalidNode, doc["first"]["fourth"].as<int>(),
|
||||
"invalid node; first invalid key: \"fourth\"");
|
||||
|
||||
EXPECT_THROW_EXCEPTION(YAML::InvalidNode, doc["first"][37].as<int>(),
|
||||
"invalid node; first invalid key: \"37\"");
|
||||
|
||||
// Non-printable key is not included in error message
|
||||
EXPECT_THROW_EXCEPTION(YAML::InvalidNode,
|
||||
doc["first"][std::vector<int>()].as<int>(),
|
||||
"invalid node; this may result from using a map "
|
||||
"iterator as a sequence iterator, or vice-versa");
|
||||
}
|
||||
}
|
||||
}
|
||||
9936
test/integration/gen_emitter_test.cpp
Normal file
9936
test/integration/gen_emitter_test.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1686
test/integration/handler_spec_test.cpp
Normal file
1686
test/integration/handler_spec_test.cpp
Normal file
File diff suppressed because it is too large
Load Diff
76
test/integration/handler_test.cpp
Normal file
76
test/integration/handler_test.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#include "handler_test.h"
|
||||
#include "specexamples.h" // IWYU pragma: keep
|
||||
#include "yaml-cpp/yaml.h" // IWYU pragma: keep
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using ::testing::_;
|
||||
|
||||
#define EXPECT_THROW_PARSER_EXCEPTION(statement, message) \
|
||||
ASSERT_THROW(statement, ParserException); \
|
||||
try { \
|
||||
statement; \
|
||||
} catch (const ParserException& e) { \
|
||||
EXPECT_EQ(e.msg, message); \
|
||||
}
|
||||
|
||||
namespace YAML {
|
||||
namespace {
|
||||
|
||||
TEST_F(HandlerTest, NoEndOfMapFlow) {
|
||||
EXPECT_THROW_PARSER_EXCEPTION(IgnoreParse("---{header: {id: 1"),
|
||||
ErrorMsg::END_OF_MAP_FLOW);
|
||||
}
|
||||
|
||||
TEST_F(HandlerTest, PlainScalarStartingWithQuestionMark) {
|
||||
EXPECT_CALL(handler, OnDocumentStart(_));
|
||||
EXPECT_CALL(handler, OnMapStart(_, "?", 0, EmitterStyle::Block));
|
||||
EXPECT_CALL(handler, OnScalar(_, "?", 0, "foo"));
|
||||
EXPECT_CALL(handler, OnScalar(_, "?", 0, "?bar"));
|
||||
EXPECT_CALL(handler, OnMapEnd());
|
||||
EXPECT_CALL(handler, OnDocumentEnd());
|
||||
Parse("foo: ?bar");
|
||||
}
|
||||
|
||||
TEST_F(HandlerTest, NullStringScalar) {
|
||||
EXPECT_CALL(handler, OnDocumentStart(_));
|
||||
EXPECT_CALL(handler, OnMapStart(_, "?", 0, EmitterStyle::Block));
|
||||
EXPECT_CALL(handler, OnScalar(_, "?", 0, "foo"));
|
||||
EXPECT_CALL(handler, OnNull(_, 0));
|
||||
EXPECT_CALL(handler, OnMapEnd());
|
||||
EXPECT_CALL(handler, OnDocumentEnd());
|
||||
Parse("foo: null");
|
||||
}
|
||||
|
||||
TEST_F(HandlerTest, CommentOnNewlineOfMapValueWithNoSpaces) {
|
||||
EXPECT_CALL(handler, OnDocumentStart(_));
|
||||
EXPECT_CALL(handler, OnMapStart(_, "?", 0, EmitterStyle::Block));
|
||||
EXPECT_CALL(handler, OnScalar(_, "?", 0, "key"));
|
||||
EXPECT_CALL(handler, OnScalar(_, "?", 0, "value"));
|
||||
EXPECT_CALL(handler, OnMapEnd());
|
||||
EXPECT_CALL(handler, OnDocumentEnd());
|
||||
Parse("key: value\n# comment");
|
||||
}
|
||||
|
||||
TEST_F(HandlerTest, CommentOnNewlineOfMapValueWithOneSpace) {
|
||||
EXPECT_CALL(handler, OnDocumentStart(_));
|
||||
EXPECT_CALL(handler, OnMapStart(_, "?", 0, EmitterStyle::Block));
|
||||
EXPECT_CALL(handler, OnScalar(_, "?", 0, "key"));
|
||||
EXPECT_CALL(handler, OnScalar(_, "?", 0, "value"));
|
||||
EXPECT_CALL(handler, OnMapEnd());
|
||||
EXPECT_CALL(handler, OnDocumentEnd());
|
||||
Parse("key: value\n # comment");
|
||||
}
|
||||
|
||||
TEST_F(HandlerTest, CommentOnNewlineOfMapValueWithManySpace) {
|
||||
EXPECT_CALL(handler, OnDocumentStart(_));
|
||||
EXPECT_CALL(handler, OnMapStart(_, "?", 0, EmitterStyle::Block));
|
||||
EXPECT_CALL(handler, OnScalar(_, "?", 0, "key"));
|
||||
EXPECT_CALL(handler, OnScalar(_, "?", 0, "value"));
|
||||
EXPECT_CALL(handler, OnMapEnd());
|
||||
EXPECT_CALL(handler, OnDocumentEnd());
|
||||
Parse("key: value\n # comment");
|
||||
}
|
||||
} // namespace
|
||||
} // namespace YAML
|
||||
349
test/integration/load_node_test.cpp
Normal file
349
test/integration/load_node_test.cpp
Normal file
@@ -0,0 +1,349 @@
|
||||
#include "yaml-cpp/yaml.h" // IWYU pragma: keep
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace YAML {
|
||||
namespace {
|
||||
TEST(LoadNodeTest, Reassign) {
|
||||
Node node = Load("foo");
|
||||
node = Node();
|
||||
EXPECT_TRUE(node.IsNull());
|
||||
}
|
||||
|
||||
TEST(LoadNodeTest, FallbackValues) {
|
||||
Node node = Load("foo: bar\nx: 2");
|
||||
EXPECT_EQ("bar", node["foo"].as<std::string>());
|
||||
EXPECT_EQ("bar", node["foo"].as<std::string>("hello"));
|
||||
EXPECT_EQ("hello", node["baz"].as<std::string>("hello"));
|
||||
EXPECT_EQ(2, node["x"].as<int>());
|
||||
EXPECT_EQ(2, node["x"].as<int>(5));
|
||||
EXPECT_EQ(5, node["y"].as<int>(5));
|
||||
}
|
||||
|
||||
TEST(LoadNodeTest, NumericConversion) {
|
||||
EXPECT_EQ(1.5f, Load("1.5").as<float>());
|
||||
EXPECT_EQ(1.5, Load("1.5").as<double>());
|
||||
EXPECT_THROW(Load("1.5").as<int>(), TypedBadConversion<int>);
|
||||
EXPECT_EQ(1, Load("1").as<int>());
|
||||
EXPECT_EQ(1.0f, Load("1").as<float>());
|
||||
EXPECT_NE(Load(".nan").as<float>(), Load(".nan").as<float>());
|
||||
EXPECT_EQ(std::numeric_limits<float>::infinity(), Load(".inf").as<float>());
|
||||
EXPECT_EQ(-std::numeric_limits<float>::infinity(), Load("-.inf").as<float>());
|
||||
EXPECT_EQ(21, Load("0x15").as<int>());
|
||||
EXPECT_EQ(13, Load("015").as<int>());
|
||||
EXPECT_EQ(-128, +Load("-128").as<int8_t>());
|
||||
EXPECT_EQ(127, +Load("127").as<int8_t>());
|
||||
EXPECT_THROW(Load("128").as<int8_t>(), TypedBadConversion<signed char>);
|
||||
EXPECT_EQ(255, +Load("255").as<uint8_t>());
|
||||
EXPECT_THROW(Load("256").as<uint8_t>(), TypedBadConversion<unsigned char>);
|
||||
// test as<char>/as<uint8_t> with ‘a’,"ab",'1',"127"
|
||||
EXPECT_EQ('a', Load("a").as<char>());
|
||||
EXPECT_THROW(Load("ab").as<char>(), TypedBadConversion<char>);
|
||||
EXPECT_EQ('1', Load("1").as<char>());
|
||||
EXPECT_THROW(Load("127").as<char>(), TypedBadConversion<char>);
|
||||
EXPECT_THROW(Load("a").as<uint8_t>(), TypedBadConversion<unsigned char>);
|
||||
EXPECT_THROW(Load("ab").as<uint8_t>(), TypedBadConversion<unsigned char>);
|
||||
EXPECT_EQ(1, +Load("1").as<uint8_t>());
|
||||
// Throw exception: convert a negative number to an unsigned number.
|
||||
EXPECT_THROW(Load("-128").as<unsigned>(), TypedBadConversion<unsigned int>);
|
||||
EXPECT_THROW(Load("-128").as<unsigned short>(), TypedBadConversion<unsigned short>);
|
||||
EXPECT_THROW(Load("-128").as<unsigned long>(), TypedBadConversion<unsigned long>);
|
||||
EXPECT_THROW(Load("-128").as<unsigned long long>(), TypedBadConversion<unsigned long long>);
|
||||
EXPECT_THROW(Load("-128").as<uint8_t>(), TypedBadConversion<unsigned char>);
|
||||
}
|
||||
|
||||
TEST(LoadNodeTest, Binary) {
|
||||
Node node = Load(
|
||||
"[!!binary \"SGVsbG8sIFdvcmxkIQ==\", !!binary "
|
||||
"\"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieS"
|
||||
"B0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIG"
|
||||
"x1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbi"
|
||||
"B0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZG"
|
||||
"dlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS"
|
||||
"4K\"]");
|
||||
EXPECT_EQ(Binary(reinterpret_cast<const unsigned char*>("Hello, World!"), 13),
|
||||
node[0].as<Binary>());
|
||||
EXPECT_EQ(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),
|
||||
node[1].as<Binary>());
|
||||
}
|
||||
|
||||
TEST(LoadNodeTest, BinaryWithWhitespaces) {
|
||||
Node node = Load(
|
||||
"binaryText: !binary |-\n"
|
||||
" TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieS\n"
|
||||
" B0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIG\n"
|
||||
" x1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbi\n"
|
||||
" B0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZG\n"
|
||||
" dlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS\n"
|
||||
" 4K");
|
||||
EXPECT_EQ(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),
|
||||
node["binaryText"].as<Binary>());
|
||||
}
|
||||
|
||||
TEST(LoadNodeTest, IterateSequence) {
|
||||
Node node = Load("[1, 3, 5, 7]");
|
||||
int seq[] = {1, 3, 5, 7};
|
||||
int i = 0;
|
||||
for (const_iterator it = node.begin(); it != node.end(); ++it) {
|
||||
EXPECT_TRUE(i < 4);
|
||||
int x = seq[i++];
|
||||
EXPECT_EQ(x, it->as<int>());
|
||||
}
|
||||
EXPECT_EQ(4, i);
|
||||
}
|
||||
|
||||
TEST(LoadNodeTest, IterateMap) {
|
||||
Node node = Load("{a: A, b: B, c: C}");
|
||||
int i = 0;
|
||||
for (const_iterator it = node.begin(); it != node.end(); ++it) {
|
||||
EXPECT_TRUE(i < 3);
|
||||
i++;
|
||||
EXPECT_EQ(it->second.as<char>(), it->first.as<char>() + 'A' - 'a');
|
||||
}
|
||||
EXPECT_EQ(3, i);
|
||||
}
|
||||
|
||||
#ifdef BOOST_FOREACH
|
||||
TEST(LoadNodeTest, ForEach) {
|
||||
Node node = Load("[1, 3, 5, 7]");
|
||||
int seq[] = {1, 3, 5, 7};
|
||||
int i = 0;
|
||||
BOOST_FOREACH (const Node& item, node) {
|
||||
int x = seq[i++];
|
||||
EXPECT_EQ(x, item.as<int>());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(LoadNodeTest, ForEachMap) {
|
||||
Node node = Load("{a: A, b: B, c: C}");
|
||||
BOOST_FOREACH (const const_iterator::value_type& p, node) {
|
||||
EXPECT_EQ(p.second.as<char>(), p.first.as<char>() + 'A' - 'a');
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(LoadNodeTest, CloneScalar) {
|
||||
Node node = Load("!foo monkey");
|
||||
Node clone = Clone(node);
|
||||
EXPECT_FALSE(clone == node);
|
||||
EXPECT_EQ(clone.as<std::string>(), node.as<std::string>());
|
||||
EXPECT_EQ(clone.Tag(), node.Tag());
|
||||
}
|
||||
|
||||
TEST(LoadNodeTest, CloneSeq) {
|
||||
Node node = Load("[1, 3, 5, 7]");
|
||||
Node clone = Clone(node);
|
||||
EXPECT_FALSE(clone == node);
|
||||
EXPECT_EQ(NodeType::Sequence, clone.Type());
|
||||
EXPECT_EQ(clone.size(), node.size());
|
||||
for (std::size_t i = 0; i < node.size(); i++) {
|
||||
EXPECT_EQ(clone[i].as<int>(), node[i].as<int>());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(LoadNodeTest, CloneMap) {
|
||||
Node node = Load("{foo: bar}");
|
||||
Node clone = Clone(node);
|
||||
EXPECT_FALSE(clone == node);
|
||||
EXPECT_EQ(NodeType::Map, clone.Type());
|
||||
EXPECT_EQ(clone.size(), node.size());
|
||||
EXPECT_EQ(clone["foo"].as<std::string>(), node["foo"].as<std::string>());
|
||||
}
|
||||
|
||||
TEST(LoadNodeTest, CloneAlias) {
|
||||
Node node = Load("&foo [*foo]");
|
||||
Node clone = Clone(node);
|
||||
EXPECT_FALSE(clone == node);
|
||||
EXPECT_EQ(NodeType::Sequence, clone.Type());
|
||||
EXPECT_EQ(clone.size(), node.size());
|
||||
EXPECT_EQ(clone[0], clone);
|
||||
}
|
||||
|
||||
TEST(LoadNodeTest, ForceInsertIntoMap) {
|
||||
Node node;
|
||||
node["a"] = "b";
|
||||
node.force_insert("x", "y");
|
||||
node.force_insert("a", 5);
|
||||
EXPECT_EQ(3, node.size());
|
||||
EXPECT_EQ(NodeType::Map, node.Type());
|
||||
bool ab = false;
|
||||
bool a5 = false;
|
||||
bool xy = false;
|
||||
for (const_iterator it = node.begin(); it != node.end(); ++it) {
|
||||
if (it->first.as<std::string>() == "a") {
|
||||
if (it->second.as<std::string>() == "b")
|
||||
ab = true;
|
||||
else if (it->second.as<std::string>() == "5")
|
||||
a5 = true;
|
||||
} else if (it->first.as<std::string>() == "x" &&
|
||||
it->second.as<std::string>() == "y")
|
||||
xy = true;
|
||||
}
|
||||
EXPECT_TRUE(ab);
|
||||
EXPECT_TRUE(a5);
|
||||
EXPECT_TRUE(xy);
|
||||
}
|
||||
|
||||
TEST(LoadNodeTest, ResetNode) {
|
||||
Node node = Load("[1, 2, 3]");
|
||||
EXPECT_TRUE(!node.IsNull());
|
||||
Node other = node;
|
||||
node.reset();
|
||||
EXPECT_TRUE(node.IsNull());
|
||||
EXPECT_TRUE(!other.IsNull());
|
||||
node.reset(other);
|
||||
EXPECT_TRUE(!node.IsNull());
|
||||
EXPECT_EQ(node, other);
|
||||
}
|
||||
|
||||
TEST(LoadNodeTest, EmptyString) {
|
||||
Node node = Load("\"\"");
|
||||
EXPECT_TRUE(!node.IsNull());
|
||||
}
|
||||
|
||||
TEST(LoadNodeTest, DereferenceIteratorError) {
|
||||
Node node = Load("[{a: b}, 1, 2]");
|
||||
EXPECT_THROW(node.begin()->first.as<int>(), InvalidNode);
|
||||
EXPECT_EQ(true, (*node.begin()).IsMap());
|
||||
EXPECT_EQ(true, node.begin()->IsMap());
|
||||
EXPECT_THROW((*node.begin()->begin()).Type(), InvalidNode);
|
||||
EXPECT_THROW(node.begin()->begin()->Type(), InvalidNode);
|
||||
}
|
||||
|
||||
TEST(NodeTest, EmitEmptyNode) {
|
||||
Node node;
|
||||
Emitter emitter;
|
||||
emitter << node;
|
||||
EXPECT_EQ("", std::string(emitter.c_str()));
|
||||
}
|
||||
|
||||
TEST(NodeTest, ParseNodeStyle) {
|
||||
EXPECT_EQ(EmitterStyle::Flow, Load("[1, 2, 3]").Style());
|
||||
EXPECT_EQ(EmitterStyle::Flow, Load("{foo: bar}").Style());
|
||||
EXPECT_EQ(EmitterStyle::Block, Load("- foo\n- bar").Style());
|
||||
EXPECT_EQ(EmitterStyle::Block, Load("foo: bar").Style());
|
||||
}
|
||||
|
||||
struct ParserExceptionTestCase {
|
||||
std::string name;
|
||||
std::string input;
|
||||
std::string expected_exception;
|
||||
};
|
||||
|
||||
TEST(NodeTest, IncompleteJson) {
|
||||
std::vector<ParserExceptionTestCase> tests = {
|
||||
{"JSON map without value", "{\"access\"", ErrorMsg::END_OF_MAP_FLOW},
|
||||
{"JSON map with colon but no value", "{\"access\":",
|
||||
ErrorMsg::END_OF_MAP_FLOW},
|
||||
{"JSON map with unclosed value quote", "{\"access\":\"",
|
||||
ErrorMsg::END_OF_MAP_FLOW},
|
||||
{"JSON map without end brace", "{\"access\":\"abc\"",
|
||||
ErrorMsg::END_OF_MAP_FLOW},
|
||||
};
|
||||
for (const ParserExceptionTestCase& test : tests) {
|
||||
try {
|
||||
Load(test.input);
|
||||
FAIL() << "Expected exception " << test.expected_exception << " for "
|
||||
<< test.name << ", input: " << test.input;
|
||||
} catch (const ParserException& e) {
|
||||
EXPECT_EQ(test.expected_exception, e.msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SingleNodeTestCase {
|
||||
std::string input;
|
||||
NodeType::value nodeType;
|
||||
int nodeSize;
|
||||
std::string expected_content;
|
||||
};
|
||||
|
||||
TEST(NodeTest, SpecialFlow) {
|
||||
std::vector<SingleNodeTestCase> tests = {
|
||||
{"[:]", NodeType::Sequence, 1, "[{~: ~}]"},
|
||||
{"[a:]", NodeType::Sequence, 1, "[{a: ~}]"},
|
||||
{"[:a]", NodeType::Sequence, 1, "[:a]"},
|
||||
{"[,]", NodeType::Sequence, 1, "[~]"},
|
||||
{"[a:,]", NodeType::Sequence, 1, "[{a: ~}]"},
|
||||
{"{:}", NodeType::Map, 1, "{~: ~}"},
|
||||
{"{a:}", NodeType::Map, 1, "{a: ~}"},
|
||||
{"{:a}", NodeType::Map, 1, "{:a: ~}"},
|
||||
{"{,}", NodeType::Map, 1, "{~: ~}"},
|
||||
{"{a:,}", NodeType::Map, 1, "{a: ~}"},
|
||||
//testcase for the trailing TAB of scalar
|
||||
{"key\t: value\t", NodeType::Map, 1, "key: value"},
|
||||
{"key\t: value\t #comment", NodeType::Map, 1, "key: value"},
|
||||
{"{key\t: value\t}", NodeType::Map, 1, "{key: value}"},
|
||||
{"{key\t: value\t #comment\n}", NodeType::Map, 1, "{key: value}"},
|
||||
};
|
||||
for (const SingleNodeTestCase& test : tests) {
|
||||
Node node = Load(test.input);
|
||||
Emitter emitter;
|
||||
emitter << node;
|
||||
EXPECT_EQ(test.nodeType, node.Type());
|
||||
EXPECT_EQ(test.nodeSize, node.size());
|
||||
EXPECT_EQ(test.expected_content, std::string(emitter.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NodeTest, IncorrectFlow) {
|
||||
std::vector<ParserExceptionTestCase> tests = {
|
||||
{"Incorrect yaml: \"{:]\"", "{:]", ErrorMsg::FLOW_END},
|
||||
{"Incorrect yaml: \"[:}\"", "[:}", ErrorMsg::FLOW_END},
|
||||
};
|
||||
for (const ParserExceptionTestCase test : tests) {
|
||||
try {
|
||||
Load(test.input);
|
||||
FAIL() << "Expected exception " << test.expected_exception << " for "
|
||||
<< test.name << ", input: " << test.input;
|
||||
} catch (const ParserException& e) {
|
||||
EXPECT_EQ(test.expected_exception, e.msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NodeTest, LoadTildeAsNull) {
|
||||
Node node = Load("~");
|
||||
ASSERT_TRUE(node.IsNull());
|
||||
EXPECT_EQ(node.as<std::string>(), "null");
|
||||
EXPECT_EQ(node.as<std::string>("~"), "null");
|
||||
}
|
||||
|
||||
TEST(NodeTest, LoadNullWithStrTag) {
|
||||
Node node = Load("!!str null");
|
||||
EXPECT_EQ(node.Tag(), "tag:yaml.org,2002:str");
|
||||
EXPECT_EQ(node.as<std::string>(), "null");
|
||||
}
|
||||
|
||||
TEST(NodeTest, LoadQuotedNull) {
|
||||
Node node = Load("\"null\"");
|
||||
EXPECT_EQ(node.as<std::string>(), "null");
|
||||
}
|
||||
|
||||
TEST(NodeTest, LoadTagWithParenthesis) {
|
||||
Node node = Load("!Complex(Tag) foo");
|
||||
EXPECT_EQ(node.Tag(), "!Complex(Tag)");
|
||||
EXPECT_EQ(node.as<std::string>(), "foo");
|
||||
}
|
||||
|
||||
TEST(NodeTest, LoadTagWithNullScalar) {
|
||||
Node node = Load("!2");
|
||||
EXPECT_TRUE(node.IsNull());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace YAML
|
||||
1136
test/integration/node_spec_test.cpp
Normal file
1136
test/integration/node_spec_test.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user