From c2b22d6129b41978d4584cdd34509da8e512c0f4 Mon Sep 17 00:00:00 2001 From: Jesse Beder Date: Sat, 19 May 2012 17:53:43 -0500 Subject: [PATCH] Added framework for spectests with event handling --- test/core/spectests.cpp | 211 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 210 insertions(+), 1 deletion(-) diff --git a/test/core/spectests.cpp b/test/core/spectests.cpp index 9176d4b..eff7aad 100644 --- a/test/core/spectests.cpp +++ b/test/core/spectests.cpp @@ -1,11 +1,220 @@ #include "spectests.h" +#include "specexamples.h" +#include "yaml-cpp/yaml.h" +#include "yaml-cpp/eventhandler.h" +#include namespace Test { + struct Event { + enum Type { DocStart, DocEnd, Null, Alias, Scalar, SeqStart, SeqEnd, MapStart, MapEnd }; + + typedef YAML::Mark Mark; + typedef YAML::anchor_t anchor_t; + + Event(Type type_, const std::string& tag_, anchor_t anchor_, const std::string& scalar_): type(type_), tag(tag_), anchor(anchor_), scalar(scalar_) {} + + Type type; + std::string tag; + anchor_t anchor; + std::string scalar; + + std::ostream& write(std::ostream& out) const { + switch(type) { + case DocStart: + return out << "DocStart"; + case DocEnd: + return out << "DocEnd"; + case Null: + return out << "Null(" << anchor << ")"; + case Alias: + return out << "Alias(" << anchor << ")"; + case Scalar: + return out << "Scalar(" << tag << ", " << anchor << ", " << scalar << ")"; + case SeqStart: + return out << "SeqStart(" << tag << ", " << anchor << ")"; + case SeqEnd: + return out << "SeqEnd"; + case MapStart: + return out << "MapStart(" << tag << ", " << anchor << ")"; + case MapEnd: + return out << "MapEnd"; + } + assert(false); + return out; + } + }; + + std::ostream& operator << (std::ostream& out, const Event& event) { + return event.write(out); + } + + bool operator == (const Event& a, const Event& b) { + return a.type == b.type && a.tag == b.tag && a.anchor == b.anchor && a.scalar == b.scalar; + } + + bool operator != (const Event& a, const Event& b) { + return !(a == b); + } + + class MockEventHandler: public YAML::EventHandler + { + public: + typedef YAML::Mark Mark; + typedef YAML::anchor_t anchor_t; + + MockEventHandler() {} + + virtual void OnDocumentStart(const Mark&) { + m_actualEvents.push_back(Event(Event::DocStart, "", 0, "")); + } + + virtual void OnDocumentEnd() { + m_actualEvents.push_back(Event(Event::DocEnd, "", 0, "")); + } + + virtual void OnNull(const Mark&, anchor_t anchor) { + m_actualEvents.push_back(Event(Event::Null, "", anchor, "")); + } + + virtual void OnAlias(const Mark&, anchor_t anchor) { + m_actualEvents.push_back(Event(Event::Alias, "", anchor, "")); + } + + virtual void OnScalar(const Mark&, const std::string& tag, anchor_t anchor, const std::string& value) { + m_actualEvents.push_back(Event(Event::Scalar, tag, anchor, value)); + } + + virtual void OnSequenceStart(const Mark&, const std::string& tag, anchor_t anchor) { + m_actualEvents.push_back(Event(Event::SeqStart, tag, anchor, "")); + } + + virtual void OnSequenceEnd() { + m_actualEvents.push_back(Event(Event::SeqEnd, "", 0, "")); + } + + virtual void OnMapStart(const Mark&, const std::string& tag, anchor_t anchor) { + m_actualEvents.push_back(Event(Event::MapStart, tag, anchor, "")); + } + + virtual void OnMapEnd() { + m_actualEvents.push_back(Event(Event::MapEnd, "", 0, "")); + } + + void Expect(const Event& event) { m_expectedEvents.push_back(event); } + + Test::TEST Check() const { + std::size_t N = std::max(m_expectedEvents.size(), m_actualEvents.size()); + for(std::size_t i=0;i= m_expectedEvents.size()) { + std::stringstream out; + for(std::size_t j=0;j= m_actualEvents.size()) { + std::stringstream out; + for(std::size_t j=0;j m_expectedEvents; + std::vector m_actualEvents; + }; + +#define HANDLE(ex)\ + MockEventHandler handler;\ + std::stringstream stream(ex);\ + YAML::Parser parser(stream);\ + parser.HandleNextDocument(handler) + +#define HANDLE_NEXT(ex)\ + parser.HandleNextDocument(handler) + +#define EXPECT_DOC_START()\ + do {\ + handler.Expect(Event(Event::DocStart, "", 0, ""));\ + } while(false) + +#define EXPECT_DOC_END()\ + do {\ + handler.Expect(Event(Event::DocEnd, "", 0, ""));\ + } while(false) + +#define EXPECT_NULL(anchor)\ + do {\ + handler.Expect(Event(Event::Null, "", anchor, ""));\ + } while(false) + +#define EXPECT_ALIAS(anchor)\ + do {\ + handler.Expect(Event(Event::Alias, "", anchor, ""));\ + } while(false) + +#define EXPECT_SCALAR(tag, anchor, value)\ + do {\ + handler.Expect(Event(Event::Scalar, tag, anchor, value));\ + } while(false) + +#define EXPECT_SEQ_START(tag, anchor)\ + do {\ + handler.Expect(Event(Event::SeqStart, tag, anchor, ""));\ + } while(false) + +#define EXPECT_SEQ_END()\ + do {\ + handler.Expect(Event(Event::SeqEnd, "", 0, ""));\ + } while(false) + +#define EXPECT_MAP_START(tag, anchor)\ + do {\ + handler.Expect(Event(Event::MapStart, tag, anchor, ""));\ + } while(false) + +#define EXPECT_MAP_END()\ + do {\ + handler.Expect(Event(Event::MapEnd, "", 0, ""));\ + } while(false) + +#define DONE()\ + do {\ + return handler.Check();\ + } while(false) + namespace Spec { // 2.1 TEST SeqScalars() { - return " not written yet"; + HANDLE(ex2_1); + EXPECT_DOC_START(); + EXPECT_SEQ_START("?", 0); + EXPECT_SCALAR("?", 0, "Mark McGwire"); + EXPECT_SCALAR("?", 0, "Sammy Sosa"); + EXPECT_SCALAR("?", 0, "Ken Griffey"); + EXPECT_SEQ_END(); + EXPECT_DOC_END(); + DONE(); } // 2.2