Commit c2251264 authored by Jesse Beder's avatar Jesse Beder
Browse files

Copied all files from new-api branch of old repo

parent c8a539f4
#include "yaml-cpp/node/convert.h"
#include "yaml-cpp/node/impl.h"
#include <algorithm>
namespace
{
// we're not gonna mess with the mess that is all the isupper/etc. functions
bool IsLower(char ch) { return 'a' <= ch && ch <= 'z'; }
bool IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; }
char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; }
std::string tolower(const std::string& str)
{
std::string s(str);
std::transform(s.begin(), s.end(), s.begin(), ToLower);
return s;
}
template <typename T>
bool IsEntirely(const std::string& str, T func)
{
for(std::size_t i=0;i<str.size();i++)
if(!func(str[i]))
return false;
return true;
}
// IsFlexibleCase
// . Returns true if 'str' is:
// . UPPERCASE
// . lowercase
// . Capitalized
bool IsFlexibleCase(const std::string& str)
{
if(str.empty())
return true;
if(IsEntirely(str, IsLower))
return true;
bool firstcaps = IsUpper(str[0]);
std::string rest = str.substr(1);
return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper));
}
}
namespace YAML
{
bool convert<bool>::decode(const Node& node, bool& rhs) {
if(!node.IsScalar())
return false;
// we can't use iostream bool extraction operators as they don't
// recognize all possible values in the table below (taken from
// http://yaml.org/type/bool.html)
static const struct {
std::string truename, falsename;
} names[] = {
{ "y", "n" },
{ "yes", "no" },
{ "true", "false" },
{ "on", "off" },
};
if(!IsFlexibleCase(node.Scalar()))
return false;
for(unsigned i=0;i<sizeof(names)/sizeof(names[0]);i++) {
if(names[i].truename == tolower(node.Scalar())) {
rhs = true;
return true;
}
if(names[i].falsename == tolower(node.Scalar())) {
rhs = false;
return true;
}
}
return false;
}
}
#include "yaml-cpp/node/emit.h"
#include "yaml-cpp/emitfromevents.h"
#include "yaml-cpp/emitter.h"
#include "nodeevents.h"
namespace YAML
{
Emitter& operator << (Emitter& out, const Node& node)
{
EmitFromEvents emitFromEvents(out);
NodeEvents events(node);
events.Emit(emitFromEvents);
return out;
}
std::ostream& operator << (std::ostream& out, const Node& node)
{
Emitter emitter;
emitter << node;
out << emitter.c_str();
return out;
}
std::string Dump(const Node& node)
{
Emitter emitter;
emitter << node;
return emitter.c_str();
}
}
#include "yaml-cpp/node/detail/memory.h"
#include "yaml-cpp/node/detail/node.h"
namespace YAML
{
namespace detail
{
void memory_holder::merge(memory_holder& rhs)
{
if(m_pMemory == rhs.m_pMemory)
return;
m_pMemory->merge(*rhs.m_pMemory);
rhs.m_pMemory = m_pMemory;
}
node& memory::create_node()
{
shared_node pNode(new node);
m_nodes.insert(pNode);
return *pNode;
}
void memory::merge(const memory& rhs)
{
m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end());
}
}
}
#include "yaml-cpp/node/detail/node_data.h"
#include "yaml-cpp/node/detail/memory.h"
#include "yaml-cpp/node/detail/node.h"
#include "yaml-cpp/exceptions.h"
#include <sstream>
namespace YAML
{
namespace detail
{
std::string node_data::empty_scalar;
node_data::node_data(): m_isDefined(false), m_type(NodeType::Null), m_seqSize(0)
{
}
void node_data::mark_defined()
{
if(m_type == NodeType::Undefined)
m_type = NodeType::Null;
m_isDefined = true;
}
void node_data::set_type(NodeType::value type)
{
if(type == NodeType::Undefined) {
m_type = type;
m_isDefined = false;
return;
}
m_isDefined = true;
if(type == m_type)
return;
m_type = type;
switch(m_type) {
case NodeType::Null:
break;
case NodeType::Scalar:
m_scalar.clear();
break;
case NodeType::Sequence:
reset_sequence();
break;
case NodeType::Map:
reset_map();
break;
case NodeType::Undefined:
assert(false);
break;
}
}
void node_data::set_tag(const std::string& tag)
{
m_tag = tag;
}
void node_data::set_null()
{
m_isDefined = true;
m_type = NodeType::Null;
}
void node_data::set_scalar(const std::string& scalar)
{
m_isDefined = true;
m_type = NodeType::Scalar;
m_scalar = scalar;
}
// size/iterator
std::size_t node_data::size() const
{
if(!m_isDefined)
return 0;
switch(m_type) {
case NodeType::Sequence: compute_seq_size(); return m_seqSize;
case NodeType::Map: compute_map_size(); return m_map.size() - m_undefinedPairs.size();
default:
return 0;
}
return 0;
}
void node_data::compute_seq_size() const
{
while(m_seqSize < m_sequence.size() && m_sequence[m_seqSize]->is_defined())
m_seqSize++;
}
void node_data::compute_map_size() const
{
kv_pairs::iterator it = m_undefinedPairs.begin();
while(it != m_undefinedPairs.end()) {
kv_pairs::iterator jt = boost::next(it);
if(it->first->is_defined() && it->second->is_defined())
m_undefinedPairs.erase(it);
it = jt;
}
}
const_node_iterator node_data::begin() const
{
if(!m_isDefined)
return const_node_iterator();
switch(m_type) {
case NodeType::Sequence: return const_node_iterator(m_sequence.begin());
case NodeType::Map: return const_node_iterator(m_map.begin(), m_map.end());
default: return const_node_iterator();
}
}
node_iterator node_data::begin()
{
if(!m_isDefined)
return node_iterator();
switch(m_type) {
case NodeType::Sequence: return node_iterator(m_sequence.begin());
case NodeType::Map: return node_iterator(m_map.begin(), m_map.end());
default: return node_iterator();
}
}
const_node_iterator node_data::end() const
{
if(!m_isDefined)
return const_node_iterator();
switch(m_type) {
case NodeType::Sequence: return const_node_iterator(m_sequence.end());
case NodeType::Map: return const_node_iterator(m_map.end(), m_map.end());
default: return const_node_iterator();
}
}
node_iterator node_data::end()
{
if(!m_isDefined)
return node_iterator();
switch(m_type) {
case NodeType::Sequence: return node_iterator(m_sequence.end());
case NodeType::Map: return node_iterator(m_map.end(), m_map.end());
default: return node_iterator();
}
}
// sequence
void node_data::push_back(node& node, shared_memory_holder /* pMemory */)
{
if(m_type == NodeType::Undefined || m_type == NodeType::Null) {
m_type = NodeType::Sequence;
reset_sequence();
}
if(m_type != NodeType::Sequence)
throw BadPushback();
m_sequence.push_back(&node);
}
void node_data::insert(node& key, node& value, shared_memory_holder pMemory)
{
switch(m_type) {
case NodeType::Map:
break;
case NodeType::Undefined:
case NodeType::Null:
case NodeType::Sequence:
convert_to_map(pMemory);
break;
case NodeType::Scalar:
throw BadSubscript();
}
insert_map_pair(key, value);
}
// indexing
node& node_data::get(node& key, shared_memory_holder pMemory) const
{
if(m_type != NodeType::Map)
return pMemory->create_node();
for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
if(it->first->is(key))
return *it->second;
}
return pMemory->create_node();
}
node& node_data::get(node& key, shared_memory_holder pMemory)
{
switch(m_type) {
case NodeType::Map:
break;
case NodeType::Undefined:
case NodeType::Null:
case NodeType::Sequence:
convert_to_map(pMemory);
break;
case NodeType::Scalar:
throw BadSubscript();
}
for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
if(it->first->is(key))
return *it->second;
}
node& value = pMemory->create_node();
insert_map_pair(key, value);
return value;
}
bool node_data::remove(node& key, shared_memory_holder /* pMemory */)
{
if(m_type != NodeType::Map)
return false;
for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) {
if(it->first->is(key)) {
m_map.erase(it);
return true;
}
}
return false;
}
void node_data::reset_sequence()
{
m_sequence.clear();
m_seqSize = 0;
}
void node_data::reset_map()
{
m_map.clear();
m_undefinedPairs.clear();
}
void node_data::insert_map_pair(node& key, node& value)
{
m_map[&key] = &value;
if(!key.is_defined() || !value.is_defined())
m_undefinedPairs.push_back(kv_pair(&key, &value));
}
void node_data::convert_to_map(shared_memory_holder pMemory)
{
switch(m_type) {
case NodeType::Undefined:
case NodeType::Null:
reset_map();
m_type = NodeType::Map;
break;
case NodeType::Sequence:
convert_sequence_to_map(pMemory);
break;
case NodeType::Map:
break;
case NodeType::Scalar:
assert(false);
break;
}
}
void node_data::convert_sequence_to_map(shared_memory_holder pMemory)
{
assert(m_type == NodeType::Sequence);
reset_map();
for(std::size_t i=0;i<m_sequence.size();i++) {
std::stringstream stream;
stream << i;
node& key = pMemory->create_node();
key.set_scalar(stream.str());
insert_map_pair(key, *m_sequence[i]);
}
reset_sequence();
m_type = NodeType::Map;
}
}
}
#include "nodebuilder.h"
#include "yaml-cpp/mark.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/impl.h"
#include <cassert>
namespace YAML
{
NodeBuilder::NodeBuilder(): m_pMemory(new detail::memory_holder), m_pRoot(0), m_mapDepth(0)
{
m_anchors.push_back(0); // since the anchors start at 1
}
NodeBuilder::~NodeBuilder()
{
}
Node NodeBuilder::Root()
{
if(!m_pRoot)
return Node();
return Node(*m_pRoot, m_pMemory);
}
void NodeBuilder::OnDocumentStart(const Mark&)
{
}
void NodeBuilder::OnDocumentEnd()
{
}
void NodeBuilder::OnNull(const Mark& /* mark */, anchor_t anchor)
{
detail::node& node = Push(anchor);
node.set_null();
Pop();
}
void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor)
{
detail::node& node = *m_anchors[anchor];
Push(node);
Pop();
}
void NodeBuilder::OnScalar(const Mark& /* mark */, const std::string& tag, anchor_t anchor, const std::string& value)
{
detail::node& node = Push(anchor);
node.set_scalar(value);
node.set_tag(tag);
Pop();
}
void NodeBuilder::OnSequenceStart(const Mark& /* mark */, const std::string& tag, anchor_t anchor)
{
detail::node& node = Push(anchor);
node.set_tag(tag);
node.set_type(NodeType::Sequence);
}
void NodeBuilder::OnSequenceEnd()
{
Pop();
}
void NodeBuilder::OnMapStart(const Mark& /* mark */, const std::string& tag, anchor_t anchor)
{
detail::node& node = Push(anchor);
node.set_type(NodeType::Map);
node.set_tag(tag);
m_mapDepth++;
}
void NodeBuilder::OnMapEnd()
{
assert(m_mapDepth > 0);
m_mapDepth--;
Pop();
}
detail::node& NodeBuilder::Push(anchor_t anchor)
{
detail::node& node = m_pMemory->create_node();
RegisterAnchor(anchor, node);
Push(node);
return node;
}
void NodeBuilder::Push(detail::node& node)
{
const bool needsKey = (!m_stack.empty() && m_stack.back()->type() == NodeType::Map && m_keys.size() < m_mapDepth);
m_stack.push_back(&node);
if(needsKey)
m_keys.push_back(PushedKey(&node, false));
}
void NodeBuilder::Pop()
{
assert(!m_stack.empty());
if(m_stack.size() == 1) {
m_pRoot = m_stack[0];
m_stack.pop_back();
return;
}
detail::node& node = *m_stack.back();
m_stack.pop_back();
detail::node& collection = *m_stack.back();
if(collection.type() == NodeType::Sequence) {
collection.push_back(node, m_pMemory);
} else if(collection.type() == NodeType::Map) {
assert(!m_keys.empty());
PushedKey& key = m_keys.back();
if(key.second) {
collection.insert(*key.first, node, m_pMemory);
m_keys.pop_back();
} else {
key.second = true;
}
} else {
assert(false);
m_stack.clear();
}
}
void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node)
{
if(anchor) {
assert(anchor == m_anchors.size());
m_anchors.push_back(&node);
}
}
}
#ifndef NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
#include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/node/ptr.h"
#include <vector>
namespace YAML
{
class Node;
class NodeBuilder: public EventHandler
{
public:
NodeBuilder();
virtual ~NodeBuilder();
Node Root();
virtual void OnDocumentStart(const Mark& mark);
virtual void OnDocumentEnd();
virtual void OnNull(const Mark& mark, anchor_t anchor);
virtual void OnAlias(const Mark& mark, anchor_t anchor);
virtual void OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value);
virtual void OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor);
virtual void OnSequenceEnd();
virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor);
virtual void OnMapEnd();
private:
detail::node& Push(anchor_t anchor);
void Push(detail::node& node);
void Pop();
void RegisterAnchor(anchor_t anchor, detail::node& node);
private:
detail::shared_memory_holder m_pMemory;
detail::node *m_pRoot;
typedef std::vector<detail::node *> Nodes;
Nodes m_stack;
Nodes m_anchors;
typedef std::pair<detail::node *, bool> PushedKey;
std::vector<PushedKey> m_keys;
std::size_t m_mapDepth;
};
}
#endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include "nodeevents.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/impl.h"
#include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/mark.h"
namespace YAML
{
void NodeEvents::AliasManager::RegisterReference(const detail::node& node)
{
m_anchorByIdentity.insert(std::make_pair(node.ref(), _CreateNewAnchor()));
}
anchor_t NodeEvents::AliasManager::LookupAnchor(const detail::node& node) const
{
AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(node.ref());
if(it == m_anchorByIdentity.end())
return 0;
return it->second;
}
NodeEvents::NodeEvents(const Node& node): m_pMemory(node.m_pMemory), m_root(*node.m_pNode)
{
Setup(m_root);
}
void NodeEvents::Setup(const detail::node& node)
{
int& refCount = m_refCount[node.ref()];
refCount++;
if(refCount > 1)
return;
if(node.type() == NodeType::Sequence) {
for(detail::const_node_iterator it=node.begin();it!=node.end();++it)
Setup(**it);
} else if(node.type() == NodeType::Map) {
for(detail::const_node_iterator it=node.begin();it!=node.end();++it) {
Setup(*it->first);
Setup(*it->second);
}
}
}
void NodeEvents::Emit(EventHandler& handler)
{
AliasManager am;
handler.OnDocumentStart(Mark());
Emit(m_root, handler, am);
handler.OnDocumentEnd();
}
void NodeEvents::Emit(const detail::node& node, EventHandler& handler, AliasManager& am) const
{
anchor_t anchor = NullAnchor;
if(IsAliased(node)) {
anchor = am.LookupAnchor(node);
if(anchor) {
handler.OnAlias(Mark(), anchor);
return;
}
am.RegisterReference(node);
anchor = am.LookupAnchor(node);
}
switch(node.type()) {
case NodeType::Undefined:
break;
case NodeType::Null:
handler.OnNull(Mark(), anchor);
break;
case NodeType::Scalar:
handler.OnScalar(Mark(), node.tag(), anchor, node.scalar());
break;
case NodeType::Sequence:
handler.OnSequenceStart(Mark(), node.tag(), anchor);
for(detail::const_node_iterator it=node.begin();it!=node.end();++it)
Emit(**it, handler, am);
handler.OnSequenceEnd();
break;
case NodeType::Map:
handler.OnMapStart(Mark(), node.tag(), anchor);
for(detail::const_node_iterator it=node.begin();it!=node.end();++it) {
Emit(*it->first, handler, am);
Emit(*it->second, handler, am);
}
handler.OnMapEnd();
break;
}
}
bool NodeEvents::IsAliased(const detail::node& node) const
{
RefCount::const_iterator it = m_refCount.find(node.ref());
return it != m_refCount.end() && it->second > 1;
}
}
#ifndef NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
#include "yaml-cpp/anchor.h"
#include "yaml-cpp/node/ptr.h"
#include <map>
#include <vector>
namespace YAML
{
class EventHandler;
class Node;
class NodeEvents
{
public:
explicit NodeEvents(const Node& node);
void Emit(EventHandler& handler);
private:
class AliasManager {
public:
AliasManager(): m_curAnchor(0) {}
void RegisterReference(const detail::node& node);
anchor_t LookupAnchor(const detail::node& node) const;
private:
anchor_t _CreateNewAnchor() { return ++m_curAnchor; }
private:
typedef std::map<const detail::node_ref*, anchor_t> AnchorByIdentity;
AnchorByIdentity m_anchorByIdentity;
anchor_t m_curAnchor;
};
void Setup(const detail::node& node);
void Emit(const detail::node& node, EventHandler& handler, AliasManager& am) const;
bool IsAliased(const detail::node& node) const;
private:
detail::shared_memory_holder m_pMemory;
detail::node& m_root;
typedef std::map<const detail::node_ref *, int> RefCount;
RefCount m_refCount;
};
}
#endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include "yaml-cpp/node/parse.h"
#include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/impl.h"
#include "yaml-cpp/parser.h"
#include "nodebuilder.h"
#include <fstream>
#include <sstream>
namespace YAML
{
Node Load(const std::string& input) {
std::stringstream stream(input);
return Load(stream);
}
Node Load(const char *input) {
std::stringstream stream(input);
return Load(stream);
}
Node Load(std::istream& input) {
Parser parser(input);
NodeBuilder builder;
if(!parser.HandleNextDocument(builder))
return Node();
return builder.Root();
}
Node LoadFile(const std::string& filename) {
std::ifstream fin(filename.c_str());
return Load(fin);
}
std::vector<Node> LoadAll(const std::string& input) {
std::stringstream stream(input);
return LoadAll(stream);
}
std::vector<Node> LoadAll(const char *input) {
std::stringstream stream(input);
return LoadAll(stream);
}
std::vector<Node> LoadAll(std::istream& input) {
std::vector<Node> docs;
Parser parser(input);
while(1) {
NodeBuilder builder;
if(!parser.HandleNextDocument(builder))
break;
docs.push_back(builder.Root());
}
return docs;
}
std::vector<Node> LoadAllFromFile(const std::string& filename) {
std::ifstream fin(filename.c_str());
return LoadAll(fin);
}
}
......@@ -253,7 +253,6 @@ namespace YAML
throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP_FLOW);
Token& token = m_scanner.peek();
const Mark mark = token.mark;
// first check for end
if(token.type == Token::FLOW_MAP_END) {
m_scanner.pop();
......@@ -265,7 +264,7 @@ namespace YAML
m_scanner.pop();
HandleNode(eventHandler);
} else {
eventHandler.OnNull(mark, NullAnchor);
eventHandler.OnNull(token.mark, NullAnchor);
}
// now grab value (optional)
......@@ -273,7 +272,7 @@ namespace YAML
m_scanner.pop();
HandleNode(eventHandler);
} else {
eventHandler.OnNull(mark, NullAnchor);
eventHandler.OnNull(token.mark, NullAnchor);
}
// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
......
file(GLOB test_headers [a-z]*.h)
file(GLOB test_sources [a-z]*.cpp)
file(GLOB test_core_sources core/[a-z]*.cpp)
file(GLOB test_new_api_sources new-api/[a-z]*.cpp)
list(APPEND test_sources ${test_core_sources})
list(APPEND test_sources ${test_new_api_sources})
include_directories(${YAML_CPP_SOURCE_DIR}/test)
......
#include "tests.h"
#include "yaml-cpp/yaml.h"
#include "yaml-cpp/eventhandler.h"
#include <iostream>
namespace Test
......@@ -1000,21 +999,6 @@ namespace Test
}
namespace {
class NullEventHandler: public YAML::EventHandler {
virtual void OnDocumentStart(const YAML::Mark&) {}
virtual void OnDocumentEnd() {}
virtual void OnNull(const YAML::Mark&, YAML::anchor_t) {}
virtual void OnAlias(const YAML::Mark&, YAML::anchor_t) {}
virtual void OnScalar(const YAML::Mark&, const std::string&, YAML::anchor_t, const std::string&) {}
virtual void OnSequenceStart(const YAML::Mark&, const std::string&, YAML::anchor_t) {}
virtual void OnSequenceEnd() {}
virtual void OnMapStart(const YAML::Mark&, const std::string&, YAML::anchor_t) {}
virtual void OnMapEnd() {}
};
void RunEmitterTest(void (*test)(YAML::Emitter&, std::string&), const std::string& name, int& passed, int& total) {
YAML::Emitter out;
std::string desiredOutput;
......@@ -1024,10 +1008,7 @@ namespace Test
if(output == desiredOutput) {
try {
std::stringstream stream(output);
YAML::Parser parser;
NullEventHandler handler;
parser.HandleNextDocument(handler);
YAML::Node node = YAML::Load(output);
passed++;
} catch(const YAML::Exception& e) {
std::cout << "Emitter test failed: " << name << "\n";
......
#include "nodetests.h"
#include "yaml-cpp/yaml.h"
#include <boost/foreach.hpp>
#include <iostream>
namespace {
struct TEST {
TEST(): ok(false) {}
TEST(bool ok_): ok(ok_) {}
TEST(const char *error_): ok(false), error(error_) {}
bool ok;
std::string error;
};
}
#define YAML_ASSERT(cond) do { if(!(cond)) return " Assert failed: " #cond; } while(false)
#define YAML_ASSERT_THROWS(cond, exc) do { try { (cond); return " Expression did not throw: " #cond; } catch(const exc&) {} catch(...) { return " Expression threw something other than " #exc ": " #cond; } } while(false)
namespace Test
{
namespace Node
{
TEST SimpleScalar()
{
YAML::Node node = YAML::Node("Hello, World!");
YAML_ASSERT(node.IsScalar());
YAML_ASSERT(node.as<std::string>() == "Hello, World!");
return true;
}
TEST IntScalar()
{
YAML::Node node = YAML::Node(15);
YAML_ASSERT(node.IsScalar());
YAML_ASSERT(node.as<int>() == 15);
return true;
}
TEST SimpleAppendSequence()
{
YAML::Node node;
node.push_back(10);
node.push_back("foo");
node.push_back("monkey");
YAML_ASSERT(node.IsSequence());
YAML_ASSERT(node.size() == 3);
YAML_ASSERT(node[0].as<int>() == 10);
YAML_ASSERT(node[1].as<std::string>() == "foo");
YAML_ASSERT(node[2].as<std::string>() == "monkey");
YAML_ASSERT(node.IsSequence());
return true;
}
TEST SimpleAssignSequence()
{
YAML::Node node;
node[0] = 10;
node[1] = "foo";
node[2] = "monkey";
YAML_ASSERT(node.IsSequence());
YAML_ASSERT(node.size() == 3);
YAML_ASSERT(node[0].as<int>() == 10);
YAML_ASSERT(node[1].as<std::string>() == "foo");
YAML_ASSERT(node[2].as<std::string>() == "monkey");
YAML_ASSERT(node.IsSequence());
return true;
}
TEST SimpleMap()
{
YAML::Node node;
node["key"] = "value";
YAML_ASSERT(node.IsMap());
YAML_ASSERT(node["key"].as<std::string>() == "value");
YAML_ASSERT(node.size() == 1);
return true;
}
TEST MapWithUndefinedValues()
{
YAML::Node node;
node["key"] = "value";
node["undefined"];
YAML_ASSERT(node.IsMap());
YAML_ASSERT(node["key"].as<std::string>() == "value");
YAML_ASSERT(node.size() == 1);
node["undefined"] = "monkey";
YAML_ASSERT(node["undefined"].as<std::string>() == "monkey");
YAML_ASSERT(node.size() == 2);
return true;
}
TEST MapIteratorWithUndefinedValues()
{
YAML::Node node;
node["key"] = "value";
node["undefined"];
std::size_t count = 0;
for(YAML::const_iterator it=node.begin();it!=node.end();++it)
count++;
YAML_ASSERT(count == 1);
return true;
}
TEST SimpleSubkeys()
{
YAML::Node node;
node["device"]["udid"] = "12345";
node["device"]["name"] = "iPhone";
node["device"]["os"] = "4.0";
node["username"] = "monkey";
YAML_ASSERT(node["device"]["udid"].as<std::string>() == "12345");
YAML_ASSERT(node["device"]["name"].as<std::string>() == "iPhone");
YAML_ASSERT(node["device"]["os"].as<std::string>() == "4.0");
YAML_ASSERT(node["username"].as<std::string>() == "monkey");
return true;
}
TEST StdVector()
{
std::vector<int> primes;
primes.push_back(2);
primes.push_back(3);
primes.push_back(5);
primes.push_back(7);
primes.push_back(11);
primes.push_back(13);
YAML::Node node;
node["primes"] = primes;
YAML_ASSERT(node["primes"].as<std::vector<int> >() == primes);
return true;
}
TEST StdList()
{
std::list<int> primes;
primes.push_back(2);
primes.push_back(3);
primes.push_back(5);
primes.push_back(7);
primes.push_back(11);
primes.push_back(13);
YAML::Node node;
node["primes"] = primes;
YAML_ASSERT(node["primes"].as<std::list<int> >() == primes);
return true;
}
TEST StdMap()
{
std::map<int, int> squares;
squares[0] = 0;
squares[1] = 1;
squares[2] = 4;
squares[3] = 9;
squares[4] = 16;
YAML::Node node;
node["squares"] = squares;
YAML_ASSERT((node["squares"].as<std::map<int, int> >() == squares));
return true;
}
TEST SimpleAlias()
{
YAML::Node node;
node["foo"] = "value";
node["bar"] = node["foo"];
YAML_ASSERT(node["foo"].as<std::string>() == "value");
YAML_ASSERT(node["bar"].as<std::string>() == "value");
YAML_ASSERT(node["foo"] == node["bar"]);
YAML_ASSERT(node.size() == 2);
return true;
}
TEST AliasAsKey()
{
YAML::Node node;
node["foo"] = "value";
YAML::Node value = node["foo"];
node[value] = "foo";
YAML_ASSERT(node["foo"].as<std::string>() == "value");
YAML_ASSERT(node[value].as<std::string>() == "foo");
YAML_ASSERT(node["value"].as<std::string>() == "foo");
YAML_ASSERT(node.size() == 2);
return true;
}
TEST SelfReferenceSequence()
{
YAML::Node node;
node[0] = node;
YAML_ASSERT(node.IsSequence());
YAML_ASSERT(node.size() == 1);
YAML_ASSERT(node[0] == node);
YAML_ASSERT(node[0][0] == node);
YAML_ASSERT(node[0][0] == node[0]);
return true;
}
TEST ValueSelfReferenceMap()
{
YAML::Node node;
node["key"] = node;
YAML_ASSERT(node.IsMap());
YAML_ASSERT(node.size() == 1);
YAML_ASSERT(node["key"] == node);
YAML_ASSERT(node["key"]["key"] == node);
YAML_ASSERT(node["key"]["key"] == node["key"]);
return true;
}
TEST KeySelfReferenceMap()
{
YAML::Node node;
node[node] = "value";
YAML_ASSERT(node.IsMap());
YAML_ASSERT(node.size() == 1);
YAML_ASSERT(node[node].as<std::string>() == "value");
return true;
}
TEST SelfReferenceMap()
{
YAML::Node node;
node[node] = node;
YAML_ASSERT(node.IsMap());
YAML_ASSERT(node.size() == 1);
YAML_ASSERT(node[node] == node);
YAML_ASSERT(node[node][node] == node);
YAML_ASSERT(node[node][node] == node[node]);
return true;
}
TEST TempMapVariable()
{
YAML::Node node;
YAML::Node tmp = node["key"];
tmp = "value";
YAML_ASSERT(node.IsMap());
YAML_ASSERT(node.size() == 1);
YAML_ASSERT(node["key"].as<std::string>() == "value");
return true;
}
TEST TempMapVariableAlias()
{
YAML::Node node;
YAML::Node tmp = node["key"];
tmp = node["other"];
node["other"] = "value";
YAML_ASSERT(node.IsMap());
YAML_ASSERT(node.size() == 2);
YAML_ASSERT(node["key"].as<std::string>() == "value");
YAML_ASSERT(node["other"].as<std::string>() == "value");
YAML_ASSERT(node["other"] == node["key"]);
return true;
}
TEST Bool()
{
YAML::Node node;
node[true] = false;
YAML_ASSERT(node.IsMap());
YAML_ASSERT(node[true].as<bool>() == false);
return true;
}
TEST AutoBoolConversion()
{
YAML::Node node;
node["foo"] = "bar";
YAML_ASSERT(static_cast<bool>(node["foo"]));
YAML_ASSERT(!node["monkey"]);
YAML_ASSERT(!!node["foo"]);
return true;
}
TEST Reassign()
{
YAML::Node node = YAML::Load("foo");
node = YAML::Node();
return true;
}
TEST FallbackValues()
{
YAML::Node node = YAML::Load("foo: bar\nx: 2");
YAML_ASSERT(node["foo"].as<std::string>() == "bar");
YAML_ASSERT(node["foo"].as<std::string>("hello") == "bar");
YAML_ASSERT(node["baz"].as<std::string>("hello") == "hello");
YAML_ASSERT(node["x"].as<int>() == 2);
YAML_ASSERT(node["x"].as<int>(5) == 2);
YAML_ASSERT(node["y"].as<int>(5) == 5);
return true;
}
TEST NumericConversion()
{
YAML::Node node = YAML::Load("[1.5, 1, .nan, .inf, -.inf, 0x15, 015]");
YAML_ASSERT(node[0].as<float>() == 1.5f);
YAML_ASSERT(node[0].as<double>() == 1.5);
YAML_ASSERT_THROWS(node[0].as<int>(), std::runtime_error);
YAML_ASSERT(node[1].as<int>() == 1);
YAML_ASSERT(node[1].as<float>() == 1.0f);
YAML_ASSERT(node[2].as<float>() != node[2].as<float>());
YAML_ASSERT(node[3].as<float>() == std::numeric_limits<float>::infinity());
YAML_ASSERT(node[4].as<float>() == -std::numeric_limits<float>::infinity());
YAML_ASSERT(node[5].as<int>() == 21);
YAML_ASSERT(node[6].as<int>() == 13);
return true;
}
TEST Binary()
{
YAML::Node node = YAML::Load("[!!binary \"SGVsbG8sIFdvcmxkIQ==\", !!binary \"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4K\"]");
YAML_ASSERT(node[0].as<YAML::Binary>() == YAML::Binary(reinterpret_cast<const unsigned char*>("Hello, World!"), 13));
YAML_ASSERT(node[1].as<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 true;
}
TEST IterateSequence()
{
YAML::Node node = YAML::Load("[1, 3, 5, 7]");
int seq[] = {1, 3, 5, 7};
int i=0;
for(YAML::const_iterator it=node.begin();it!=node.end();++it) {
YAML_ASSERT(i < 4);
int x = seq[i++];
YAML_ASSERT(it->as<int>() == x);
}
YAML_ASSERT(i == 4);
return true;
}
TEST IterateMap()
{
YAML::Node node = YAML::Load("{a: A, b: B, c: C}");
int i=0;
for(YAML::const_iterator it=node.begin();it!=node.end();++it) {
YAML_ASSERT(i < 3);
i++;
YAML_ASSERT(it->first.as<char>() + 'A' - 'a' == it->second.as<char>());
}
YAML_ASSERT(i == 3);
return true;
}
TEST ForEach()
{
YAML::Node node = YAML::Load("[1, 3, 5, 7]");
int seq[] = {1, 3, 5, 7};
int i = 0;
BOOST_FOREACH(const YAML::Node &item, node) {
int x = seq[i++];
YAML_ASSERT(item.as<int>() == x);
}
return true;
}
TEST ForEachMap()
{
YAML::Node node = YAML::Load("{a: A, b: B, c: C}");
BOOST_FOREACH(const YAML::const_iterator::value_type &p, node) {
YAML_ASSERT(p.first.as<char>() + 'A' - 'a' == p.second.as<char>());
}
return true;
}
}
void RunNodeTest(TEST (*test)(), const std::string& name, int& passed, int& total) {
TEST ret;
try {
ret = test();
} catch(...) {
ret.ok = false;
}
if(ret.ok) {
passed++;
} else {
std::cout << "Node test failed: " << name << "\n";
if(ret.error != "")
std::cout << ret.error << "\n";
}
total++;
}
bool RunNodeTests()
{
int passed = 0;
int total = 0;
RunNodeTest(&Node::SimpleScalar, "simple scalar", passed, total);
RunNodeTest(&Node::IntScalar, "int scalar", passed, total);
RunNodeTest(&Node::SimpleAppendSequence, "simple append sequence", passed, total);
RunNodeTest(&Node::SimpleAssignSequence, "simple assign sequence", passed, total);
RunNodeTest(&Node::SimpleMap, "simple map", passed, total);
RunNodeTest(&Node::MapWithUndefinedValues, "map with undefined values", passed, total);
RunNodeTest(&Node::MapIteratorWithUndefinedValues, "map iterator with undefined values", passed, total);
RunNodeTest(&Node::SimpleSubkeys, "simple subkey", passed, total);
RunNodeTest(&Node::StdVector, "std::vector", passed, total);
RunNodeTest(&Node::StdList, "std::list", passed, total);
RunNodeTest(&Node::StdMap, "std::map", passed, total);
RunNodeTest(&Node::SimpleAlias, "simple alias", passed, total);
RunNodeTest(&Node::AliasAsKey, "alias as key", passed, total);
RunNodeTest(&Node::SelfReferenceSequence, "self reference sequence", passed, total);
RunNodeTest(&Node::ValueSelfReferenceMap, "value self reference map", passed, total);
RunNodeTest(&Node::KeySelfReferenceMap, "key self reference map", passed, total);
RunNodeTest(&Node::SelfReferenceMap, "self reference map", passed, total);
RunNodeTest(&Node::TempMapVariable, "temp map variable", passed, total);
RunNodeTest(&Node::TempMapVariableAlias, "temp map variable alias", passed, total);
RunNodeTest(&Node::Bool, "bool", passed, total);
RunNodeTest(&Node::AutoBoolConversion, "auto bool conversion", passed, total);
RunNodeTest(&Node::Reassign, "reassign", passed, total);
RunNodeTest(&Node::FallbackValues, "fallback values", passed, total);
RunNodeTest(&Node::NumericConversion, "numeric conversion", passed, total);
RunNodeTest(&Node::Binary, "binary", passed, total);
RunNodeTest(&Node::IterateSequence, "iterate sequence", passed, total);
RunNodeTest(&Node::IterateMap, "iterate map", passed, total);
RunNodeTest(&Node::ForEach, "for each", passed, total);
RunNodeTest(&Node::ForEachMap, "for each map", passed, total);
std::cout << "Node tests: " << passed << "/" << total << " passed\n";
return passed == total;
}
}
#include "parsertests.h"
namespace Test {
bool RunParserTests()
{
return true;
}
}
#include "spectests.h"
#include "specexamples.h"
#include "yaml-cpp/yaml.h"
#include <iostream>
#define YAML_ASSERT(cond) do { if(!(cond)) return " Assert failed: " #cond; } while(false)
namespace Test
{
namespace Spec
{
// 2.1
TEST SeqScalars() {
YAML::Node doc = YAML::Load(ex2_1);
YAML_ASSERT(doc.IsSequence());
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc[0].as<std::string>() == "Mark McGwire");
YAML_ASSERT(doc[1].as<std::string>() == "Sammy Sosa");
YAML_ASSERT(doc[2].as<std::string>() == "Ken Griffey");
return true;
}
// 2.2
TEST MappingScalarsToScalars() {
YAML::Node doc = YAML::Load(ex2_2);
YAML_ASSERT(doc.IsMap());
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["hr"].as<std::string>() == "65");
YAML_ASSERT(doc["avg"].as<std::string>() == "0.278");
YAML_ASSERT(doc["rbi"].as<std::string>() == "147");
return true;
}
// 2.3
TEST MappingScalarsToSequences() {
YAML::Node doc = YAML::Load(ex2_3);
YAML_ASSERT(doc.IsMap());
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["american"].size() == 3);
YAML_ASSERT(doc["american"][0].as<std::string>() == "Boston Red Sox");
YAML_ASSERT(doc["american"][1].as<std::string>() == "Detroit Tigers");
YAML_ASSERT(doc["american"][2].as<std::string>() == "New York Yankees");
YAML_ASSERT(doc["national"].size() == 3);
YAML_ASSERT(doc["national"][0].as<std::string>() == "New York Mets");
YAML_ASSERT(doc["national"][1].as<std::string>() == "Chicago Cubs");
YAML_ASSERT(doc["national"][2].as<std::string>() == "Atlanta Braves");
return true;
}
// 2.4
TEST SequenceOfMappings() {
YAML::Node doc = YAML::Load(ex2_4);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc[0].size() == 3);
YAML_ASSERT(doc[0]["name"].as<std::string>() == "Mark McGwire");
YAML_ASSERT(doc[0]["hr"].as<std::string>() == "65");
YAML_ASSERT(doc[0]["avg"].as<std::string>() == "0.278");
YAML_ASSERT(doc[1].size() == 3);
YAML_ASSERT(doc[1]["name"].as<std::string>() == "Sammy Sosa");
YAML_ASSERT(doc[1]["hr"].as<std::string>() == "63");
YAML_ASSERT(doc[1]["avg"].as<std::string>() == "0.288");
return true;
}
// 2.5
TEST SequenceOfSequences() {
YAML::Node doc = YAML::Load(ex2_5);
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc[0].size() == 3);
YAML_ASSERT(doc[0][0].as<std::string>() == "name");
YAML_ASSERT(doc[0][1].as<std::string>() == "hr");
YAML_ASSERT(doc[0][2].as<std::string>() == "avg");
YAML_ASSERT(doc[1].size() == 3);
YAML_ASSERT(doc[1][0].as<std::string>() == "Mark McGwire");
YAML_ASSERT(doc[1][1].as<std::string>() == "65");
YAML_ASSERT(doc[1][2].as<std::string>() == "0.278");
YAML_ASSERT(doc[2].size() == 3);
YAML_ASSERT(doc[2][0].as<std::string>() == "Sammy Sosa");
YAML_ASSERT(doc[2][1].as<std::string>() == "63");
YAML_ASSERT(doc[2][2].as<std::string>() == "0.288");
return true;
}
// 2.6
TEST MappingOfMappings() {
YAML::Node doc = YAML::Load(ex2_6);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["Mark McGwire"].size() == 2);
YAML_ASSERT(doc["Mark McGwire"]["hr"].as<std::string>() == "65");
YAML_ASSERT(doc["Mark McGwire"]["avg"].as<std::string>() == "0.278");
YAML_ASSERT(doc["Sammy Sosa"].size() == 2);
YAML_ASSERT(doc["Sammy Sosa"]["hr"].as<std::string>() == "63");
YAML_ASSERT(doc["Sammy Sosa"]["avg"].as<std::string>() == "0.288");
return true;
}
// 2.7
TEST TwoDocumentsInAStream() {
std::vector<YAML::Node> docs = YAML::LoadAll(ex2_7);
YAML_ASSERT(docs.size() == 2);
{
YAML::Node doc = docs[0];
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc[0].as<std::string>() == "Mark McGwire");
YAML_ASSERT(doc[1].as<std::string>() == "Sammy Sosa");
YAML_ASSERT(doc[2].as<std::string>() == "Ken Griffey");
}
{
YAML::Node doc = docs[1];
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc[0].as<std::string>() == "Chicago Cubs");
YAML_ASSERT(doc[1].as<std::string>() == "St Louis Cardinals");
}
return true;
}
// 2.8
TEST PlayByPlayFeed() {
std::vector<YAML::Node> docs = YAML::LoadAll(ex2_8);
YAML_ASSERT(docs.size() == 2);
{
YAML::Node doc = docs[0];
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["time"].as<std::string>() == "20:03:20");
YAML_ASSERT(doc["player"].as<std::string>() == "Sammy Sosa");
YAML_ASSERT(doc["action"].as<std::string>() == "strike (miss)");
}
{
YAML::Node doc = docs[1];
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["time"].as<std::string>() == "20:03:47");
YAML_ASSERT(doc["player"].as<std::string>() == "Sammy Sosa");
YAML_ASSERT(doc["action"].as<std::string>() == "grand slam");
}
return true;
}
// 2.9
TEST SingleDocumentWithTwoComments() {
YAML::Node doc = YAML::Load(ex2_9);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["hr"].size() == 2);
YAML_ASSERT(doc["hr"][0].as<std::string>() == "Mark McGwire");
YAML_ASSERT(doc["hr"][1].as<std::string>() == "Sammy Sosa");
YAML_ASSERT(doc["rbi"].size() == 2);
YAML_ASSERT(doc["rbi"][0].as<std::string>() == "Sammy Sosa");
YAML_ASSERT(doc["rbi"][1].as<std::string>() == "Ken Griffey");
return true;
}
// 2.10
TEST SimpleAnchor() {
YAML::Node doc = YAML::Load(ex2_10);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["hr"].size() == 2);
YAML_ASSERT(doc["hr"][0].as<std::string>() == "Mark McGwire");
YAML_ASSERT(doc["hr"][1].as<std::string>() == "Sammy Sosa");
YAML_ASSERT(doc["rbi"].size() == 2);
YAML_ASSERT(doc["rbi"][0].as<std::string>() == "Sammy Sosa");
YAML_ASSERT(doc["rbi"][1].as<std::string>() == "Ken Griffey");
return true;
}
// 2.11
TEST MappingBetweenSequences() {
YAML::Node doc = YAML::Load(ex2_11);
std::vector<std::string> tigers_cubs;
tigers_cubs.push_back("Detroit Tigers");
tigers_cubs.push_back("Chicago cubs");
std::vector<std::string> yankees_braves;
yankees_braves.push_back("New York Yankees");
yankees_braves.push_back("Atlanta Braves");
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc[tigers_cubs].size() == 1);
YAML_ASSERT(doc[tigers_cubs][0].as<std::string>() == "2001-07-23");
YAML_ASSERT(doc[yankees_braves].size() == 3);
YAML_ASSERT(doc[yankees_braves][0].as<std::string>() == "2001-07-02");
YAML_ASSERT(doc[yankees_braves][1].as<std::string>() == "2001-08-12");
YAML_ASSERT(doc[yankees_braves][2].as<std::string>() == "2001-08-14");
return true;
}
// 2.12
TEST CompactNestedMapping() {
YAML::Node doc = YAML::Load(ex2_12);
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc[0].size() == 2);
YAML_ASSERT(doc[0]["item"].as<std::string>() == "Super Hoop");
YAML_ASSERT(doc[0]["quantity"].as<int>() == 1);
YAML_ASSERT(doc[1].size() == 2);
YAML_ASSERT(doc[1]["item"].as<std::string>() == "Basketball");
YAML_ASSERT(doc[1]["quantity"].as<int>() == 4);
YAML_ASSERT(doc[2].size() == 2);
YAML_ASSERT(doc[2]["item"].as<std::string>() == "Big Shoes");
YAML_ASSERT(doc[2]["quantity"].as<int>() == 1);
return true;
}
// 2.13
TEST InLiteralsNewlinesArePreserved() {
YAML::Node doc = YAML::Load(ex2_13);
YAML_ASSERT(doc.as<std::string>() ==
"\\//||\\/||\n"
"// || ||__");
return true;
}
// 2.14
TEST InFoldedScalarsNewlinesBecomeSpaces() {
YAML::Node doc = YAML::Load(ex2_14);
YAML_ASSERT(doc.as<std::string>() == "Mark McGwire's year was crippled by a knee injury.");
return true;
}
// 2.15
TEST FoldedNewlinesArePreservedForMoreIndentedAndBlankLines() {
YAML::Node doc = YAML::Load(ex2_15);
YAML_ASSERT(doc.as<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() {
YAML::Node doc = YAML::Load(ex2_16);
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["name"].as<std::string>() == "Mark McGwire");
YAML_ASSERT(doc["accomplishment"].as<std::string>() == "Mark set a major league home run record in 1998.\n");
YAML_ASSERT(doc["stats"].as<std::string>() == "65 Home Runs\n0.278 Batting Average\n");
return true;
}
// 2.17
TEST QuotedScalars() {
YAML::Node doc = YAML::Load(ex2_17);
YAML_ASSERT(doc.size() == 6);
YAML_ASSERT(doc["unicode"].as<std::string>() == "Sosa did fine.\xe2\x98\xba");
YAML_ASSERT(doc["control"].as<std::string>() == "\b1998\t1999\t2000\n");
YAML_ASSERT(doc["hex esc"].as<std::string>() == "\x0d\x0a is \r\n");
YAML_ASSERT(doc["single"].as<std::string>() == "\"Howdy!\" he cried.");
YAML_ASSERT(doc["quoted"].as<std::string>() == " # Not a 'comment'.");
YAML_ASSERT(doc["tie-fighter"].as<std::string>() == "|\\-*-/|");
return true;
}
// 2.18
TEST MultiLineFlowScalars() {
YAML::Node doc = YAML::Load(ex2_18);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["plain"].as<std::string>() == "This unquoted scalar spans many lines.");
YAML_ASSERT(doc["quoted"].as<std::string>() == "So does this quoted scalar.\n");
return true;
}
// TODO: 2.19 - 2.22 schema tags
// 2.23
TEST VariousExplicitTags() {
YAML::Node doc = YAML::Load(ex2_23);
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["not-date"].Tag() == "tag:yaml.org,2002:str");
YAML_ASSERT(doc["not-date"].as<std::string>() == "2002-04-28");
YAML_ASSERT(doc["picture"].Tag() == "tag:yaml.org,2002:binary");
YAML_ASSERT(doc["picture"].as<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"].as<std::string>() ==
"The semantics of the tag\n"
"above may be different for\n"
"different documents."
);
return true;
}
// 2.24
TEST GlobalTags() {
YAML::Node doc = YAML::Load(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"].as<int>() == 73);
YAML_ASSERT(doc[0]["center"]["y"].as<int>() == 129);
YAML_ASSERT(doc[0]["radius"].as<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"].as<int>() == 73);
YAML_ASSERT(doc[1]["start"]["y"].as<int>() == 129);
YAML_ASSERT(doc[1]["finish"].size() == 2);
YAML_ASSERT(doc[1]["finish"]["x"].as<int>() == 89);
YAML_ASSERT(doc[1]["finish"]["y"].as<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"].as<int>() == 73);
YAML_ASSERT(doc[2]["start"]["y"].as<int>() == 129);
YAML_ASSERT(doc[2]["color"].as<std::string>() == "0xFFEEBB");
YAML_ASSERT(doc[2]["text"].as<std::string>() == "Pretty vector drawing.");
return true;
}
// 2.25
TEST UnorderedSets() {
YAML::Node doc = YAML::Load(ex2_25);
YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:set");
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["Mark McGwire"].IsNull());
YAML_ASSERT(doc["Sammy Sosa"].IsNull());
YAML_ASSERT(doc["Ken Griffey"].IsNull());
return true;
}
// 2.26
TEST OrderedMappings() {
YAML::Node doc = YAML::Load(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"].as<int>() == 65);
YAML_ASSERT(doc[1].size() == 1);
YAML_ASSERT(doc[1]["Sammy Sosa"].as<int>() == 63);
YAML_ASSERT(doc[2].size() == 1);
YAML_ASSERT(doc[2]["Ken Griffey"].as<int>() == 58);
return true;
}
// 2.27
TEST Invoice() {
YAML::Node doc = YAML::Load(ex2_27);
YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:invoice");
YAML_ASSERT(doc.size() == 8);
YAML_ASSERT(doc["invoice"].as<int>() == 34843);
YAML_ASSERT(doc["date"].as<std::string>() == "2001-01-23");
YAML_ASSERT(doc["bill-to"].size() == 3);
YAML_ASSERT(doc["bill-to"]["given"].as<std::string>() == "Chris");
YAML_ASSERT(doc["bill-to"]["family"].as<std::string>() == "Dumars");
YAML_ASSERT(doc["bill-to"]["address"].size() == 4);
YAML_ASSERT(doc["bill-to"]["address"]["lines"].as<std::string>() == "458 Walkman Dr.\nSuite #292\n");
YAML_ASSERT(doc["bill-to"]["address"]["city"].as<std::string>() == "Royal Oak");
YAML_ASSERT(doc["bill-to"]["address"]["state"].as<std::string>() == "MI");
YAML_ASSERT(doc["bill-to"]["address"]["postal"].as<std::string>() == "48046");
YAML_ASSERT(doc["ship-to"].size() == 3);
YAML_ASSERT(doc["ship-to"]["given"].as<std::string>() == "Chris");
YAML_ASSERT(doc["ship-to"]["family"].as<std::string>() == "Dumars");
YAML_ASSERT(doc["ship-to"]["address"].size() == 4);
YAML_ASSERT(doc["ship-to"]["address"]["lines"].as<std::string>() == "458 Walkman Dr.\nSuite #292\n");
YAML_ASSERT(doc["ship-to"]["address"]["city"].as<std::string>() == "Royal Oak");
YAML_ASSERT(doc["ship-to"]["address"]["state"].as<std::string>() == "MI");
YAML_ASSERT(doc["ship-to"]["address"]["postal"].as<std::string>() == "48046");
YAML_ASSERT(doc["product"].size() == 2);
YAML_ASSERT(doc["product"][0].size() == 4);
YAML_ASSERT(doc["product"][0]["sku"].as<std::string>() == "BL394D");
YAML_ASSERT(doc["product"][0]["quantity"].as<int>() == 4);
YAML_ASSERT(doc["product"][0]["description"].as<std::string>() == "Basketball");
YAML_ASSERT(doc["product"][0]["price"].as<std::string>() == "450.00");
YAML_ASSERT(doc["product"][1].size() == 4);
YAML_ASSERT(doc["product"][1]["sku"].as<std::string>() == "BL4438H");
YAML_ASSERT(doc["product"][1]["quantity"].as<int>() == 1);
YAML_ASSERT(doc["product"][1]["description"].as<std::string>() == "Super Hoop");
YAML_ASSERT(doc["product"][1]["price"].as<std::string>() == "2392.00");
YAML_ASSERT(doc["tax"].as<std::string>() == "251.42");
YAML_ASSERT(doc["total"].as<std::string>() == "4443.52");
YAML_ASSERT(doc["comments"].as<std::string>() == "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.");
return true;
}
// 2.28
TEST LogFile() {
std::vector<YAML::Node> docs = YAML::LoadAll(ex2_28);
YAML_ASSERT(docs.size() == 3);
{
YAML::Node doc = docs[0];
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["Time"].as<std::string>() == "2001-11-23 15:01:42 -5");
YAML_ASSERT(doc["User"].as<std::string>() == "ed");
YAML_ASSERT(doc["Warning"].as<std::string>() == "This is an error message for the log file");
}
{
YAML::Node doc = docs[1];
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["Time"].as<std::string>() == "2001-11-23 15:02:31 -5");
YAML_ASSERT(doc["User"].as<std::string>() == "ed");
YAML_ASSERT(doc["Warning"].as<std::string>() == "A slightly different error message.");
}
{
YAML::Node doc = docs[2];
YAML_ASSERT(doc.size() == 4);
YAML_ASSERT(doc["Date"].as<std::string>() == "2001-11-23 15:03:17 -5");
YAML_ASSERT(doc["User"].as<std::string>() == "ed");
YAML_ASSERT(doc["Fatal"].as<std::string>() == "Unknown variable \"bar\"");
YAML_ASSERT(doc["Stack"].size() == 2);
YAML_ASSERT(doc["Stack"][0].size() == 3);
YAML_ASSERT(doc["Stack"][0]["file"].as<std::string>() == "TopClass.py");
YAML_ASSERT(doc["Stack"][0]["line"].as<std::string>() == "23");
YAML_ASSERT(doc["Stack"][0]["code"].as<std::string>() == "x = MoreObject(\"345\\n\")\n");
YAML_ASSERT(doc["Stack"][1].size() == 3);
YAML_ASSERT(doc["Stack"][1]["file"].as<std::string>() == "MoreClass.py");
YAML_ASSERT(doc["Stack"][1]["line"].as<std::string>() == "58");
YAML_ASSERT(doc["Stack"][1]["code"].as<std::string>() == "foo = bar");
}
return true;
}
// TODO: 5.1 - 5.2 BOM
// 5.3
TEST BlockStructureIndicators() {
YAML::Node doc = YAML::Load(ex5_3);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["sequence"].size() == 2);
YAML_ASSERT(doc["sequence"][0].as<std::string>() == "one");
YAML_ASSERT(doc["sequence"][1].as<std::string>() == "two");
YAML_ASSERT(doc["mapping"].size() == 2);
YAML_ASSERT(doc["mapping"]["sky"].as<std::string>() == "blue");
YAML_ASSERT(doc["mapping"]["sea"].as<std::string>() == "green");
return true;
}
// 5.4
TEST FlowStructureIndicators() {
YAML::Node doc = YAML::Load(ex5_4);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["sequence"].size() == 2);
YAML_ASSERT(doc["sequence"][0].as<std::string>() == "one");
YAML_ASSERT(doc["sequence"][1].as<std::string>() == "two");
YAML_ASSERT(doc["mapping"].size() == 2);
YAML_ASSERT(doc["mapping"]["sky"].as<std::string>() == "blue");
YAML_ASSERT(doc["mapping"]["sea"].as<std::string>() == "green");
return true;
}
// 5.5
TEST CommentIndicator() {
YAML::Node doc = YAML::Load(ex5_5);
YAML_ASSERT(doc.IsNull());
return true;
}
// 5.6
TEST NodePropertyIndicators() {
YAML::Node doc = YAML::Load(ex5_6);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["anchored"].as<std::string>() == "value"); // TODO: assert tag
YAML_ASSERT(doc["alias"].as<std::string>() == "value");
return true;
}
// 5.7
TEST BlockScalarIndicators() {
YAML::Node doc = YAML::Load(ex5_7);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["literal"].as<std::string>() == "some\ntext\n");
YAML_ASSERT(doc["folded"].as<std::string>() == "some text\n");
return true;
}
// 5.8
TEST QuotedScalarIndicators() {
YAML::Node doc = YAML::Load(ex5_8);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["single"].as<std::string>() == "text");
YAML_ASSERT(doc["double"].as<std::string>() == "text");
return true;
}
// TODO: 5.9 directive
// TODO: 5.10 reserved indicator
// 5.11
TEST LineBreakCharacters() {
YAML::Node doc = YAML::Load(ex5_11);
YAML_ASSERT(doc.as<std::string>() == "Line break (no glyph)\nLine break (glyphed)\n");
return true;
}
// 5.12
TEST TabsAndSpaces() {
YAML::Node doc = YAML::Load(ex5_12);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["quoted"].as<std::string>() == "Quoted\t");
YAML_ASSERT(doc["block"].as<std::string>() ==
"void main() {\n"
"\tprintf(\"Hello, world!\\n\");\n"
"}");
return true;
}
// 5.13
TEST EscapedCharacters() {
YAML::Node doc = YAML::Load(ex5_13);
YAML_ASSERT(doc.as<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() {
try {
YAML::Load(ex5_14);
} catch(const YAML::ParserException& e) {
YAML_ASSERT(e.msg == std::string(YAML::ErrorMsg::INVALID_ESCAPE) + "c");
return true;
}
return false;
}
// 6.1
TEST IndentationSpaces() {
YAML::Node doc = YAML::Load(ex6_1);
YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc["Not indented"].size() == 2);
YAML_ASSERT(doc["Not indented"]["By one space"].as<std::string>() == "By four\n spaces\n");
YAML_ASSERT(doc["Not indented"]["Flow style"].size() == 3);
YAML_ASSERT(doc["Not indented"]["Flow style"][0].as<std::string>() == "By two");
YAML_ASSERT(doc["Not indented"]["Flow style"][1].as<std::string>() == "Also by two");
YAML_ASSERT(doc["Not indented"]["Flow style"][2].as<std::string>() == "Still by two");
return true;
}
// 6.2
TEST IndentationIndicators() {
YAML::Node doc = YAML::Load(ex6_2);
YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc["a"].size() == 2);
YAML_ASSERT(doc["a"][0].as<std::string>() == "b");
YAML_ASSERT(doc["a"][1].size() == 2);
YAML_ASSERT(doc["a"][1][0].as<std::string>() == "c");
YAML_ASSERT(doc["a"][1][1].as<std::string>() == "d");
return true;
}
// 6.3
TEST SeparationSpaces() {
YAML::Node doc = YAML::Load(ex6_3);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc[0].size() == 1);
YAML_ASSERT(doc[0]["foo"].as<std::string>() == "bar");
YAML_ASSERT(doc[1].size() == 2);
YAML_ASSERT(doc[1][0].as<std::string>() == "baz");
YAML_ASSERT(doc[1][1].as<std::string>() == "baz");
return true;
}
// 6.4
TEST LinePrefixes() {
YAML::Node doc = YAML::Load(ex6_4);
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["plain"].as<std::string>() == "text lines");
YAML_ASSERT(doc["quoted"].as<std::string>() == "text lines");
YAML_ASSERT(doc["block"].as<std::string>() == "text\n \tlines\n");
return true;
}
// 6.5
TEST EmptyLines() {
YAML::Node doc = YAML::Load(ex6_5);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["Folding"].as<std::string>() == "Empty line\nas a line feed");
YAML_ASSERT(doc["Chomping"].as<std::string>() == "Clipped empty lines\n");
return true;
}
// 6.6
TEST LineFolding() {
YAML::Node doc = YAML::Load(ex6_6);
YAML_ASSERT(doc.as<std::string>() == "trimmed\n\n\nas space");
return true;
}
// 6.7
TEST BlockFolding() {
YAML::Node doc = YAML::Load(ex6_7);
YAML_ASSERT(doc.as<std::string>() == "foo \n\n\t bar\n\nbaz\n");
return true;
}
// 6.8
TEST FlowFolding() {
YAML::Node doc = YAML::Load(ex6_8);
YAML_ASSERT(doc.as<std::string>() == " foo\nbar\nbaz ");
return true;
}
// 6.9
TEST SeparatedComment() {
YAML::Node doc = YAML::Load(ex6_9);
YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc["key"].as<std::string>() == "value");
return true;
}
// 6.10
TEST CommentLines() {
YAML::Node doc = YAML::Load(ex6_10);
YAML_ASSERT(doc.IsNull());
return true;
}
// 6.11
TEST MultiLineComments() {
YAML::Node doc = YAML::Load(ex6_11);
YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc["key"].as<std::string>() == "value");
return true;
}
// 6.12
TEST SeparationSpacesII() {
YAML::Node doc = YAML::Load(ex6_12);
std::map<std::string, std::string> sammy;
sammy["first"] = "Sammy";
sammy["last"] = "Sosa";
YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc[sammy].size() == 2);
YAML_ASSERT(doc[sammy]["hr"].as<int>() == 65);
YAML_ASSERT(doc[sammy]["avg"].as<std::string>() == "0.278");
return true;
}
// 6.13
TEST ReservedDirectives() {
YAML::Node doc = YAML::Load(ex6_13);
YAML_ASSERT(doc.as<std::string>() == "foo");
return true;
}
// 6.14
TEST YAMLDirective() {
YAML::Node doc = YAML::Load(ex6_14);
YAML_ASSERT(doc.as<std::string>() == "foo");
return true;
}
// 6.15
TEST InvalidRepeatedYAMLDirective() {
try {
YAML::Load(ex6_15);
} catch(const YAML::ParserException& e) {
YAML_ASSERT(e.msg == YAML::ErrorMsg::REPEATED_YAML_DIRECTIVE);
return true;
}
return " No exception was thrown";
}
// 6.16
TEST TagDirective() {
YAML::Node doc = YAML::Load(ex6_16);
YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:str");
YAML_ASSERT(doc.as<std::string>() == "foo");
return true;
}
// 6.17
TEST InvalidRepeatedTagDirective() {
try {
YAML::Load(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() {
std::vector<YAML::Node> docs = YAML::LoadAll(ex6_18);
YAML_ASSERT(docs.size() == 2);
{
YAML::Node doc = docs[0];
YAML_ASSERT(doc.Tag() == "!foo");
YAML_ASSERT(doc.as<std::string>() == "bar");
}
{
YAML::Node doc = docs[1];
YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo");
YAML_ASSERT(doc.as<std::string>() == "bar");
}
return true;
}
// 6.19
TEST SecondaryTagHandle() {
YAML::Node doc = YAML::Load(ex6_19);
YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/int");
YAML_ASSERT(doc.as<std::string>() == "1 - 3");
return true;
}
// 6.20
TEST TagHandles() {
YAML::Node doc = YAML::Load(ex6_20);
YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo");
YAML_ASSERT(doc.as<std::string>() == "bar");
return true;
}
// 6.21
TEST LocalTagPrefix() {
std::vector<YAML::Node> docs = YAML::LoadAll(ex6_21);
YAML_ASSERT(docs.size() == 2);
{
YAML::Node doc = docs[0];
YAML_ASSERT(doc.Tag() == "!my-light");
YAML_ASSERT(doc.as<std::string>() == "fluorescent");
}
{
YAML::Node doc = docs[1];
YAML_ASSERT(doc.Tag() == "!my-light");
YAML_ASSERT(doc.as<std::string>() == "green");
}
return true;
}
// 6.22
TEST GlobalTagPrefix() {
YAML::Node doc = YAML::Load(ex6_22);
YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc[0].Tag() == "tag:example.com,2000:app/foo");
YAML_ASSERT(doc[0].as<std::string>() == "bar");
return true;
}
// 6.23
TEST NodeProperties() {
YAML::Node doc = YAML::Load(ex6_23);
YAML_ASSERT(doc.size() == 2);
for(YAML::const_iterator it=doc.begin();it!=doc.end();++it) {
if(it->first.as<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.as<std::string>() == "bar");
} else if(it->first.as<std::string>() == "baz") {
YAML_ASSERT(it->second.as<std::string>() == "foo");
} else
return " unknown key";
}
return true;
}
// 6.24
TEST VerbatimTags() {
YAML::Node doc = YAML::Load(ex6_24);
YAML_ASSERT(doc.size() == 1);
for(YAML::const_iterator it=doc.begin();it!=doc.end();++it) {
YAML_ASSERT(it->first.Tag() == "tag:yaml.org,2002:str");
YAML_ASSERT(it->first.as<std::string>() == "foo");
YAML_ASSERT(it->second.Tag() == "!bar");
YAML_ASSERT(it->second.as<std::string>() == "baz");
}
return true;
}
// 6.25
TEST InvalidVerbatimTags() {
YAML::Node doc = YAML::Load(ex6_25);
return " not implemented yet"; // TODO: check tags (but we probably will say these are valid, I think)
}
// 6.26
TEST TagShorthands() {
YAML::Node doc = YAML::Load(ex6_26);
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc[0].Tag() == "!local");
YAML_ASSERT(doc[0].as<std::string>() == "foo");
YAML_ASSERT(doc[1].Tag() == "tag:yaml.org,2002:str");
YAML_ASSERT(doc[1].as<std::string>() == "bar");
YAML_ASSERT(doc[2].Tag() == "tag:example.com,2000:app/tag%21");
YAML_ASSERT(doc[2].as<std::string>() == "baz");
return true;
}
// 6.27
TEST InvalidTagShorthands() {
bool threw = false;
try {
YAML::Load(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";
YAML::Load(ex6_27b); // TODO: should we reject this one (since !h! is not declared)?
return " not implemented yet";
}
// 6.28
TEST NonSpecificTags() {
YAML::Node doc = YAML::Load(ex6_28);
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc[0].as<std::string>() == "12"); // TODO: check tags. How?
YAML_ASSERT(doc[1].as<int>() == 12);
YAML_ASSERT(doc[2].as<std::string>() == "12");
return true;
}
// 6.29
TEST NodeAnchors() {
YAML::Node doc = YAML::Load(ex6_29);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["First occurrence"].as<std::string>() == "Value");
YAML_ASSERT(doc["Second occurrence"].as<std::string>() == "Value");
return true;
}
// 7.1
TEST AliasNodes() {
YAML::Node doc = YAML::Load(ex7_1);
YAML_ASSERT(doc.size() == 4);
YAML_ASSERT(doc["First occurrence"].as<std::string>() == "Foo");
YAML_ASSERT(doc["Second occurrence"].as<std::string>() == "Foo");
YAML_ASSERT(doc["Override anchor"].as<std::string>() == "Bar");
YAML_ASSERT(doc["Reuse anchor"].as<std::string>() == "Bar");
return true;
}
// 7.2
TEST EmptyNodes() {
YAML::Node doc = YAML::Load(ex7_2);
YAML_ASSERT(doc.size() == 2);
for(YAML::const_iterator it=doc.begin();it!=doc.end();++it) {
if(it->first.as<std::string>() == "foo") {
YAML_ASSERT(it->second.Tag() == "tag:yaml.org,2002:str");
YAML_ASSERT(it->second.as<std::string>() == "");
} else if(it->first.as<std::string>() == "") {
YAML_ASSERT(it->first.Tag() == "tag:yaml.org,2002:str");
YAML_ASSERT(it->second.as<std::string>() == "bar");
} else
return " unexpected key";
}
return true;
}
// 7.3
TEST CompletelyEmptyNodes() {
YAML::Node doc = YAML::Load(ex7_3);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["foo"].IsNull());
YAML_ASSERT(doc[YAML::Null].as<std::string>() == "bar");
return true;
}
// 7.4
TEST DoubleQuotedImplicitKeys() {
YAML::Node doc = YAML::Load(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"].as<std::string>() == "value");
return true;
}
// 7.5
TEST DoubleQuotedLineBreaks() {
YAML::Node doc = YAML::Load(ex7_5);
YAML_ASSERT(doc.as<std::string>() == "folded to a space,\nto a line feed, or \t \tnon-content");
return true;
}
// 7.6
TEST DoubleQuotedLines() {
YAML::Node doc = YAML::Load(ex7_6);
YAML_ASSERT(doc.as<std::string>() == " 1st non-empty\n2nd non-empty 3rd non-empty ");
return true;
}
// 7.7
TEST SingleQuotedCharacters() {
YAML::Node doc = YAML::Load(ex7_7);
YAML_ASSERT(doc.as<std::string>() == "here's to \"quotes\"");
return true;
}
// 7.8
TEST SingleQuotedImplicitKeys() {
YAML::Node doc = YAML::Load(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"].as<std::string>() == "value");
return true;
}
// 7.9
TEST SingleQuotedLines() {
YAML::Node doc = YAML::Load(ex7_9);
YAML_ASSERT(doc.as<std::string>() == " 1st non-empty\n2nd non-empty 3rd non-empty ");
return true;
}
// 7.10
TEST PlainCharacters() {
YAML::Node doc = YAML::Load(ex7_10);
YAML_ASSERT(doc.size() == 6);
YAML_ASSERT(doc[0].as<std::string>() == "::vector");
YAML_ASSERT(doc[1].as<std::string>() == ": - ()");
YAML_ASSERT(doc[2].as<std::string>() == "Up, up, and away!");
YAML_ASSERT(doc[3].as<int>() == -123);
YAML_ASSERT(doc[4].as<std::string>() == "http://example.com/foo#bar");
YAML_ASSERT(doc[5].size() == 5);
YAML_ASSERT(doc[5][0].as<std::string>() == "::vector");
YAML_ASSERT(doc[5][1].as<std::string>() == ": - ()");
YAML_ASSERT(doc[5][2].as<std::string>() == "Up, up, and away!");
YAML_ASSERT(doc[5][3].as<int>() == -123);
YAML_ASSERT(doc[5][4].as<std::string>() == "http://example.com/foo#bar");
return true;
}
// 7.11
TEST PlainImplicitKeys() {
YAML::Node doc = YAML::Load(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"].as<std::string>() == "value");
return true;
}
// 7.12
TEST PlainLines() {
YAML::Node doc = YAML::Load(ex7_12);
YAML_ASSERT(doc.as<std::string>() == "1st non-empty\n2nd non-empty 3rd non-empty");
return true;
}
// 7.13
TEST FlowSequence() {
YAML::Node doc = YAML::Load(ex7_13);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc[0].size() == 2);
YAML_ASSERT(doc[0][0].as<std::string>() == "one");
YAML_ASSERT(doc[0][1].as<std::string>() == "two");
YAML_ASSERT(doc[1].size() == 2);
YAML_ASSERT(doc[1][0].as<std::string>() == "three");
YAML_ASSERT(doc[1][1].as<std::string>() == "four");
return true;
}
// 7.14
TEST FlowSequenceEntries() {
YAML::Node doc = YAML::Load(ex7_14);
YAML_ASSERT(doc.size() == 5);
YAML_ASSERT(doc[0].as<std::string>() == "double quoted");
YAML_ASSERT(doc[1].as<std::string>() == "single quoted");
YAML_ASSERT(doc[2].as<std::string>() == "plain text");
YAML_ASSERT(doc[3].size() == 1);
YAML_ASSERT(doc[3][0].as<std::string>() == "nested");
YAML_ASSERT(doc[4].size() == 1);
YAML_ASSERT(doc[4]["single"].as<std::string>() == "pair");
return true;
}
// 7.15
TEST FlowMappings() {
YAML::Node doc = YAML::Load(ex7_15);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc[0].size() == 2);
YAML_ASSERT(doc[0]["one"].as<std::string>() == "two");
YAML_ASSERT(doc[0]["three"].as<std::string>() == "four");
YAML_ASSERT(doc[1].size() == 2);
YAML_ASSERT(doc[1]["five"].as<std::string>() == "six");
YAML_ASSERT(doc[1]["seven"].as<std::string>() == "eight");
return true;
}
// 7.16
TEST FlowMappingEntries() {
YAML::Node doc = YAML::Load(ex7_16);
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["explicit"].as<std::string>() == "entry");
YAML_ASSERT(doc["implicit"].as<std::string>() == "entry");
YAML_ASSERT(doc[YAML::Null].IsNull());
return true;
}
// 7.17
TEST FlowMappingSeparateValues() {
YAML::Node doc = YAML::Load(ex7_17);
YAML_ASSERT(doc.size() == 4);
YAML_ASSERT(doc["unquoted"].as<std::string>() == "separate");
YAML_ASSERT(doc["http://foo.com"].IsNull());
YAML_ASSERT(doc["omitted value"].IsNull());
YAML_ASSERT(doc[YAML::Null].as<std::string>() == "omitted key");
return true;
}
// 7.18
TEST FlowMappingAdjacentValues() {
YAML::Node doc = YAML::Load(ex7_18);
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["adjacent"].as<std::string>() == "value");
YAML_ASSERT(doc["readable"].as<std::string>() == "value");
YAML_ASSERT(doc["empty"].IsNull());
return true;
}
// 7.19
TEST SinglePairFlowMappings() {
YAML::Node doc = YAML::Load(ex7_19);
YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc[0].size() == 1);
YAML_ASSERT(doc[0]["foo"].as<std::string>() == "bar");
return true;
}
// 7.20
TEST SinglePairExplicitEntry() {
YAML::Node doc = YAML::Load(ex7_20);
YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc[0].size() == 1);
YAML_ASSERT(doc[0]["foo bar"].as<std::string>() == "baz");
return true;
}
// 7.21
TEST SinglePairImplicitEntries() {
YAML::Node doc = YAML::Load(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"].as<std::string>() == "separate");
YAML_ASSERT(doc[1].size() == 1);
YAML_ASSERT(doc[1][0].size() == 1);
YAML_ASSERT(doc[1][0][YAML::Null].as<std::string>() == "empty key entry");
YAML_ASSERT(doc[2].size() == 1);
YAML_ASSERT(doc[2][0].size() == 1);
std::map<std::string, std::string> key;
key["JSON"] = "like";
YAML_ASSERT(doc[2][0][key].as<std::string>() == "adjacent");
return true;
}
// 7.22
TEST InvalidImplicitKeys() {
try {
YAML::Load(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() {
YAML::Node doc = YAML::Load(ex7_23);
YAML_ASSERT(doc.size() == 5);
YAML_ASSERT(doc[0].size() == 2);
YAML_ASSERT(doc[0][0].as<std::string>() == "a");
YAML_ASSERT(doc[0][1].as<std::string>() == "b");
YAML_ASSERT(doc[1].size() == 1);
YAML_ASSERT(doc[1]["a"].as<std::string>() == "b");
YAML_ASSERT(doc[2].as<std::string>() == "a");
YAML_ASSERT(doc[3].as<char>() == 'b');
YAML_ASSERT(doc[4].as<std::string>() == "c");
return true;
}
// 7.24
TEST FlowNodes() {
YAML::Node doc = YAML::Load(ex7_24);
YAML_ASSERT(doc.size() == 5);
YAML_ASSERT(doc[0].Tag() == "tag:yaml.org,2002:str");
YAML_ASSERT(doc[0].as<std::string>() == "a");
YAML_ASSERT(doc[1].as<char>() == 'b');
YAML_ASSERT(doc[2].as<std::string>() == "c");
YAML_ASSERT(doc[3].as<std::string>() == "c");
YAML_ASSERT(doc[4].Tag() == "tag:yaml.org,2002:str");
YAML_ASSERT(doc[4].as<std::string>() == "");
return true;
}
// 8.1
TEST BlockScalarHeader() {
YAML::Node doc = YAML::Load(ex8_1);
YAML_ASSERT(doc.size() == 4);
YAML_ASSERT(doc[0].as<std::string>() == "literal\n");
YAML_ASSERT(doc[1].as<std::string>() == " folded\n");
YAML_ASSERT(doc[2].as<std::string>() == "keep\n\n");
YAML_ASSERT(doc[3].as<std::string>() == " strip");
return true;
}
// 8.2
TEST BlockIndentationHeader() {
YAML::Node doc = YAML::Load(ex8_2);
YAML_ASSERT(doc.size() == 4);
YAML_ASSERT(doc[0].as<std::string>() == "detected\n");
YAML_ASSERT(doc[1].as<std::string>() == "\n\n# detected\n");
YAML_ASSERT(doc[2].as<std::string>() == " explicit\n");
YAML_ASSERT(doc[3].as<std::string>() == "\t\ndetected\n");
return true;
}
// 8.3
TEST InvalidBlockScalarIndentationIndicators() {
{
bool threw = false;
try {
YAML::Load(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 {
YAML::Load(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 {
YAML::Load(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() {
YAML::Node doc = YAML::Load(ex8_4);
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["strip"].as<std::string>() == "text");
YAML_ASSERT(doc["clip"].as<std::string>() == "text\n");
YAML_ASSERT(doc["keep"].as<std::string>() == "text\n");
return true;
}
// 8.5
TEST ChompingTrailingLines() {
YAML::Node doc = YAML::Load(ex8_5);
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["strip"].as<std::string>() == "# text");
YAML_ASSERT(doc["clip"].as<std::string>() == "# text\n");
YAML_ASSERT(doc["keep"].as<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() {
YAML::Node doc = YAML::Load(ex8_6);
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["strip"].as<std::string>() == "");
YAML_ASSERT(doc["clip"].as<std::string>() == "");
YAML_ASSERT(doc["keep"].as<std::string>() == "\n");
return true;
}
// 8.7
TEST LiteralScalar() {
YAML::Node doc = YAML::Load(ex8_7);
YAML_ASSERT(doc.as<std::string>() == "literal\n\ttext\n");
return true;
}
// 8.8
TEST LiteralContent() {
YAML::Node doc = YAML::Load(ex8_8);
YAML_ASSERT(doc.as<std::string>() == "\n\nliteral\n \n\ntext\n");
return true;
}
// 8.9
TEST FoldedScalar() {
YAML::Node doc = YAML::Load(ex8_9);
YAML_ASSERT(doc.as<std::string>() == "folded text\n");
return true;
}
// 8.10
TEST FoldedLines() {
YAML::Node doc = YAML::Load(ex8_10);
YAML_ASSERT(doc.as<std::string>() == "\nfolded line\nnext line\n * bullet\n\n * list\n * lines\n\nlast line\n");
return true;
}
// 8.11
TEST MoreIndentedLines() {
YAML::Node doc = YAML::Load(ex8_11);
YAML_ASSERT(doc.as<std::string>() == "\nfolded line\nnext line\n * bullet\n\n * list\n * lines\n\nlast line\n");
return true;
}
// 8.12
TEST EmptySeparationLines() {
YAML::Node doc = YAML::Load(ex8_12);
YAML_ASSERT(doc.as<std::string>() == "\nfolded line\nnext line\n * bullet\n\n * list\n * lines\n\nlast line\n");
return true;
}
// 8.13
TEST FinalEmptyLines() {
YAML::Node doc = YAML::Load(ex8_13);
YAML_ASSERT(doc.as<std::string>() == "\nfolded line\nnext line\n * bullet\n\n * list\n * lines\n\nlast line\n");
return true;
}
// 8.14
TEST BlockSequence() {
YAML::Node doc = YAML::Load(ex8_14);
YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc["block sequence"].size() == 2);
YAML_ASSERT(doc["block sequence"][0].as<std::string>() == "one");
YAML_ASSERT(doc["block sequence"][1].size() == 1);
YAML_ASSERT(doc["block sequence"][1]["two"].as<std::string>() == "three");
return true;
}
// 8.15
TEST BlockSequenceEntryTypes() {
YAML::Node doc = YAML::Load(ex8_15);
YAML_ASSERT(doc.size() == 4);
YAML_ASSERT(doc[0].IsNull());
YAML_ASSERT(doc[1].as<std::string>() == "block node\n");
YAML_ASSERT(doc[2].size() == 2);
YAML_ASSERT(doc[2][0].as<std::string>() == "one");
YAML_ASSERT(doc[2][1].as<std::string>() == "two");
YAML_ASSERT(doc[3].size() == 1);
YAML_ASSERT(doc[3]["one"].as<std::string>() == "two");
return true;
}
// 8.16
TEST BlockMappings() {
YAML::Node doc = YAML::Load(ex8_16);
YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc["block mapping"].size() == 1);
YAML_ASSERT(doc["block mapping"]["key"].as<std::string>() == "value");
return true;
}
// 8.17
TEST ExplicitBlockMappingEntries() {
YAML::Node doc = YAML::Load(ex8_17);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["explicit key"].IsNull());
YAML_ASSERT(doc["block key\n"].size() == 2);
YAML_ASSERT(doc["block key\n"][0].as<std::string>() == "one");
YAML_ASSERT(doc["block key\n"][1].as<std::string>() == "two");
return true;
}
// 8.18
TEST ImplicitBlockMappingEntries() {
YAML::Node doc = YAML::Load(ex8_18);
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["plain key"].as<std::string>() == "in-line value");
YAML_ASSERT(doc[YAML::Null].IsNull());
YAML_ASSERT(doc["quoted key"].size() == 1);
YAML_ASSERT(doc["quoted key"][0].as<std::string>() == "entry");
return true;
}
// 8.19
TEST CompactBlockMappings() {
YAML::Node doc = YAML::Load(ex8_19);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc[0].size() == 1);
YAML_ASSERT(doc[0]["sun"].as<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"].as<std::string>() == "white");
return true;
}
// 8.20
TEST BlockNodeTypes() {
YAML::Node doc = YAML::Load(ex8_20);
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc[0].as<std::string>() == "flow in block");
YAML_ASSERT(doc[1].as<std::string>() == "Block scalar\n");
YAML_ASSERT(doc[2].size() == 1);
YAML_ASSERT(doc[2]["foo"].as<std::string>() == "bar");
return true;
}
// 8.21
TEST BlockScalarNodes() {
YAML::Node doc = YAML::Load(ex8_21);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["literal"].as<std::string>() == "value"); // Note: I believe this is a bug in the YAML spec - it should be "value\n"
YAML_ASSERT(doc["folded"].as<std::string>() == "value");
YAML_ASSERT(doc["folded"].Tag() == "!foo");
return true;
}
// 8.22
TEST BlockCollectionNodes() {
YAML::Node doc = YAML::Load(ex8_22);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["sequence"].size() == 2);
YAML_ASSERT(doc["sequence"][0].as<std::string>() == "entry");
YAML_ASSERT(doc["sequence"][1].size() == 1);
YAML_ASSERT(doc["sequence"][1][0].as<std::string>() == "nested");
YAML_ASSERT(doc["mapping"].size() == 1);
YAML_ASSERT(doc["mapping"]["foo"].as<std::string>() == "bar");
return true;
}
}
}
#ifndef NODETESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODETESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
namespace Test {
bool RunNodeTests();
}
#endif // NODETESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A6666
#ifndef PARSERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define PARSERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
namespace Test {
bool RunParserTests();
}
#endif // PARSERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#include "tests.h"
#include "emittertests.h"
#include "nodetests.h"
#include "parsertests.h"
#include "spectests.h"
#include "yaml-cpp/yaml.h"
#include <fstream>
......@@ -12,12 +14,18 @@ namespace Test
void RunAll()
{
bool passed = true;
if(!RunParserTests())
passed = false;
if(!RunEmitterTests())
passed = false;
if(!RunSpecTests())
passed = false;
if(!RunNodeTests())
passed = false;
if(passed)
std::cout << "All tests passed!\n";
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment