Add flow/block style setting on Nodes

This commit is contained in:
Jesse Beder
2015-01-24 13:11:43 -06:00
parent 9880b608b9
commit 0c280724e9
13 changed files with 252 additions and 84 deletions

View File

@@ -7,6 +7,7 @@
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/type.h" #include "yaml-cpp/node/type.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
@@ -28,6 +29,7 @@ class node : private boost::noncopyable {
const std::string& scalar() const { return m_pRef->scalar(); } const std::string& scalar() const { return m_pRef->scalar(); }
const std::string& tag() const { return m_pRef->tag(); } const std::string& tag() const { return m_pRef->tag(); }
EmitterStyle::value style() const { return m_pRef->style(); }
void mark_defined() { void mark_defined() {
if (is_defined()) if (is_defined())
@@ -76,6 +78,12 @@ class node : private boost::noncopyable {
m_pRef->set_tag(tag); m_pRef->set_tag(tag);
} }
// style
void set_style(EmitterStyle::value style) {
mark_defined();
m_pRef->set_style(style);
}
// size/iterator // size/iterator
std::size_t size() const { return m_pRef->size(); } std::size_t size() const { return m_pRef->size(); }

View File

@@ -38,6 +38,7 @@ class YAML_CPP_API node_data : private boost::noncopyable {
void set_tag(const std::string& tag); void set_tag(const std::string& tag);
void set_null(); void set_null();
void set_scalar(const std::string& scalar); void set_scalar(const std::string& scalar);
void set_style(EmitterStyle::value style);
bool is_defined() const { return m_isDefined; } bool is_defined() const { return m_isDefined; }
NodeType::value type() const { NodeType::value type() const {
@@ -45,6 +46,7 @@ class YAML_CPP_API node_data : private boost::noncopyable {
} }
const std::string& scalar() const { return m_scalar; } const std::string& scalar() const { return m_scalar; }
const std::string& tag() const { return m_tag; } const std::string& tag() const { return m_tag; }
EmitterStyle::value style() const { return m_style; }
// size/iterator // size/iterator
std::size_t size() const; std::size_t size() const;
@@ -101,6 +103,7 @@ class YAML_CPP_API node_data : private boost::noncopyable {
bool m_isDefined; bool m_isDefined;
NodeType::value m_type; NodeType::value m_type;
std::string m_tag; std::string m_tag;
EmitterStyle::value m_style;
// scalar // scalar
std::string m_scalar; std::string m_scalar;

View File

@@ -23,6 +23,7 @@ class node_ref : private boost::noncopyable {
NodeType::value type() const { return m_pData->type(); } NodeType::value type() const { return m_pData->type(); }
const std::string& scalar() const { return m_pData->scalar(); } const std::string& scalar() const { return m_pData->scalar(); }
const std::string& tag() const { return m_pData->tag(); } const std::string& tag() const { return m_pData->tag(); }
EmitterStyle::value style() const { return m_pData->style(); }
void mark_defined() { m_pData->mark_defined(); } void mark_defined() { m_pData->mark_defined(); }
void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; } void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; }
@@ -31,6 +32,7 @@ class node_ref : private boost::noncopyable {
void set_tag(const std::string& tag) { m_pData->set_tag(tag); } void set_tag(const std::string& tag) { m_pData->set_tag(tag); }
void set_null() { m_pData->set_null(); } void set_null() { m_pData->set_null(); }
void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); } void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); }
void set_style(EmitterStyle::value style) { m_pData->set_style(style); }
// size/iterator // size/iterator
std::size_t size() const { return m_pData->size(); } std::size_t size() const { return m_pData->size(); }

View File

@@ -164,6 +164,19 @@ inline void Node::SetTag(const std::string& tag) {
m_pNode->set_tag(tag); m_pNode->set_tag(tag);
} }
inline EmitterStyle::value Node::Style() const {
if (!m_isValid)
throw InvalidNode();
return m_pNode ? m_pNode->style() : EmitterStyle::Default;
}
inline void Node::SetStyle(EmitterStyle::value style) {
if (!m_isValid)
throw InvalidNode();
EnsureNodeExists();
m_pNode->set_style(style);
}
// assignment // assignment
inline bool Node::is(const Node& rhs) const { inline bool Node::is(const Node& rhs) const {
if (!m_isValid || !rhs.m_isValid) if (!m_isValid || !rhs.m_isValid)

View File

@@ -10,6 +10,7 @@
#include <stdexcept> #include <stdexcept>
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/node/detail/bool_type.h" #include "yaml-cpp/node/detail/bool_type.h"
#include "yaml-cpp/node/detail/iterator_fwd.h" #include "yaml-cpp/node/detail/iterator_fwd.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
@@ -63,9 +64,15 @@ class YAML_CPP_API Node {
template <typename T, typename S> template <typename T, typename S>
const T as(const S& fallback) const; const T as(const S& fallback) const;
const std::string& Scalar() const; const std::string& Scalar() const;
const std::string& Tag() const; const std::string& Tag() const;
void SetTag(const std::string& tag); void SetTag(const std::string& tag);
// style
// WARNING: This API might change in future releases.
EmitterStyle::value Style() const;
void SetStyle(EmitterStyle::value style);
// assignment // assignment
bool is(const Node& rhs) const; bool is(const Node& rhs) const;
template <typename T> template <typename T>

View File

@@ -51,7 +51,9 @@ bool convert<bool>::decode(const Node& node, bool& rhs) {
// http://yaml.org/type/bool.html) // http://yaml.org/type/bool.html)
static const struct { static const struct {
std::string truename, falsename; std::string truename, falsename;
} names[] = {{"y", "n"}, {"yes", "no"}, {"true", "false"}, {"on", "off"}, }; } names[] = {
{"y", "n"}, {"yes", "no"}, {"true", "false"}, {"on", "off"},
};
if (!IsFlexibleCase(node.Scalar())) if (!IsFlexibleCase(node.Scalar()))
return false; return false;

View File

@@ -16,7 +16,10 @@ namespace detail {
std::string node_data::empty_scalar; std::string node_data::empty_scalar;
node_data::node_data() node_data::node_data()
: m_isDefined(false), m_type(NodeType::Null), m_seqSize(0) {} : m_isDefined(false),
m_type(NodeType::Null),
m_seqSize(0),
m_style(EmitterStyle::Default) {}
void node_data::mark_defined() { void node_data::mark_defined() {
if (m_type == NodeType::Undefined) if (m_type == NodeType::Undefined)
@@ -57,6 +60,8 @@ void node_data::set_type(NodeType::value type) {
void node_data::set_tag(const std::string& tag) { m_tag = tag; } void node_data::set_tag(const std::string& tag) { m_tag = tag; }
void node_data::set_style(EmitterStyle::value style) { m_style = style; }
void node_data::set_null() { void node_data::set_null() {
m_isDefined = true; m_isDefined = true;
m_type = NodeType::Null; m_type = NodeType::Null;

View File

@@ -54,6 +54,7 @@ void NodeBuilder::OnSequenceStart(const Mark& /* mark */,
detail::node& node = Push(anchor); detail::node& node = Push(anchor);
node.set_tag(tag); node.set_tag(tag);
node.set_type(NodeType::Sequence); node.set_type(NodeType::Sequence);
node.set_style(style);
} }
void NodeBuilder::OnSequenceEnd() { Pop(); } void NodeBuilder::OnSequenceEnd() { Pop(); }
@@ -63,6 +64,7 @@ void NodeBuilder::OnMapStart(const Mark& /* mark */, const std::string& tag,
detail::node& node = Push(anchor); detail::node& node = Push(anchor);
node.set_type(NodeType::Map); node.set_type(NodeType::Map);
node.set_tag(tag); node.set_tag(tag);
node.set_style(style);
m_mapDepth++; m_mapDepth++;
} }

View File

@@ -76,15 +76,14 @@ void NodeEvents::Emit(const detail::node& node, EventHandler& handler,
handler.OnScalar(Mark(), node.tag(), anchor, node.scalar()); handler.OnScalar(Mark(), node.tag(), anchor, node.scalar());
break; break;
case NodeType::Sequence: case NodeType::Sequence:
handler.OnSequenceStart(Mark(), node.tag(), anchor, handler.OnSequenceStart(Mark(), node.tag(), anchor, node.style());
EmitterStyle::Default);
for (detail::const_node_iterator it = node.begin(); it != node.end(); for (detail::const_node_iterator it = node.begin(); it != node.end();
++it) ++it)
Emit(**it, handler, am); Emit(**it, handler, am);
handler.OnSequenceEnd(); handler.OnSequenceEnd();
break; break;
case NodeType::Map: case NodeType::Map:
handler.OnMapStart(Mark(), node.tag(), anchor, EmitterStyle::Default); handler.OnMapStart(Mark(), node.tag(), anchor, node.style());
for (detail::const_node_iterator it = node.begin(); it != node.end(); for (detail::const_node_iterator it = node.begin(); it != node.end();
++it) { ++it) {
Emit(*it->first, handler, am); Emit(*it->first, handler, am);

View File

@@ -5,12 +5,12 @@
namespace YAML { namespace YAML {
namespace { namespace {
TEST(LoadNodeTest, Reassign) { TEST(LoadNodeTest, Reassign) {
YAML::Node node = YAML::Load("foo"); Node node = Load("foo");
node = YAML::Node(); node = Node();
} }
TEST(LoadNodeTest, FallbackValues) { TEST(LoadNodeTest, FallbackValues) {
YAML::Node node = YAML::Load("foo: bar\nx: 2"); Node node = Load("foo: bar\nx: 2");
EXPECT_EQ("bar", node["foo"].as<std::string>()); EXPECT_EQ("bar", node["foo"].as<std::string>());
EXPECT_EQ("bar", node["foo"].as<std::string>("hello")); EXPECT_EQ("bar", node["foo"].as<std::string>("hello"));
EXPECT_EQ("hello", node["baz"].as<std::string>("hello")); EXPECT_EQ("hello", node["baz"].as<std::string>("hello"));
@@ -20,10 +20,10 @@ TEST(LoadNodeTest, FallbackValues) {
} }
TEST(LoadNodeTest, NumericConversion) { TEST(LoadNodeTest, NumericConversion) {
YAML::Node node = YAML::Load("[1.5, 1, .nan, .inf, -.inf, 0x15, 015]"); Node node = Load("[1.5, 1, .nan, .inf, -.inf, 0x15, 015]");
EXPECT_EQ(1.5f, node[0].as<float>()); EXPECT_EQ(1.5f, node[0].as<float>());
EXPECT_EQ(1.5, node[0].as<double>()); EXPECT_EQ(1.5, node[0].as<double>());
EXPECT_THROW(node[0].as<int>(), YAML::TypedBadConversion<int>); EXPECT_THROW(node[0].as<int>(), TypedBadConversion<int>);
EXPECT_EQ(1, node[1].as<int>()); EXPECT_EQ(1, node[1].as<int>());
EXPECT_EQ(1.0f, node[1].as<float>()); EXPECT_EQ(1.0f, node[1].as<float>());
EXPECT_NE(node[2].as<float>(), node[2].as<float>()); EXPECT_NE(node[2].as<float>(), node[2].as<float>());
@@ -34,7 +34,7 @@ TEST(LoadNodeTest, NumericConversion) {
} }
TEST(LoadNodeTest, Binary) { TEST(LoadNodeTest, Binary) {
YAML::Node node = YAML::Load( Node node = Load(
"[!!binary \"SGVsbG8sIFdvcmxkIQ==\", !!binary " "[!!binary \"SGVsbG8sIFdvcmxkIQ==\", !!binary "
"\"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieS" "\"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieS"
"B0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIG" "B0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIG"
@@ -42,10 +42,9 @@ TEST(LoadNodeTest, Binary) {
"B0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZG" "B0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZG"
"dlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS" "dlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS"
"4K\"]"); "4K\"]");
EXPECT_EQ( EXPECT_EQ(Binary(reinterpret_cast<const unsigned char*>("Hello, World!"), 13),
YAML::Binary(reinterpret_cast<const unsigned char*>("Hello, World!"), 13), node[0].as<Binary>());
node[0].as<YAML::Binary>()); EXPECT_EQ(Binary(reinterpret_cast<const unsigned char*>(
EXPECT_EQ(YAML::Binary(reinterpret_cast<const unsigned char*>(
"Man is distinguished, not only by his reason, " "Man is distinguished, not only by his reason, "
"but by this singular passion from other " "but by this singular passion from other "
"animals, which is a lust of the mind, that by " "animals, which is a lust of the mind, that by "
@@ -53,14 +52,14 @@ TEST(LoadNodeTest, Binary) {
"indefatigable generation of knowledge, exceeds " "indefatigable generation of knowledge, exceeds "
"the short vehemence of any carnal pleasure.\n"), "the short vehemence of any carnal pleasure.\n"),
270), 270),
node[1].as<YAML::Binary>()); node[1].as<Binary>());
} }
TEST(LoadNodeTest, IterateSequence) { TEST(LoadNodeTest, IterateSequence) {
YAML::Node node = YAML::Load("[1, 3, 5, 7]"); Node node = Load("[1, 3, 5, 7]");
int seq[] = {1, 3, 5, 7}; int seq[] = {1, 3, 5, 7};
int i = 0; int i = 0;
for (YAML::const_iterator it = node.begin(); it != node.end(); ++it) { for (const_iterator it = node.begin(); it != node.end(); ++it) {
EXPECT_TRUE(i < 4); EXPECT_TRUE(i < 4);
int x = seq[i++]; int x = seq[i++];
EXPECT_EQ(x, it->as<int>()); EXPECT_EQ(x, it->as<int>());
@@ -69,9 +68,9 @@ TEST(LoadNodeTest, IterateSequence) {
} }
TEST(LoadNodeTest, IterateMap) { TEST(LoadNodeTest, IterateMap) {
YAML::Node node = YAML::Load("{a: A, b: B, c: C}"); Node node = Load("{a: A, b: B, c: C}");
int i = 0; int i = 0;
for (YAML::const_iterator it = node.begin(); it != node.end(); ++it) { for (const_iterator it = node.begin(); it != node.end(); ++it) {
EXPECT_TRUE(i < 3); EXPECT_TRUE(i < 3);
i++; i++;
EXPECT_EQ(it->second.as<char>(), it->first.as<char>() + 'A' - 'a'); EXPECT_EQ(it->second.as<char>(), it->first.as<char>() + 'A' - 'a');
@@ -81,36 +80,36 @@ TEST(LoadNodeTest, IterateMap) {
#ifdef BOOST_FOREACH #ifdef BOOST_FOREACH
TEST(LoadNodeTest, ForEach) { TEST(LoadNodeTest, ForEach) {
YAML::Node node = YAML::Load("[1, 3, 5, 7]"); Node node = Load("[1, 3, 5, 7]");
int seq[] = {1, 3, 5, 7}; int seq[] = {1, 3, 5, 7};
int i = 0; int i = 0;
BOOST_FOREACH(const YAML::Node & item, node) { BOOST_FOREACH (const Node& item, node) {
int x = seq[i++]; int x = seq[i++];
EXPECT_EQ(x, item.as<int>()); EXPECT_EQ(x, item.as<int>());
} }
} }
TEST(LoadNodeTest, ForEachMap) { TEST(LoadNodeTest, ForEachMap) {
YAML::Node node = YAML::Load("{a: A, b: B, c: C}"); Node node = Load("{a: A, b: B, c: C}");
BOOST_FOREACH(const YAML::const_iterator::value_type & p, node) { BOOST_FOREACH (const const_iterator::value_type& p, node) {
EXPECT_EQ(p.second.as<char>(), p.first.as<char>() + 'A' - 'a'); EXPECT_EQ(p.second.as<char>(), p.first.as<char>() + 'A' - 'a');
} }
} }
#endif #endif
TEST(LoadNodeTest, CloneScalar) { TEST(LoadNodeTest, CloneScalar) {
YAML::Node node = YAML::Load("!foo monkey"); Node node = Load("!foo monkey");
YAML::Node clone = Clone(node); Node clone = Clone(node);
EXPECT_FALSE(clone == node); EXPECT_FALSE(clone == node);
EXPECT_EQ(clone.as<std::string>(), node.as<std::string>()); EXPECT_EQ(clone.as<std::string>(), node.as<std::string>());
EXPECT_EQ(clone.Tag(), node.Tag()); EXPECT_EQ(clone.Tag(), node.Tag());
} }
TEST(LoadNodeTest, CloneSeq) { TEST(LoadNodeTest, CloneSeq) {
YAML::Node node = YAML::Load("[1, 3, 5, 7]"); Node node = Load("[1, 3, 5, 7]");
YAML::Node clone = Clone(node); Node clone = Clone(node);
EXPECT_FALSE(clone == node); EXPECT_FALSE(clone == node);
EXPECT_EQ(YAML::NodeType::Sequence, clone.Type()); EXPECT_EQ(NodeType::Sequence, clone.Type());
EXPECT_EQ(clone.size(), node.size()); EXPECT_EQ(clone.size(), node.size());
for (std::size_t i = 0; i < node.size(); i++) { for (std::size_t i = 0; i < node.size(); i++) {
EXPECT_EQ(clone[i].as<int>(), node[i].as<int>()); EXPECT_EQ(clone[i].as<int>(), node[i].as<int>());
@@ -118,34 +117,34 @@ TEST(LoadNodeTest, CloneSeq) {
} }
TEST(LoadNodeTest, CloneMap) { TEST(LoadNodeTest, CloneMap) {
YAML::Node node = YAML::Load("{foo: bar}"); Node node = Load("{foo: bar}");
YAML::Node clone = Clone(node); Node clone = Clone(node);
EXPECT_FALSE(clone == node); EXPECT_FALSE(clone == node);
EXPECT_EQ(YAML::NodeType::Map, clone.Type()); EXPECT_EQ(NodeType::Map, clone.Type());
EXPECT_EQ(clone.size(), node.size()); EXPECT_EQ(clone.size(), node.size());
EXPECT_EQ(clone["foo"].as<std::string>(), node["foo"].as<std::string>()); EXPECT_EQ(clone["foo"].as<std::string>(), node["foo"].as<std::string>());
} }
TEST(LoadNodeTest, CloneAlias) { TEST(LoadNodeTest, CloneAlias) {
YAML::Node node = YAML::Load("&foo [*foo]"); Node node = Load("&foo [*foo]");
YAML::Node clone = Clone(node); Node clone = Clone(node);
EXPECT_FALSE(clone == node); EXPECT_FALSE(clone == node);
EXPECT_EQ(YAML::NodeType::Sequence, clone.Type()); EXPECT_EQ(NodeType::Sequence, clone.Type());
EXPECT_EQ(clone.size(), node.size()); EXPECT_EQ(clone.size(), node.size());
EXPECT_EQ(clone[0], clone); EXPECT_EQ(clone[0], clone);
} }
TEST(LoadNodeTest, ForceInsertIntoMap) { TEST(LoadNodeTest, ForceInsertIntoMap) {
YAML::Node node; Node node;
node["a"] = "b"; node["a"] = "b";
node.force_insert("x", "y"); node.force_insert("x", "y");
node.force_insert("a", 5); node.force_insert("a", 5);
EXPECT_EQ(3, node.size()); EXPECT_EQ(3, node.size());
EXPECT_EQ(YAML::NodeType::Map, node.Type()); EXPECT_EQ(NodeType::Map, node.Type());
bool ab = false; bool ab = false;
bool a5 = false; bool a5 = false;
bool xy = false; bool xy = false;
for (YAML::const_iterator it = node.begin(); it != node.end(); ++it) { for (const_iterator it = node.begin(); it != node.end(); ++it) {
if (it->first.as<std::string>() == "a") { if (it->first.as<std::string>() == "a") {
if (it->second.as<std::string>() == "b") if (it->second.as<std::string>() == "b")
ab = true; ab = true;
@@ -161,9 +160,9 @@ TEST(LoadNodeTest, ForceInsertIntoMap) {
} }
TEST(LoadNodeTest, ResetNode) { TEST(LoadNodeTest, ResetNode) {
YAML::Node node = YAML::Load("[1, 2, 3]"); Node node = Load("[1, 2, 3]");
EXPECT_TRUE(!node.IsNull()); EXPECT_TRUE(!node.IsNull());
YAML::Node other = node; Node other = node;
node.reset(); node.reset();
EXPECT_TRUE(node.IsNull()); EXPECT_TRUE(node.IsNull());
EXPECT_TRUE(!other.IsNull()); EXPECT_TRUE(!other.IsNull());
@@ -173,19 +172,26 @@ TEST(LoadNodeTest, ResetNode) {
} }
TEST(LoadNodeTest, DereferenceIteratorError) { TEST(LoadNodeTest, DereferenceIteratorError) {
YAML::Node node = YAML::Load("[{a: b}, 1, 2]"); Node node = Load("[{a: b}, 1, 2]");
EXPECT_THROW(node.begin()->first.as<int>(), YAML::InvalidNode); EXPECT_THROW(node.begin()->first.as<int>(), InvalidNode);
EXPECT_EQ(true, (*node.begin()).IsMap()); EXPECT_EQ(true, (*node.begin()).IsMap());
EXPECT_EQ(true, node.begin()->IsMap()); EXPECT_EQ(true, node.begin()->IsMap());
EXPECT_THROW((*node.begin()->begin()).IsDefined(), YAML::InvalidNode); EXPECT_THROW((*node.begin()->begin()).IsDefined(), InvalidNode);
EXPECT_THROW(node.begin()->begin()->IsDefined(), YAML::InvalidNode); EXPECT_THROW(node.begin()->begin()->IsDefined(), InvalidNode);
} }
TEST(NodeTest, EmitEmptyNode) { TEST(NodeTest, EmitEmptyNode) {
YAML::Node node; Node node;
YAML::Emitter emitter; Emitter emitter;
emitter << node; emitter << node;
EXPECT_EQ("", std::string(emitter.c_str())); 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());
}
} }
} }

View File

@@ -7,8 +7,7 @@
ASSERT_THROW(statement, ParserException); \ ASSERT_THROW(statement, ParserException); \
try { \ try { \
statement; \ statement; \
} \ } catch (const ParserException& e) { \
catch (const ParserException& e) { \
EXPECT_EQ(e.msg, message); \ EXPECT_EQ(e.msg, message); \
} }

View File

@@ -1,3 +1,5 @@
#include "yaml-cpp/emitter.h"
#include "yaml-cpp/node/emit.h"
#include "yaml-cpp/node/node.h" #include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/impl.h" #include "yaml-cpp/node/impl.h"
#include "yaml-cpp/node/convert.h" #include "yaml-cpp/node/convert.h"
@@ -9,19 +11,19 @@
namespace YAML { namespace YAML {
namespace { namespace {
TEST(NodeTest, SimpleScalar) { TEST(NodeTest, SimpleScalar) {
YAML::Node node = YAML::Node("Hello, World!"); Node node = Node("Hello, World!");
EXPECT_TRUE(node.IsScalar()); EXPECT_TRUE(node.IsScalar());
EXPECT_EQ("Hello, World!", node.as<std::string>()); EXPECT_EQ("Hello, World!", node.as<std::string>());
} }
TEST(NodeTest, IntScalar) { TEST(NodeTest, IntScalar) {
YAML::Node node = YAML::Node(15); Node node = Node(15);
EXPECT_TRUE(node.IsScalar()); EXPECT_TRUE(node.IsScalar());
EXPECT_EQ(15, node.as<int>()); EXPECT_EQ(15, node.as<int>());
} }
TEST(NodeTest, SimpleAppendSequence) { TEST(NodeTest, SimpleAppendSequence) {
YAML::Node node; Node node;
node.push_back(10); node.push_back(10);
node.push_back("foo"); node.push_back("foo");
node.push_back("monkey"); node.push_back("monkey");
@@ -34,7 +36,7 @@ TEST(NodeTest, SimpleAppendSequence) {
} }
TEST(NodeTest, SimpleAssignSequence) { TEST(NodeTest, SimpleAssignSequence) {
YAML::Node node; Node node;
node[0] = 10; node[0] = 10;
node[1] = "foo"; node[1] = "foo";
node[2] = "monkey"; node[2] = "monkey";
@@ -47,7 +49,7 @@ TEST(NodeTest, SimpleAssignSequence) {
} }
TEST(NodeTest, SimpleMap) { TEST(NodeTest, SimpleMap) {
YAML::Node node; Node node;
node["key"] = "value"; node["key"] = "value";
EXPECT_TRUE(node.IsMap()); EXPECT_TRUE(node.IsMap());
EXPECT_EQ("value", node["key"].as<std::string>()); EXPECT_EQ("value", node["key"].as<std::string>());
@@ -55,7 +57,7 @@ TEST(NodeTest, SimpleMap) {
} }
TEST(NodeTest, MapWithUndefinedValues) { TEST(NodeTest, MapWithUndefinedValues) {
YAML::Node node; Node node;
node["key"] = "value"; node["key"] = "value";
node["undefined"]; node["undefined"];
EXPECT_TRUE(node.IsMap()); EXPECT_TRUE(node.IsMap());
@@ -68,7 +70,7 @@ TEST(NodeTest, MapWithUndefinedValues) {
} }
TEST(NodeTest, MapIteratorWithUndefinedValues) { TEST(NodeTest, MapIteratorWithUndefinedValues) {
YAML::Node node; Node node;
node["key"] = "value"; node["key"] = "value";
node["undefined"]; node["undefined"];
@@ -79,7 +81,7 @@ TEST(NodeTest, MapIteratorWithUndefinedValues) {
} }
TEST(NodeTest, SimpleSubkeys) { TEST(NodeTest, SimpleSubkeys) {
YAML::Node node; Node node;
node["device"]["udid"] = "12345"; node["device"]["udid"] = "12345";
node["device"]["name"] = "iPhone"; node["device"]["name"] = "iPhone";
node["device"]["os"] = "4.0"; node["device"]["os"] = "4.0";
@@ -99,7 +101,7 @@ TEST(NodeTest, StdVector) {
primes.push_back(11); primes.push_back(11);
primes.push_back(13); primes.push_back(13);
YAML::Node node; Node node;
node["primes"] = primes; node["primes"] = primes;
EXPECT_EQ(primes, node["primes"].as<std::vector<int> >()); EXPECT_EQ(primes, node["primes"].as<std::vector<int> >());
} }
@@ -113,7 +115,7 @@ TEST(NodeTest, StdList) {
primes.push_back(11); primes.push_back(11);
primes.push_back(13); primes.push_back(13);
YAML::Node node; Node node;
node["primes"] = primes; node["primes"] = primes;
EXPECT_EQ(primes, node["primes"].as<std::list<int> >()); EXPECT_EQ(primes, node["primes"].as<std::list<int> >());
} }
@@ -126,7 +128,7 @@ TEST(NodeTest, StdMap) {
squares[3] = 9; squares[3] = 9;
squares[4] = 16; squares[4] = 16;
YAML::Node node; Node node;
node["squares"] = squares; node["squares"] = squares;
std::map<int, int> actualSquares = node["squares"].as<std::map<int, int> >(); std::map<int, int> actualSquares = node["squares"].as<std::map<int, int> >();
EXPECT_EQ(squares, actualSquares); EXPECT_EQ(squares, actualSquares);
@@ -137,7 +139,7 @@ TEST(NodeTest, StdPair) {
p.first = 5; p.first = 5;
p.second = "five"; p.second = "five";
YAML::Node node; Node node;
node["pair"] = p; node["pair"] = p;
std::pair<int, std::string> actualP = std::pair<int, std::string> actualP =
node["pair"].as<std::pair<int, std::string> >(); node["pair"].as<std::pair<int, std::string> >();
@@ -145,7 +147,7 @@ TEST(NodeTest, StdPair) {
} }
TEST(NodeTest, SimpleAlias) { TEST(NodeTest, SimpleAlias) {
YAML::Node node; Node node;
node["foo"] = "value"; node["foo"] = "value";
node["bar"] = node["foo"]; node["bar"] = node["foo"];
EXPECT_EQ("value", node["foo"].as<std::string>()); EXPECT_EQ("value", node["foo"].as<std::string>());
@@ -155,9 +157,9 @@ TEST(NodeTest, SimpleAlias) {
} }
TEST(NodeTest, AliasAsKey) { TEST(NodeTest, AliasAsKey) {
YAML::Node node; Node node;
node["foo"] = "value"; node["foo"] = "value";
YAML::Node value = node["foo"]; Node value = node["foo"];
node[value] = "foo"; node[value] = "foo";
EXPECT_EQ("value", node["foo"].as<std::string>()); EXPECT_EQ("value", node["foo"].as<std::string>());
EXPECT_EQ("foo", node[value].as<std::string>()); EXPECT_EQ("foo", node[value].as<std::string>());
@@ -166,7 +168,7 @@ TEST(NodeTest, AliasAsKey) {
} }
TEST(NodeTest, SelfReferenceSequence) { TEST(NodeTest, SelfReferenceSequence) {
YAML::Node node; Node node;
node[0] = node; node[0] = node;
EXPECT_TRUE(node.IsSequence()); EXPECT_TRUE(node.IsSequence());
EXPECT_EQ(1, node.size()); EXPECT_EQ(1, node.size());
@@ -176,7 +178,7 @@ TEST(NodeTest, SelfReferenceSequence) {
} }
TEST(NodeTest, ValueSelfReferenceMap) { TEST(NodeTest, ValueSelfReferenceMap) {
YAML::Node node; Node node;
node["key"] = node; node["key"] = node;
EXPECT_TRUE(node.IsMap()); EXPECT_TRUE(node.IsMap());
EXPECT_EQ(1, node.size()); EXPECT_EQ(1, node.size());
@@ -186,7 +188,7 @@ TEST(NodeTest, ValueSelfReferenceMap) {
} }
TEST(NodeTest, KeySelfReferenceMap) { TEST(NodeTest, KeySelfReferenceMap) {
YAML::Node node; Node node;
node[node] = "value"; node[node] = "value";
EXPECT_TRUE(node.IsMap()); EXPECT_TRUE(node.IsMap());
EXPECT_EQ(1, node.size()); EXPECT_EQ(1, node.size());
@@ -194,7 +196,7 @@ TEST(NodeTest, KeySelfReferenceMap) {
} }
TEST(NodeTest, SelfReferenceMap) { TEST(NodeTest, SelfReferenceMap) {
YAML::Node node; Node node;
node[node] = node; node[node] = node;
EXPECT_TRUE(node.IsMap()); EXPECT_TRUE(node.IsMap());
EXPECT_EQ(1, node.size()); EXPECT_EQ(1, node.size());
@@ -204,8 +206,8 @@ TEST(NodeTest, SelfReferenceMap) {
} }
TEST(NodeTest, TempMapVariable) { TEST(NodeTest, TempMapVariable) {
YAML::Node node; Node node;
YAML::Node tmp = node["key"]; Node tmp = node["key"];
tmp = "value"; tmp = "value";
EXPECT_TRUE(node.IsMap()); EXPECT_TRUE(node.IsMap());
EXPECT_EQ(1, node.size()); EXPECT_EQ(1, node.size());
@@ -213,8 +215,8 @@ TEST(NodeTest, TempMapVariable) {
} }
TEST(NodeTest, TempMapVariableAlias) { TEST(NodeTest, TempMapVariableAlias) {
YAML::Node node; Node node;
YAML::Node tmp = node["key"]; Node tmp = node["key"];
tmp = node["other"]; tmp = node["other"];
node["other"] = "value"; node["other"] = "value";
EXPECT_TRUE(node.IsMap()); EXPECT_TRUE(node.IsMap());
@@ -225,7 +227,7 @@ TEST(NodeTest, TempMapVariableAlias) {
} }
TEST(NodeTest, Bool) { TEST(NodeTest, Bool) {
YAML::Node node; Node node;
node[true] = false; node[true] = false;
EXPECT_TRUE(node.IsMap()); EXPECT_TRUE(node.IsMap());
EXPECT_EQ(false, node[true].as<bool>()); EXPECT_EQ(false, node[true].as<bool>());
@@ -235,7 +237,7 @@ TEST(NodeTest, AutoBoolConversion) {
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(disable : 4800) #pragma warning(disable : 4800)
#endif #endif
YAML::Node node; Node node;
node["foo"] = "bar"; node["foo"] = "bar";
EXPECT_TRUE(static_cast<bool>(node["foo"])); EXPECT_TRUE(static_cast<bool>(node["foo"]));
EXPECT_TRUE(!node["monkey"]); EXPECT_TRUE(!node["monkey"]);
@@ -244,12 +246,12 @@ TEST(NodeTest, AutoBoolConversion) {
TEST(NodeTest, FloatingPrecision) { TEST(NodeTest, FloatingPrecision) {
const double x = 0.123456789; const double x = 0.123456789;
YAML::Node node = YAML::Node(x); Node node = Node(x);
EXPECT_EQ(x, node.as<double>()); EXPECT_EQ(x, node.as<double>());
} }
TEST(NodeTest, SpaceChar) { TEST(NodeTest, SpaceChar) {
YAML::Node node = YAML::Node(' '); Node node = Node(' ');
EXPECT_EQ(' ', node.as<char>()); EXPECT_EQ(' ', node.as<char>());
} }
@@ -258,5 +260,126 @@ TEST(NodeTest, CloneNull) {
Node clone = Clone(node); Node clone = Clone(node);
EXPECT_EQ(NodeType::Null, clone.Type()); EXPECT_EQ(NodeType::Null, clone.Type());
} }
TEST(NodeTest, DefaultNodeStyle) {
Node node;
EXPECT_EQ(EmitterStyle::Default, node.Style());
}
class NodeEmitterTest : public ::testing::Test {
protected:
void ExpectOutput(const std::string& output, const Node& node) {
Emitter emitter;
emitter << node;
ASSERT_TRUE(emitter.good());
EXPECT_EQ(output, emitter.c_str());
}
};
TEST_F(NodeEmitterTest, SimpleFlowSeqNode) {
Node node;
node.SetStyle(EmitterStyle::Flow);
node.push_back(1.01);
node.push_back(2.01);
node.push_back(3.01);
ExpectOutput("[1.01, 2.01, 3.01]", node);
}
TEST_F(NodeEmitterTest, NestFlowSeqNode) {
Node node, cell0, cell1;
cell0.push_back(1.01);
cell0.push_back(2.01);
cell0.push_back(3.01);
cell1.push_back(4.01);
cell1.push_back(5.01);
cell1.push_back(6.01);
node.SetStyle(EmitterStyle::Flow);
node.push_back(cell0);
node.push_back(cell1);
ExpectOutput("[[1.01, 2.01, 3.01], [4.01, 5.01, 6.01]]", node);
}
TEST_F(NodeEmitterTest, MixBlockFlowSeqNode) {
Node node, cell0, cell1;
cell0.SetStyle(EmitterStyle::Flow);
cell0.push_back(1.01);
cell0.push_back(2.01);
cell0.push_back(3.01);
cell1.push_back(4.01);
cell1.push_back(5.01);
cell1.push_back(6.01);
node.SetStyle(EmitterStyle::Block);
node.push_back(cell0);
node.push_back(cell1);
ExpectOutput("- [1.01, 2.01, 3.01]\n-\n - 4.01\n - 5.01\n - 6.01", node);
}
TEST_F(NodeEmitterTest, NestBlockFlowMapListNode) {
Node node, mapNode, blockNode;
node.push_back(1.01);
node.push_back(2.01);
node.push_back(3.01);
mapNode.SetStyle(EmitterStyle::Flow);
mapNode["position"] = node;
blockNode.push_back(1.01);
blockNode.push_back(mapNode);
ExpectOutput("- 1.01\n- {position: [1.01, 2.01, 3.01]}", blockNode);
}
TEST_F(NodeEmitterTest, NestBlockMixMapListNode) {
Node node, mapNode, blockNode;
node.push_back(1.01);
node.push_back(2.01);
node.push_back(3.01);
mapNode.SetStyle(EmitterStyle::Flow);
mapNode["position"] = node;
blockNode["scalar"] = 1.01;
blockNode["object"] = mapNode;
ExpectOutput("scalar: 1.01\nobject: {position: [1.01, 2.01, 3.01]}",
blockNode);
}
TEST_F(NodeEmitterTest, NestBlockMapListNode) {
Node node, mapNode;
node.push_back(1.01);
node.push_back(2.01);
node.push_back(3.01);
mapNode.SetStyle(EmitterStyle::Block);
mapNode["position"] = node;
ExpectOutput("position:\n - 1.01\n - 2.01\n - 3.01", mapNode);
}
TEST_F(NodeEmitterTest, NestFlowMapListNode) {
Node node, mapNode;
node.push_back(1.01);
node.push_back(2.01);
node.push_back(3.01);
mapNode.SetStyle(EmitterStyle::Flow);
mapNode["position"] = node;
ExpectOutput("{position: [1.01, 2.01, 3.01]}", mapNode);
}
} }
} }

View File

@@ -41,8 +41,7 @@ void parse(std::istream& input) {
try { try {
YAML::Node doc = YAML::Load(input); YAML::Node doc = YAML::Load(input);
std::cout << doc << "\n"; std::cout << doc << "\n";
} } catch (const YAML::Exception& e) {
catch (const YAML::Exception& e) {
std::cerr << e.what() << "\n"; std::cerr << e.what() << "\n";
} }
} }