Files
1261Nat/test/lib/FakeIt/fakeit.hpp
2017-02-16 00:55:04 +01:00

19631 lines
584 KiB
C++

#pragma once
/*
* FakeIt - A Simplified C++ Mocking Framework
* Copyright (c) Eran Pe'er 2013
* Generated: 2016-10-01 07:49:36.977632
* Distributed under the MIT License. Please refer to the LICENSE file at:
* https://github.com/eranpeer/FakeIt
*/
#ifndef fakeit_h__
#define fakeit_h__
#include <functional>
#include <memory>
#include <set>
#include <vector>
#include <stdexcept>
#if defined (__GNUG__) || _MSC_VER >= 1900
#define THROWS noexcept(false)
#define NO_THROWS noexcept(true)
#elif defined (_MSC_VER)
#define THROWS throw(...)
#define NO_THROWS
#endif
#include <typeinfo>
#include <unordered_set>
#include <tuple>
#include <string>
#include <iosfwd>
#include <atomic>
#include <tuple>
namespace fakeit {
template<class C>
struct naked_type {
typedef typename std::remove_cv<typename std::remove_reference<C>::type>::type type;
};
template< class T > struct tuple_arg { typedef T type; };
template< class T > struct tuple_arg < T& > { typedef T& type; };
template< class T > struct tuple_arg < T&& > { typedef T&& type; };
template<typename... arglist>
using ArgumentsTuple = std::tuple < arglist... > ;
template< class T > struct test_arg { typedef T& type; };
template< class T > struct test_arg< T& > { typedef T& type; };
template< class T > struct test_arg< T&& > { typedef T& type; };
template< class T > struct production_arg { typedef T& type; };
template< class T > struct production_arg< T& > { typedef T& type; };
template< class T > struct production_arg< T&& > { typedef T&& type; };
template <typename T>
class is_ostreamable {
struct no {};
#if defined(_MSC_VER) && _MSC_VER < 1900
template <typename T1>
static decltype(operator<<(std::declval<std::ostream&>(), std::declval<const T1>())) test(std::ostream &s, const T1 &t);
#else
template <typename T1>
static auto test(std::ostream &s, const T1 &t) -> decltype(s << t);
#endif
static no test(...);
public:
static const bool value =
std::is_arithmetic<T>::value ||
std::is_pointer<T>::value ||
std::is_same<decltype(test(*(std::ostream *)nullptr,
std::declval<T>())), std::ostream &>::value;
};
template <>
class is_ostreamable<std::ios_base& (*)(std::ios_base&)> {
public:
static const bool value = true;
};
template <typename CharT, typename Traits>
class is_ostreamable<std::basic_ios<CharT,Traits>& (*)(std::basic_ios<CharT,Traits>&)> {
public:
static const bool value = true;
};
template <typename CharT, typename Traits>
class is_ostreamable<std::basic_ostream<CharT,Traits>& (*)(std::basic_ostream<CharT,Traits>&)> {
public:
static const bool value = true;
};
template<typename R, typename... arglist>
struct VTableMethodType {
#if defined (__GNUG__)
typedef R(*type)(void *, arglist...);
#elif defined (_MSC_VER)
typedef R(__thiscall *type)(void *, arglist...);
#endif
};
}
#include <typeinfo>
#include <tuple>
#include <string>
#include <iosfwd>
#include <sstream>
#include <string>
namespace fakeit {
struct FakeitContext;
template<typename C>
struct MockObject {
virtual ~MockObject() THROWS { };
virtual C &get() = 0;
virtual FakeitContext &getFakeIt() = 0;
};
struct MethodInfo {
static unsigned int nextMethodOrdinal() {
static std::atomic_uint ordinal{0};
return ++ordinal;
}
MethodInfo(unsigned int anId, std::string aName) :
_id(anId), _name(aName) { }
unsigned int id() const {
return _id;
}
std::string name() const {
return _name;
}
void setName(const std::string &value) {
_name = value;
}
private:
unsigned int _id;
std::string _name;
};
struct UnknownMethod {
static MethodInfo &instance() {
static MethodInfo instance(MethodInfo::nextMethodOrdinal(), "unknown");
return instance;
}
};
}
namespace fakeit {
class Destructible {
public:
virtual ~Destructible() {}
};
}
namespace fakeit {
struct Invocation : Destructible {
static unsigned int nextInvocationOrdinal() {
static std::atomic_uint invocationOrdinal{0};
return ++invocationOrdinal;
}
struct Matcher {
virtual ~Matcher() THROWS {
}
virtual bool matches(Invocation &invocation) = 0;
virtual std::string format() const = 0;
};
Invocation(unsigned int ordinal, MethodInfo &method) :
_ordinal(ordinal), _method(method), _isVerified(false) {
}
virtual ~Invocation() override = default;
unsigned int getOrdinal() const {
return _ordinal;
}
MethodInfo &getMethod() const {
return _method;
}
void markAsVerified() {
_isVerified = true;
}
bool isVerified() const {
return _isVerified;
}
virtual std::string format() const = 0;
private:
const unsigned int _ordinal;
MethodInfo &_method;
bool _isVerified;
};
}
#include <iosfwd>
#include <tuple>
#include <string>
#include <sstream>
#include <ostream>
namespace fakeit {
template<typename T, class Enable = void>
struct Formatter;
template <>
struct Formatter<bool>
{
static std::string format(bool const &val)
{
return val ? "true" : "false";
}
};
template <>
struct Formatter<char>
{
static std::string format(char const &val)
{
std::string s;
s += "'";
s += val;
s += "'";
return s;
}
};
template<class C>
struct Formatter<C, typename std::enable_if<!is_ostreamable<C>::value>::type> {
static std::string format(C const &)
{
return "?";
}
};
template<class C>
struct Formatter<C, typename std::enable_if<is_ostreamable<C>::value>::type> {
static std::string format(C const &val)
{
std::ostringstream os;
os << val;
return os.str();
}
};
template <typename T>
using TypeFormatter = Formatter<typename fakeit::naked_type<T>::type>;
}
namespace fakeit {
template<class Tuple, std::size_t N>
struct TuplePrinter {
static void print(std::ostream &strm, const Tuple &t) {
TuplePrinter<Tuple, N - 1>::print(strm, t);
strm << ", " << fakeit::TypeFormatter<decltype(std::get<N - 1>(t))>::format(std::get<N - 1>(t));
}
};
template<class Tuple>
struct TuplePrinter<Tuple, 1> {
static void print(std::ostream &strm, const Tuple &t) {
strm << fakeit::TypeFormatter<decltype(std::get<0>(t))>::format(std::get<0>(t));
}
};
template<class Tuple>
struct TuplePrinter<Tuple, 0> {
static void print(std::ostream &, const Tuple &) {
}
};
template<class ... Args>
void print(std::ostream &strm, const std::tuple<Args...> &t) {
strm << "(";
TuplePrinter<decltype(t), sizeof...(Args)>::print(strm, t);
strm << ")";
}
template<class ... Args>
std::ostream &operator<<(std::ostream &strm, const std::tuple<Args...> &t) {
print(strm, t);
return strm;
}
}
namespace fakeit {
template<typename ... arglist>
struct ActualInvocation : public Invocation {
struct Matcher : public virtual Destructible {
virtual bool matches(ActualInvocation<arglist...> &actualInvocation) = 0;
virtual std::string format() const = 0;
};
ActualInvocation(unsigned int ordinal, MethodInfo &method, const typename fakeit::production_arg<arglist>::type... args) :
Invocation(ordinal, method), _matcher{ nullptr }
, actualArguments{ std::forward<const typename fakeit::production_arg<arglist>::type>(args)... }
{
}
ArgumentsTuple<arglist...> & getActualArguments() {
return actualArguments;
}
void setActualMatcher(Matcher *matcher) {
this->_matcher = matcher;
}
Matcher *getActualMatcher() {
return _matcher;
}
virtual std::string format() const override {
std::ostringstream out;
out << getMethod().name();
print(out, actualArguments);
return out.str();
}
private:
Matcher *_matcher;
ArgumentsTuple<arglist...> actualArguments;
};
template<typename ... arglist>
std::ostream &operator<<(std::ostream &strm, const ActualInvocation<arglist...> &ai) {
strm << ai.format();
return strm;
}
}
#include <unordered_set>
namespace fakeit {
struct ActualInvocationsSource {
virtual void getActualInvocations(std::unordered_set<fakeit::Invocation *> &into) const = 0;
virtual ~ActualInvocationsSource() NO_THROWS { };
};
struct InvocationsSourceProxy : public ActualInvocationsSource {
InvocationsSourceProxy(ActualInvocationsSource *inner) :
_inner(inner) {
}
void getActualInvocations(std::unordered_set<fakeit::Invocation *> &into) const override {
_inner->getActualInvocations(into);
}
private:
std::shared_ptr<ActualInvocationsSource> _inner;
};
struct UnverifiedInvocationsSource : public ActualInvocationsSource {
UnverifiedInvocationsSource(InvocationsSourceProxy decorated) : _decorated(decorated) {
}
void getActualInvocations(std::unordered_set<fakeit::Invocation *> &into) const override {
std::unordered_set<fakeit::Invocation *> all;
_decorated.getActualInvocations(all);
for (fakeit::Invocation *i : all) {
if (!i->isVerified()) {
into.insert(i);
}
}
}
private:
InvocationsSourceProxy _decorated;
};
struct AggregateInvocationsSource : public ActualInvocationsSource {
AggregateInvocationsSource(std::vector<ActualInvocationsSource *> &sources) : _sources(sources) {
}
void getActualInvocations(std::unordered_set<fakeit::Invocation *> &into) const override {
std::unordered_set<fakeit::Invocation *> tmp;
for (ActualInvocationsSource *source : _sources) {
source->getActualInvocations(tmp);
}
filter(tmp, into);
}
protected:
bool shouldInclude(fakeit::Invocation *) const {
return true;
}
private:
std::vector<ActualInvocationsSource *> _sources;
void filter(std::unordered_set<Invocation *> &source, std::unordered_set<Invocation *> &target) const {
for (Invocation *i:source) {
if (shouldInclude(i)) {
target.insert(i);
}
}
}
};
}
namespace fakeit {
class Sequence {
private:
protected:
Sequence() {
}
virtual ~Sequence() THROWS {
}
public:
virtual void getExpectedSequence(std::vector<Invocation::Matcher *> &into) const = 0;
virtual void getInvolvedMocks(std::vector<ActualInvocationsSource *> &into) const = 0;
virtual unsigned int size() const = 0;
friend class VerifyFunctor;
};
class ConcatenatedSequence : public virtual Sequence {
private:
const Sequence &s1;
const Sequence &s2;
protected:
ConcatenatedSequence(const Sequence &seq1, const Sequence &seq2) :
s1(seq1), s2(seq2) {
}
public:
virtual ~ConcatenatedSequence() {
}
unsigned int size() const override {
return s1.size() + s2.size();
}
const Sequence &getLeft() const {
return s1;
}
const Sequence &getRight() const {
return s2;
}
void getExpectedSequence(std::vector<Invocation::Matcher *> &into) const override {
s1.getExpectedSequence(into);
s2.getExpectedSequence(into);
}
virtual void getInvolvedMocks(std::vector<ActualInvocationsSource *> &into) const override {
s1.getInvolvedMocks(into);
s2.getInvolvedMocks(into);
}
friend inline ConcatenatedSequence operator+(const Sequence &s1, const Sequence &s2);
};
class RepeatedSequence : public virtual Sequence {
private:
const Sequence &_s;
const int times;
protected:
RepeatedSequence(const Sequence &s, const int t) :
_s(s), times(t) {
}
public:
~RepeatedSequence() {
}
unsigned int size() const override {
return _s.size() * times;
}
friend inline RepeatedSequence operator*(const Sequence &s, int times);
friend inline RepeatedSequence operator*(int times, const Sequence &s);
void getInvolvedMocks(std::vector<ActualInvocationsSource *> &into) const override {
_s.getInvolvedMocks(into);
}
void getExpectedSequence(std::vector<Invocation::Matcher *> &into) const override {
for (int i = 0; i < times; i++)
_s.getExpectedSequence(into);
}
int getTimes() const {
return times;
}
const Sequence &getSequence() const {
return _s;
}
};
inline ConcatenatedSequence operator+(const Sequence &s1, const Sequence &s2) {
return ConcatenatedSequence(s1, s2);
}
inline RepeatedSequence operator*(const Sequence &s, int times) {
if (times <= 0)
throw std::invalid_argument("times");
return RepeatedSequence(s, times);
}
inline RepeatedSequence operator*(int times, const Sequence &s) {
if (times <= 0)
throw std::invalid_argument("times");
return RepeatedSequence(s, times);
}
}
namespace fakeit {
enum class VerificationType {
Exact, AtLeast, NoMoreInvocations
};
enum class UnexpectedType {
Unmocked, Unmatched
};
struct VerificationEvent {
VerificationEvent(VerificationType aVerificationType) :
_verificationType(aVerificationType), _line(0) {
}
virtual ~VerificationEvent() = default;
VerificationType verificationType() const {
return _verificationType;
}
void setFileInfo(std::string aFile, int aLine, std::string aCallingMethod) {
_file = aFile;
_callingMethod = aCallingMethod;
_line = aLine;
}
std::string file() const {
return _file;
}
int line() const {
return _line;
}
const std::string &callingMethod() const {
return _callingMethod;
}
private:
VerificationType _verificationType;
std::string _file;
int _line;
std::string _callingMethod;
};
struct NoMoreInvocationsVerificationEvent : public VerificationEvent {
~NoMoreInvocationsVerificationEvent() = default;
NoMoreInvocationsVerificationEvent(
std::vector<Invocation *> &allTheIvocations,
std::vector<Invocation *> &anUnverifedIvocations) :
VerificationEvent(VerificationType::NoMoreInvocations),
_allIvocations(allTheIvocations),
_unverifedIvocations(anUnverifedIvocations) {
}
const std::vector<Invocation *> &allIvocations() const {
return _allIvocations;
}
const std::vector<Invocation *> &unverifedIvocations() const {
return _unverifedIvocations;
}
private:
const std::vector<Invocation *> _allIvocations;
const std::vector<Invocation *> _unverifedIvocations;
};
struct SequenceVerificationEvent : public VerificationEvent {
~SequenceVerificationEvent() = default;
SequenceVerificationEvent(VerificationType aVerificationType,
std::vector<Sequence *> &anExpectedPattern,
std::vector<Invocation *> &anActualSequence,
int anExpectedCount,
int anActualCount) :
VerificationEvent(aVerificationType),
_expectedPattern(anExpectedPattern),
_actualSequence(anActualSequence),
_expectedCount(anExpectedCount),
_actualCount(anActualCount)
{
}
const std::vector<Sequence *> &expectedPattern() const {
return _expectedPattern;
}
const std::vector<Invocation *> &actualSequence() const {
return _actualSequence;
}
int expectedCount() const {
return _expectedCount;
}
int actualCount() const {
return _actualCount;
}
private:
const std::vector<Sequence *> _expectedPattern;
const std::vector<Invocation *> _actualSequence;
const int _expectedCount;
const int _actualCount;
};
struct UnexpectedMethodCallEvent {
UnexpectedMethodCallEvent(UnexpectedType unexpectedType, const Invocation &invocation) :
_unexpectedType(unexpectedType), _invocation(invocation) {
}
const Invocation &getInvocation() const {
return _invocation;
}
UnexpectedType getUnexpectedType() const {
return _unexpectedType;
}
const UnexpectedType _unexpectedType;
const Invocation &_invocation;
};
}
namespace fakeit {
struct VerificationEventHandler {
virtual void handle(const SequenceVerificationEvent &e) = 0;
virtual void handle(const NoMoreInvocationsVerificationEvent &e) = 0;
};
struct EventHandler : public VerificationEventHandler {
using VerificationEventHandler::handle;
virtual void handle(const UnexpectedMethodCallEvent &e) = 0;
};
}
#include <vector>
#include <string>
namespace fakeit {
struct UnexpectedMethodCallEvent;
struct SequenceVerificationEvent;
struct NoMoreInvocationsVerificationEvent;
struct EventFormatter {
virtual std::string format(const fakeit::UnexpectedMethodCallEvent &e) = 0;
virtual std::string format(const fakeit::SequenceVerificationEvent &e) = 0;
virtual std::string format(const fakeit::NoMoreInvocationsVerificationEvent &e) = 0;
};
}
namespace fakeit {
struct FakeitContext : public EventHandler, protected EventFormatter {
virtual ~FakeitContext() = default;
void handle(const UnexpectedMethodCallEvent &e) override {
fireEvent(e);
auto &eh = getTestingFrameworkAdapter();
eh.handle(e);
}
void handle(const SequenceVerificationEvent &e) override {
fireEvent(e);
auto &eh = getTestingFrameworkAdapter();
return eh.handle(e);
}
void handle(const NoMoreInvocationsVerificationEvent &e) override {
fireEvent(e);
auto &eh = getTestingFrameworkAdapter();
return eh.handle(e);
}
std::string format(const UnexpectedMethodCallEvent &e) override {
auto &eventFormatter = getEventFormatter();
return eventFormatter.format(e);
}
std::string format(const SequenceVerificationEvent &e) override {
auto &eventFormatter = getEventFormatter();
return eventFormatter.format(e);
}
std::string format(const NoMoreInvocationsVerificationEvent &e) override {
auto &eventFormatter = getEventFormatter();
return eventFormatter.format(e);
}
void addEventHandler(EventHandler &eventListener) {
_eventListeners.push_back(&eventListener);
}
void clearEventHandlers() {
_eventListeners.clear();
}
protected:
virtual EventHandler &getTestingFrameworkAdapter() = 0;
virtual EventFormatter &getEventFormatter() = 0;
private:
std::vector<EventHandler *> _eventListeners;
void fireEvent(const NoMoreInvocationsVerificationEvent &evt) {
for (auto listener : _eventListeners)
listener->handle(evt);
}
void fireEvent(const UnexpectedMethodCallEvent &evt) {
for (auto listener : _eventListeners)
listener->handle(evt);
}
void fireEvent(const SequenceVerificationEvent &evt) {
for (auto listener : _eventListeners)
listener->handle(evt);
}
};
}
#include <iostream>
#include <iosfwd>
namespace fakeit {
struct DefaultEventFormatter : public EventFormatter {
virtual std::string format(const UnexpectedMethodCallEvent &e) override {
std::ostringstream out;
out << "Unexpected method invocation: ";
out << e.getInvocation().format() << std::endl;
if (UnexpectedType::Unmatched == e.getUnexpectedType()) {
out << " Could not find Any recorded behavior to support this method call.";
} else {
out << " An unmocked method was invoked. All used virtual methods must be stubbed!";
}
return out.str();
}
virtual std::string format(const SequenceVerificationEvent &e) override {
std::ostringstream out;
out << "Verification error" << std::endl;
out << "Expected pattern: ";
const std::vector<fakeit::Sequence *> expectedPattern = e.expectedPattern();
out << formatExpectedPattern(expectedPattern) << std::endl;
out << "Expected matches: ";
formatExpectedCount(out, e.verificationType(), e.expectedCount());
out << std::endl;
out << "Actual matches : " << e.actualCount() << std::endl;
auto actualSequence = e.actualSequence();
out << "Actual sequence : total of " << actualSequence.size() << " actual invocations";
if (actualSequence.size() == 0) {
out << ".";
} else {
out << ":" << std::endl;
}
formatInvocationList(out, actualSequence);
return out.str();
}
virtual std::string format(const NoMoreInvocationsVerificationEvent &e) override {
std::ostringstream out;
out << "Verification error" << std::endl;
out << "Expected no more invocations!! But the following unverified invocations were found:" << std::endl;
formatInvocationList(out, e.unverifedIvocations());
return out.str();
}
private:
static std::string formatSequence(const Sequence &val) {
const ConcatenatedSequence *cs = dynamic_cast<const ConcatenatedSequence *>(&val);
if (cs) {
return format(*cs);
}
const RepeatedSequence *rs = dynamic_cast<const RepeatedSequence *>(&val);
if (rs) {
return format(*rs);
}
std::vector<Invocation::Matcher *> vec;
val.getExpectedSequence(vec);
return vec[0]->format();
}
static void formatExpectedCount(std::ostream &out, fakeit::VerificationType verificationType,
int expectedCount) {
if (verificationType == fakeit::VerificationType::Exact)
out << "exactly ";
if (verificationType == fakeit::VerificationType::AtLeast)
out << "at least ";
out << expectedCount;
}
static void formatInvocationList(std::ostream &out, const std::vector<fakeit::Invocation *> &actualSequence) {
size_t max_size = actualSequence.size();
if (max_size > 5)
max_size = 5;
for (unsigned int i = 0; i < max_size; i++) {
out << " ";
auto invocation = actualSequence[i];
out << invocation->format();
if (i < max_size - 1)
out << std::endl;
}
if (actualSequence.size() > max_size)
out << std::endl << " ...";
}
static std::string format(const ConcatenatedSequence &val) {
std::ostringstream out;
out << formatSequence(val.getLeft()) << " + " << formatSequence(val.getRight());
return out.str();
}
static std::string format(const RepeatedSequence &val) {
std::ostringstream out;
const ConcatenatedSequence *cs = dynamic_cast<const ConcatenatedSequence *>(&val.getSequence());
const RepeatedSequence *rs = dynamic_cast<const RepeatedSequence *>(&val.getSequence());
if (rs || cs)
out << '(';
out << formatSequence(val.getSequence());
if (rs || cs)
out << ')';
out << " * " << val.getTimes();
return out.str();
}
static std::string formatExpectedPattern(const std::vector<fakeit::Sequence *> &expectedPattern) {
std::string expectedPatternStr;
for (unsigned int i = 0; i < expectedPattern.size(); i++) {
Sequence *s = expectedPattern[i];
expectedPatternStr += formatSequence(*s);
if (i < expectedPattern.size() - 1)
expectedPatternStr += " ... ";
}
return expectedPatternStr;
}
};
}
namespace fakeit {
struct FakeitException {
std::exception err;
virtual ~FakeitException() = default;
virtual std::string what() const = 0;
friend std::ostream &operator<<(std::ostream &os, const FakeitException &val) {
os << val.what();
return os;
}
};
struct UnexpectedMethodCallException : public FakeitException {
UnexpectedMethodCallException(std::string format) :
_format(format) {
}
virtual std::string what() const override {
return _format;
}
private:
std::string _format;
};
}
namespace fakeit {
struct DefaultEventLogger : public fakeit::EventHandler {
DefaultEventLogger(EventFormatter &formatter) : _formatter(formatter), _out(std::cout) { }
virtual void handle(const UnexpectedMethodCallEvent &e) override {
_out << _formatter.format(e) << std::endl;
}
virtual void handle(const SequenceVerificationEvent &e) override {
_out << _formatter.format(e) << std::endl;
}
virtual void handle(const NoMoreInvocationsVerificationEvent &e) override {
_out << _formatter.format(e) << std::endl;
}
private:
EventFormatter &_formatter;
std::ostream &_out;
};
}
namespace fakeit {
class AbstractFakeit : public FakeitContext {
public:
virtual ~AbstractFakeit() = default;
protected:
virtual fakeit::EventHandler &accessTestingFrameworkAdapter() = 0;
virtual EventFormatter &accessEventFormatter() = 0;
};
class DefaultFakeit : public AbstractFakeit {
DefaultEventFormatter _formatter;
fakeit::EventFormatter *_customFormatter;
fakeit::EventHandler *_testingFrameworkAdapter;
public:
DefaultFakeit() : _formatter(),
_customFormatter(nullptr),
_testingFrameworkAdapter(nullptr) {
}
virtual ~DefaultFakeit() = default;
void setCustomEventFormatter(fakeit::EventFormatter &customEventFormatter) {
_customFormatter = &customEventFormatter;
}
void resetCustomEventFormatter() {
_customFormatter = nullptr;
}
void setTestingFrameworkAdapter(fakeit::EventHandler &testingFrameforkAdapter) {
_testingFrameworkAdapter = &testingFrameforkAdapter;
}
void resetTestingFrameworkAdapter() {
_testingFrameworkAdapter = nullptr;
}
protected:
fakeit::EventHandler &getTestingFrameworkAdapter() override {
if (_testingFrameworkAdapter)
return *_testingFrameworkAdapter;
return accessTestingFrameworkAdapter();
}
EventFormatter &getEventFormatter() override {
if (_customFormatter)
return *_customFormatter;
return accessEventFormatter();
}
EventFormatter &accessEventFormatter() override {
return _formatter;
}
};
}
#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_HPP_INCLUDED
#ifdef __clang__
# pragma clang system_header
#elif defined __GNUC__
# pragma GCC system_header
#endif
#ifdef __clang__
# ifdef __ICC
# pragma warning(push)
# pragma warning(disable: 161 1682)
# else
# pragma clang diagnostic ignored "-Wglobal-constructors"
# pragma clang diagnostic ignored "-Wvariadic-macros"
# pragma clang diagnostic ignored "-Wc99-extensions"
# pragma clang diagnostic ignored "-Wunused-variable"
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wpadded"
# pragma clang diagnostic ignored "-Wc++98-compat"
# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
# pragma clang diagnostic ignored "-Wswitch-enum"
# pragma clang diagnostic ignored "-Wcovered-switch-default"
# endif
#elif defined __GNUC__
# pragma GCC diagnostic ignored "-Wvariadic-macros"
# pragma GCC diagnostic ignored "-Wunused-variable"
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wpadded"
#endif
#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
# define CATCH_IMPL
#endif
#ifdef CATCH_IMPL
# ifndef CLARA_CONFIG_MAIN
# define CLARA_CONFIG_MAIN_NOT_DEFINED
# define CLARA_CONFIG_MAIN
# endif
#endif
#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
#define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
#include <sstream>
#include <stdexcept>
#include <algorithm>
#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
#ifdef __clang__
# if __has_feature(cxx_nullptr)
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
# endif
# if __has_feature(cxx_noexcept)
# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
# endif
#endif
#ifdef __BORLANDC__
#endif
#ifdef __EDG_VERSION__
#endif
#ifdef __DMC__
#endif
#ifdef __GNUC__
#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
#endif
#endif
#ifdef _MSC_VER
#if (_MSC_VER >= 1600)
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
#endif
#if (_MSC_VER >= 1900 )
#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
#endif
#endif
#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
( defined __GNUC__ && __GNUC__ >= 3 ) || \
( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
#endif
#if defined(__cplusplus) && __cplusplus >= 201103L
# define CATCH_CPP11_OR_GREATER
# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
# endif
# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
# endif
# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
# endif
# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
# endif
# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
# endif
# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
# endif
# if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)
# define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG
# endif
# if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)
# define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE
# endif
# if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
# endif
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_NULLPTR
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_NOEXCEPT
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_GENERATED_METHODS
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_IS_ENUM
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_TUPLE
#endif
#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
# define CATCH_CONFIG_VARIADIC_MACROS
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_LONG_LONG
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_OVERRIDE
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_UNIQUE_PTR
#endif
#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
# define CATCH_NOEXCEPT noexcept
# define CATCH_NOEXCEPT_IS(x) noexcept(x)
#else
# define CATCH_NOEXCEPT throw()
# define CATCH_NOEXCEPT_IS(x)
#endif
#ifdef CATCH_CONFIG_CPP11_NULLPTR
# define CATCH_NULL nullptr
#else
# define CATCH_NULL NULL
#endif
#ifdef CATCH_CONFIG_CPP11_OVERRIDE
# define CATCH_OVERRIDE override
#else
# define CATCH_OVERRIDE
#endif
#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR
# define CATCH_AUTO_PTR( T ) std::unique_ptr<T>
#else
# define CATCH_AUTO_PTR( T ) std::auto_ptr<T>
#endif
namespace Catch {
struct IConfig;
struct CaseSensitive { enum Choice {
Yes,
No
}; };
class NonCopyable {
#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
NonCopyable( NonCopyable const& ) = delete;
NonCopyable( NonCopyable && ) = delete;
NonCopyable& operator = ( NonCopyable const& ) = delete;
NonCopyable& operator = ( NonCopyable && ) = delete;
#else
NonCopyable( NonCopyable const& info );
NonCopyable& operator = ( NonCopyable const& );
#endif
protected:
NonCopyable() {}
virtual ~NonCopyable();
};
class SafeBool {
public:
typedef void (SafeBool::*type)() const;
static type makeSafe( bool value ) {
return value ? &SafeBool::trueValue : 0;
}
private:
void trueValue() const {}
};
template<typename ContainerT>
inline void deleteAll( ContainerT& container ) {
typename ContainerT::const_iterator it = container.begin();
typename ContainerT::const_iterator itEnd = container.end();
for(; it != itEnd; ++it )
delete *it;
}
template<typename AssociativeContainerT>
inline void deleteAllValues( AssociativeContainerT& container ) {
typename AssociativeContainerT::const_iterator it = container.begin();
typename AssociativeContainerT::const_iterator itEnd = container.end();
for(; it != itEnd; ++it )
delete it->second;
}
bool startsWith( std::string const& s, std::string const& prefix );
bool endsWith( std::string const& s, std::string const& suffix );
bool contains( std::string const& s, std::string const& infix );
void toLowerInPlace( std::string& s );
std::string toLower( std::string const& s );
std::string trim( std::string const& str );
bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
struct pluralise {
pluralise( std::size_t count, std::string const& label );
friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
std::size_t m_count;
std::string m_label;
};
struct SourceLineInfo {
SourceLineInfo();
SourceLineInfo( char const* _file, std::size_t _line );
SourceLineInfo( SourceLineInfo const& other );
# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
SourceLineInfo( SourceLineInfo && ) = default;
SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
SourceLineInfo& operator = ( SourceLineInfo && ) = default;
# endif
bool empty() const;
bool operator == ( SourceLineInfo const& other ) const;
bool operator < ( SourceLineInfo const& other ) const;
std::string file;
std::size_t line;
};
std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
inline bool isTrue( bool value ){ return value; }
inline bool alwaysTrue() { return true; }
inline bool alwaysFalse() { return false; }
void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
void seedRng( IConfig const& config );
unsigned int rngSeed();
struct StreamEndStop {
std::string operator+() {
return std::string();
}
};
template<typename T>
T const& operator + ( T const& value, StreamEndStop ) {
return value;
}
}
#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
#include <ostream>
namespace Catch {
class NotImplementedException : public std::exception
{
public:
NotImplementedException( SourceLineInfo const& lineInfo );
NotImplementedException( NotImplementedException const& ) {}
virtual ~NotImplementedException() CATCH_NOEXCEPT {}
virtual const char* what() const CATCH_NOEXCEPT;
private:
std::string m_what;
SourceLineInfo m_lineInfo;
};
}
#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
#include <string>
namespace Catch {
struct IGeneratorInfo {
virtual ~IGeneratorInfo();
virtual bool moveNext() = 0;
virtual std::size_t getCurrentIndex() const = 0;
};
struct IGeneratorsForTest {
virtual ~IGeneratorsForTest();
virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
virtual bool moveNext() = 0;
};
IGeneratorsForTest* createGeneratorsForTest();
}
#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#endif
namespace Catch {
template<typename T>
class Ptr {
public:
Ptr() : m_p( CATCH_NULL ){}
Ptr( T* p ) : m_p( p ){
if( m_p )
m_p->addRef();
}
Ptr( Ptr const& other ) : m_p( other.m_p ){
if( m_p )
m_p->addRef();
}
~Ptr(){
if( m_p )
m_p->release();
}
void reset() {
if( m_p )
m_p->release();
m_p = CATCH_NULL;
}
Ptr& operator = ( T* p ){
Ptr temp( p );
swap( temp );
return *this;
}
Ptr& operator = ( Ptr const& other ){
Ptr temp( other );
swap( temp );
return *this;
}
void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
T* get() const{ return m_p; }
T& operator*() const { return *m_p; }
T* operator->() const { return m_p; }
bool operator !() const { return m_p == CATCH_NULL; }
operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); }
private:
T* m_p;
};
struct IShared : NonCopyable {
virtual ~IShared();
virtual void addRef() const = 0;
virtual void release() const = 0;
};
template<typename T = IShared>
struct SharedImpl : T {
SharedImpl() : m_rc( 0 ){}
virtual void addRef() const {
++m_rc;
}
virtual void release() const {
if( --m_rc == 0 )
delete this;
}
mutable unsigned int m_rc;
};
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#include <memory>
#include <vector>
#include <stdlib.h>
namespace Catch {
class TestCase;
class Stream;
struct IResultCapture;
struct IRunner;
struct IGeneratorsForTest;
struct IConfig;
struct IContext
{
virtual ~IContext();
virtual IResultCapture* getResultCapture() = 0;
virtual IRunner* getRunner() = 0;
virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
virtual bool advanceGeneratorsForCurrentTest() = 0;
virtual Ptr<IConfig const> getConfig() const = 0;
};
struct IMutableContext : IContext
{
virtual ~IMutableContext();
virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
virtual void setRunner( IRunner* runner ) = 0;
virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
};
IContext& getCurrentContext();
IMutableContext& getCurrentMutableContext();
void cleanUpContext();
Stream createStream( std::string const& streamName );
}
#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
#include <vector>
namespace Catch {
class TestSpec;
struct ITestCase : IShared {
virtual void invoke () const = 0;
protected:
virtual ~ITestCase();
};
class TestCase;
struct IConfig;
struct ITestCaseRegistry {
virtual ~ITestCaseRegistry();
virtual std::vector<TestCase> const& getAllTests() const = 0;
virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
};
bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
}
namespace Catch {
template<typename C>
class MethodTestCase : public SharedImpl<ITestCase> {
public:
MethodTestCase( void (C::*method)() ) : m_method( method ) {}
virtual void invoke() const {
C obj;
(obj.*m_method)();
}
private:
virtual ~MethodTestCase() {}
void (C::*m_method)();
};
typedef void(*TestFunction)();
struct NameAndDesc {
NameAndDesc( const char* _name = "", const char* _description= "" )
: name( _name ), description( _description )
{}
const char* name;
const char* description;
};
void registerTestCase
( ITestCase* testCase,
char const* className,
NameAndDesc const& nameAndDesc,
SourceLineInfo const& lineInfo );
struct AutoReg {
AutoReg
( TestFunction function,
SourceLineInfo const& lineInfo,
NameAndDesc const& nameAndDesc );
template<typename C>
AutoReg
( void (C::*method)(),
char const* className,
NameAndDesc const& nameAndDesc,
SourceLineInfo const& lineInfo ) {
registerTestCase
( new MethodTestCase<C>( method ),
className,
nameAndDesc,
lineInfo );
}
~AutoReg();
private:
AutoReg( AutoReg const& );
void operator= ( AutoReg const& );
};
void registerTestCaseFunction
( TestFunction function,
SourceLineInfo const& lineInfo,
NameAndDesc const& nameAndDesc );
}
#ifdef CATCH_CONFIG_VARIADIC_MACROS
#define INTERNAL_CATCH_TESTCASE( ... ) \
static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\
namespace{ \
struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
void test(); \
}; \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
} \
void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );
#else
#define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
namespace{ \
struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
void test(); \
}; \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
} \
void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );
#endif
#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
namespace Catch {
struct ResultWas { enum OfType {
Unknown = -1,
Ok = 0,
Info = 1,
Warning = 2,
FailureBit = 0x10,
ExpressionFailed = FailureBit | 1,
ExplicitFailure = FailureBit | 2,
Exception = 0x100 | FailureBit,
ThrewException = Exception | 1,
DidntThrowException = Exception | 2,
FatalErrorCondition = 0x200 | FailureBit
}; };
inline bool isOk( ResultWas::OfType resultType ) {
return ( resultType & ResultWas::FailureBit ) == 0;
}
inline bool isJustInfo( int flags ) {
return flags == ResultWas::Info;
}
struct ResultDisposition { enum Flags {
Normal = 0x01,
ContinueOnFailure = 0x02,
FalseTest = 0x04,
SuppressFail = 0x08
}; };
inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
}
inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
}
#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
#include <string>
namespace Catch {
struct AssertionInfo
{
AssertionInfo() {}
AssertionInfo( std::string const& _macroName,
SourceLineInfo const& _lineInfo,
std::string const& _capturedExpression,
ResultDisposition::Flags _resultDisposition );
std::string macroName;
SourceLineInfo lineInfo;
std::string capturedExpression;
ResultDisposition::Flags resultDisposition;
};
struct AssertionResultData
{
AssertionResultData() : resultType( ResultWas::Unknown ) {}
std::string reconstructedExpression;
std::string message;
ResultWas::OfType resultType;
};
class AssertionResult {
public:
AssertionResult();
AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
~AssertionResult();
# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
AssertionResult( AssertionResult const& ) = default;
AssertionResult( AssertionResult && ) = default;
AssertionResult& operator = ( AssertionResult const& ) = default;
AssertionResult& operator = ( AssertionResult && ) = default;
# endif
bool isOk() const;
bool succeeded() const;
ResultWas::OfType getResultType() const;
bool hasExpression() const;
bool hasMessage() const;
std::string getExpression() const;
std::string getExpressionInMacro() const;
bool hasExpandedExpression() const;
std::string getExpandedExpression() const;
std::string getMessage() const;
SourceLineInfo getSourceInfo() const;
std::string getTestMacroName() const;
protected:
AssertionInfo m_info;
AssertionResultData m_resultData;
};
}
#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
namespace Catch {
namespace Matchers {
namespace Impl {
namespace Generic {
template<typename ExpressionT> class AllOf;
template<typename ExpressionT> class AnyOf;
template<typename ExpressionT> class Not;
}
template<typename ExpressionT>
struct Matcher : SharedImpl<IShared>
{
typedef ExpressionT ExpressionType;
virtual ~Matcher() {}
virtual Ptr<Matcher> clone() const = 0;
virtual bool match( ExpressionT const& expr ) const = 0;
virtual std::string toString() const = 0;
Generic::AllOf<ExpressionT> operator && ( Matcher<ExpressionT> const& other ) const;
Generic::AnyOf<ExpressionT> operator || ( Matcher<ExpressionT> const& other ) const;
Generic::Not<ExpressionT> operator ! () const;
};
template<typename DerivedT, typename ExpressionT>
struct MatcherImpl : Matcher<ExpressionT> {
virtual Ptr<Matcher<ExpressionT> > clone() const {
return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
}
};
namespace Generic {
template<typename ExpressionT>
class Not : public MatcherImpl<Not<ExpressionT>, ExpressionT> {
public:
explicit Not( Matcher<ExpressionT> const& matcher ) : m_matcher(matcher.clone()) {}
Not( Not const& other ) : m_matcher( other.m_matcher ) {}
virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE {
return !m_matcher->match( expr );
}
virtual std::string toString() const CATCH_OVERRIDE {
return "not " + m_matcher->toString();
}
private:
Ptr< Matcher<ExpressionT> > m_matcher;
};
template<typename ExpressionT>
class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
public:
AllOf() {}
AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
AllOf& add( Matcher<ExpressionT> const& matcher ) {
m_matchers.push_back( matcher.clone() );
return *this;
}
virtual bool match( ExpressionT const& expr ) const
{
for( std::size_t i = 0; i < m_matchers.size(); ++i )
if( !m_matchers[i]->match( expr ) )
return false;
return true;
}
virtual std::string toString() const {
std::ostringstream oss;
oss << "( ";
for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
if( i != 0 )
oss << " and ";
oss << m_matchers[i]->toString();
}
oss << " )";
return oss.str();
}
AllOf operator && ( Matcher<ExpressionT> const& other ) const {
AllOf allOfExpr( *this );
allOfExpr.add( other );
return allOfExpr;
}
private:
std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
};
template<typename ExpressionT>
class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
public:
AnyOf() {}
AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
AnyOf& add( Matcher<ExpressionT> const& matcher ) {
m_matchers.push_back( matcher.clone() );
return *this;
}
virtual bool match( ExpressionT const& expr ) const
{
for( std::size_t i = 0; i < m_matchers.size(); ++i )
if( m_matchers[i]->match( expr ) )
return true;
return false;
}
virtual std::string toString() const {
std::ostringstream oss;
oss << "( ";
for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
if( i != 0 )
oss << " or ";
oss << m_matchers[i]->toString();
}
oss << " )";
return oss.str();
}
AnyOf operator || ( Matcher<ExpressionT> const& other ) const {
AnyOf anyOfExpr( *this );
anyOfExpr.add( other );
return anyOfExpr;
}
private:
std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
};
}
template<typename ExpressionT>
Generic::AllOf<ExpressionT> Matcher<ExpressionT>::operator && ( Matcher<ExpressionT> const& other ) const {
Generic::AllOf<ExpressionT> allOfExpr;
allOfExpr.add( *this );
allOfExpr.add( other );
return allOfExpr;
}
template<typename ExpressionT>
Generic::AnyOf<ExpressionT> Matcher<ExpressionT>::operator || ( Matcher<ExpressionT> const& other ) const {
Generic::AnyOf<ExpressionT> anyOfExpr;
anyOfExpr.add( *this );
anyOfExpr.add( other );
return anyOfExpr;
}
template<typename ExpressionT>
Generic::Not<ExpressionT> Matcher<ExpressionT>::operator ! () const {
return Generic::Not<ExpressionT>( *this );
}
namespace StdString {
inline std::string makeString( std::string const& str ) { return str; }
inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
struct CasedString
{
CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
: m_caseSensitivity( caseSensitivity ),
m_str( adjustString( str ) )
{}
std::string adjustString( std::string const& str ) const {
return m_caseSensitivity == CaseSensitive::No
? toLower( str )
: str;
}
std::string toStringSuffix() const
{
return m_caseSensitivity == CaseSensitive::No
? " (case insensitive)"
: "";
}
CaseSensitive::Choice m_caseSensitivity;
std::string m_str;
};
struct Equals : MatcherImpl<Equals, std::string> {
Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
: m_data( str, caseSensitivity )
{}
Equals( Equals const& other ) : m_data( other.m_data ){}
virtual ~Equals();
virtual bool match( std::string const& expr ) const {
return m_data.m_str == m_data.adjustString( expr );;
}
virtual std::string toString() const {
return "equals: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
}
CasedString m_data;
};
struct Contains : MatcherImpl<Contains, std::string> {
Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
: m_data( substr, caseSensitivity ){}
Contains( Contains const& other ) : m_data( other.m_data ){}
virtual ~Contains();
virtual bool match( std::string const& expr ) const {
return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;
}
virtual std::string toString() const {
return "contains: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
}
CasedString m_data;
};
struct StartsWith : MatcherImpl<StartsWith, std::string> {
StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
: m_data( substr, caseSensitivity ){}
StartsWith( StartsWith const& other ) : m_data( other.m_data ){}
virtual ~StartsWith();
virtual bool match( std::string const& expr ) const {
return startsWith( m_data.adjustString( expr ), m_data.m_str );
}
virtual std::string toString() const {
return "starts with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
}
CasedString m_data;
};
struct EndsWith : MatcherImpl<EndsWith, std::string> {
EndsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
: m_data( substr, caseSensitivity ){}
EndsWith( EndsWith const& other ) : m_data( other.m_data ){}
virtual ~EndsWith();
virtual bool match( std::string const& expr ) const {
return endsWith( m_data.adjustString( expr ), m_data.m_str );
}
virtual std::string toString() const {
return "ends with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
}
CasedString m_data;
};
}
}
template<typename ExpressionT>
inline Impl::Generic::Not<ExpressionT> Not( Impl::Matcher<ExpressionT> const& m ) {
return Impl::Generic::Not<ExpressionT>( m );
}
template<typename ExpressionT>
inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
Impl::Matcher<ExpressionT> const& m2 ) {
return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
}
template<typename ExpressionT>
inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
Impl::Matcher<ExpressionT> const& m2,
Impl::Matcher<ExpressionT> const& m3 ) {
return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
}
template<typename ExpressionT>
inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
Impl::Matcher<ExpressionT> const& m2 ) {
return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
}
template<typename ExpressionT>
inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
Impl::Matcher<ExpressionT> const& m2,
Impl::Matcher<ExpressionT> const& m3 ) {
return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
}
inline Impl::StdString::Equals Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
return Impl::StdString::Equals( str, caseSensitivity );
}
inline Impl::StdString::Equals Equals( const char* str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
return Impl::StdString::Equals( Impl::StdString::makeString( str ), caseSensitivity );
}
inline Impl::StdString::Contains Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
return Impl::StdString::Contains( substr, caseSensitivity );
}
inline Impl::StdString::Contains Contains( const char* substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
return Impl::StdString::Contains( Impl::StdString::makeString( substr ), caseSensitivity );
}
inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) {
return Impl::StdString::StartsWith( substr );
}
inline Impl::StdString::StartsWith StartsWith( const char* substr ) {
return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
}
inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) {
return Impl::StdString::EndsWith( substr );
}
inline Impl::StdString::EndsWith EndsWith( const char* substr ) {
return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
}
}
using namespace Matchers;
}
namespace Catch {
struct TestFailureException{};
template<typename T> class ExpressionLhs;
struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
struct CopyableStream {
CopyableStream() {}
CopyableStream( CopyableStream const& other ) {
oss << other.oss.str();
}
CopyableStream& operator=( CopyableStream const& other ) {
oss.str("");
oss << other.oss.str();
return *this;
}
std::ostringstream oss;
};
class ResultBuilder {
public:
ResultBuilder( char const* macroName,
SourceLineInfo const& lineInfo,
char const* capturedExpression,
ResultDisposition::Flags resultDisposition,
char const* secondArg = "" );
template<typename T>
ExpressionLhs<T const&> operator <= ( T const& operand );
ExpressionLhs<bool> operator <= ( bool value );
template<typename T>
ResultBuilder& operator << ( T const& value ) {
m_stream.oss << value;
return *this;
}
template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
ResultBuilder& setResultType( ResultWas::OfType result );
ResultBuilder& setResultType( bool result );
ResultBuilder& setLhs( std::string const& lhs );
ResultBuilder& setRhs( std::string const& rhs );
ResultBuilder& setOp( std::string const& op );
void endExpression();
std::string reconstructExpression() const;
AssertionResult build() const;
void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
void captureResult( ResultWas::OfType resultType );
void captureExpression();
void captureExpectedException( std::string const& expectedMessage );
void captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher );
void handleResult( AssertionResult const& result );
void react();
bool shouldDebugBreak() const;
bool allowThrows() const;
private:
AssertionInfo m_assertionInfo;
AssertionResultData m_data;
struct ExprComponents {
ExprComponents() : testFalse( false ) {}
bool testFalse;
std::string lhs, rhs, op;
} m_exprComponents;
CopyableStream m_stream;
bool m_shouldDebugBreak;
bool m_shouldThrow;
};
}
#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4389)
#endif
#include <cstddef>
namespace Catch {
namespace Internal {
enum Operator {
IsEqualTo,
IsNotEqualTo,
IsLessThan,
IsGreaterThan,
IsLessThanOrEqualTo,
IsGreaterThanOrEqualTo
};
template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } };
template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } };
template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } };
template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } };
template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } };
template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } };
template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
template<typename T>
inline T& opCast(T const& t) { return const_cast<T&>(t); }
#ifdef CATCH_CONFIG_CPP11_NULLPTR
inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
#endif
template<typename T1, typename T2, Operator Op>
class Evaluator{};
template<typename T1, typename T2>
struct Evaluator<T1, T2, IsEqualTo> {
static bool evaluate( T1 const& lhs, T2 const& rhs) {
return opCast( lhs ) == opCast( rhs );
}
};
template<typename T1, typename T2>
struct Evaluator<T1, T2, IsNotEqualTo> {
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
return opCast( lhs ) != opCast( rhs );
}
};
template<typename T1, typename T2>
struct Evaluator<T1, T2, IsLessThan> {
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
return opCast( lhs ) < opCast( rhs );
}
};
template<typename T1, typename T2>
struct Evaluator<T1, T2, IsGreaterThan> {
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
return opCast( lhs ) > opCast( rhs );
}
};
template<typename T1, typename T2>
struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
return opCast( lhs ) >= opCast( rhs );
}
};
template<typename T1, typename T2>
struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
return opCast( lhs ) <= opCast( rhs );
}
};
template<Operator Op, typename T1, typename T2>
bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
}
template<Operator Op, typename T1, typename T2>
bool compare( T1 const& lhs, T2 const& rhs ) {
return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
}
template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
}
template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
}
template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
}
template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
}
template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
}
template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
}
template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
}
template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
}
template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
}
template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
}
template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
}
template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
}
template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
}
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
}
template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
}
template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
}
template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
}
template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
}
template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
}
#endif
#ifdef CATCH_CONFIG_CPP11_NULLPTR
template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
}
template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
}
#endif
}
}
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
#include <sstream>
#include <iomanip>
#include <limits>
#include <vector>
#include <cstddef>
#ifdef __OBJC__
#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
#import <Foundation/Foundation.h>
#ifdef __has_feature
#define CATCH_ARC_ENABLED __has_feature(objc_arc)
#else
#define CATCH_ARC_ENABLED 0
#endif
void arcSafeRelease( NSObject* obj );
id performOptionalSelector( id obj, SEL sel );
#if !CATCH_ARC_ENABLED
inline void arcSafeRelease( NSObject* obj ) {
[obj release];
}
inline id performOptionalSelector( id obj, SEL sel ) {
if( [obj respondsToSelector: sel] )
return [obj performSelector: sel];
return nil;
}
#define CATCH_UNSAFE_UNRETAINED
#define CATCH_ARC_STRONG
#else
inline void arcSafeRelease( NSObject* ){}
inline id performOptionalSelector( id obj, SEL sel ) {
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
#endif
if( [obj respondsToSelector: sel] )
return [obj performSelector: sel];
#ifdef __clang__
#pragma clang diagnostic pop
#endif
return nil;
}
#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
#define CATCH_ARC_STRONG __strong
#endif
#endif
#ifdef CATCH_CONFIG_CPP11_TUPLE
#include <tuple>
#endif
#ifdef CATCH_CONFIG_CPP11_IS_ENUM
#include <type_traits>
#endif
namespace Catch {
template<typename T>
std::string toString( T const& value );
std::string toString( std::string const& value );
std::string toString( std::wstring const& value );
std::string toString( const char* const value );
std::string toString( char* const value );
std::string toString( const wchar_t* const value );
std::string toString( wchar_t* const value );
std::string toString( int value );
std::string toString( unsigned long value );
std::string toString( unsigned int value );
std::string toString( const double value );
std::string toString( const float value );
std::string toString( bool value );
std::string toString( char value );
std::string toString( signed char value );
std::string toString( unsigned char value );
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
std::string toString( long long value );
std::string toString( unsigned long long value );
#endif
#ifdef CATCH_CONFIG_CPP11_NULLPTR
std::string toString( std::nullptr_t );
#endif
#ifdef __OBJC__
std::string toString( NSString const * const& nsstring );
std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
std::string toString( NSObject* const& nsObject );
#endif
namespace Detail {
extern const std::string unprintableString;
struct BorgType {
template<typename T> BorgType( T const& );
};
struct TrueType { char sizer[1]; };
struct FalseType { char sizer[2]; };
TrueType& testStreamable( std::ostream& );
FalseType testStreamable( FalseType );
FalseType operator<<( std::ostream const&, BorgType const& );
template<typename T>
struct IsStreamInsertable {
static std::ostream &s;
static T const&t;
enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
};
#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
template<typename T,
bool IsEnum = std::is_enum<T>::value
>
struct EnumStringMaker
{
static std::string convert( T const& ) { return unprintableString; }
};
template<typename T>
struct EnumStringMaker<T,true>
{
static std::string convert( T const& v )
{
return ::Catch::toString(
static_cast<typename std::underlying_type<T>::type>(v)
);
}
};
#endif
template<bool C>
struct StringMakerBase {
#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
template<typename T>
static std::string convert( T const& v )
{
return EnumStringMaker<T>::convert( v );
}
#else
template<typename T>
static std::string convert( T const& ) { return unprintableString; }
#endif
};
template<>
struct StringMakerBase<true> {
template<typename T>
static std::string convert( T const& _value ) {
std::ostringstream oss;
oss << _value;
return oss.str();
}
};
std::string rawMemoryToString( const void *object, std::size_t size );
template<typename T>
inline std::string rawMemoryToString( const T& object ) {
return rawMemoryToString( &object, sizeof(object) );
}
}
template<typename T>
struct StringMaker :
Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
template<typename T>
struct StringMaker<T*> {
template<typename U>
static std::string convert( U* p ) {
if( !p )
return "NULL";
else
return Detail::rawMemoryToString( p );
}
};
template<typename R, typename C>
struct StringMaker<R C::*> {
static std::string convert( R C::* p ) {
if( !p )
return "NULL";
else
return Detail::rawMemoryToString( p );
}
};
namespace Detail {
template<typename InputIterator>
std::string rangeToString( InputIterator first, InputIterator last );
}
template<typename T, typename Allocator>
std::string toString( std::vector<T,Allocator> const& v ) {
return Detail::rangeToString( v.begin(), v.end() );
}
#ifdef CATCH_CONFIG_CPP11_TUPLE
namespace TupleDetail {
template<
typename Tuple,
std::size_t N = 0,
bool = (N < std::tuple_size<Tuple>::value)
>
struct ElementPrinter {
static void print( const Tuple& tuple, std::ostream& os )
{
os << ( N ? ", " : " " )
<< Catch::toString(std::get<N>(tuple));
ElementPrinter<Tuple,N+1>::print(tuple,os);
}
};
template<
typename Tuple,
std::size_t N
>
struct ElementPrinter<Tuple,N,false> {
static void print( const Tuple&, std::ostream& ) {}
};
}
template<typename ...Types>
struct StringMaker<std::tuple<Types...>> {
static std::string convert( const std::tuple<Types...>& tuple )
{
std::ostringstream os;
os << '{';
TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
os << " }";
return os.str();
}
};
#endif
namespace Detail {
template<typename T>
std::string makeString( T const& value ) {
return StringMaker<T>::convert( value );
}
}
template<typename T>
std::string toString( T const& value ) {
return StringMaker<T>::convert( value );
}
namespace Detail {
template<typename InputIterator>
std::string rangeToString( InputIterator first, InputIterator last ) {
std::ostringstream oss;
oss << "{ ";
if( first != last ) {
oss << Catch::toString( *first );
for( ++first ; first != last ; ++first )
oss << ", " << Catch::toString( *first );
}
oss << " }";
return oss.str();
}
}
}
namespace Catch {
template<typename T>
class ExpressionLhs {
ExpressionLhs& operator = ( ExpressionLhs const& );
# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
# endif
public:
ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
ExpressionLhs( ExpressionLhs const& ) = default;
ExpressionLhs( ExpressionLhs && ) = default;
# endif
template<typename RhsT>
ResultBuilder& operator == ( RhsT const& rhs ) {
return captureExpression<Internal::IsEqualTo>( rhs );
}
template<typename RhsT>
ResultBuilder& operator != ( RhsT const& rhs ) {
return captureExpression<Internal::IsNotEqualTo>( rhs );
}
template<typename RhsT>
ResultBuilder& operator < ( RhsT const& rhs ) {
return captureExpression<Internal::IsLessThan>( rhs );
}
template<typename RhsT>
ResultBuilder& operator > ( RhsT const& rhs ) {
return captureExpression<Internal::IsGreaterThan>( rhs );
}
template<typename RhsT>
ResultBuilder& operator <= ( RhsT const& rhs ) {
return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
}
template<typename RhsT>
ResultBuilder& operator >= ( RhsT const& rhs ) {
return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
}
ResultBuilder& operator == ( bool rhs ) {
return captureExpression<Internal::IsEqualTo>( rhs );
}
ResultBuilder& operator != ( bool rhs ) {
return captureExpression<Internal::IsNotEqualTo>( rhs );
}
void endExpression() {
bool value = m_lhs ? true : false;
m_rb
.setLhs( Catch::toString( value ) )
.setResultType( value )
.endExpression();
}
template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
private:
template<Internal::Operator Op, typename RhsT>
ResultBuilder& captureExpression( RhsT const& rhs ) {
return m_rb
.setResultType( Internal::compare<Op>( m_lhs, rhs ) )
.setLhs( Catch::toString( m_lhs ) )
.setRhs( Catch::toString( rhs ) )
.setOp( Internal::OperatorTraits<Op>::getName() );
}
private:
ResultBuilder& m_rb;
T m_lhs;
};
}
namespace Catch {
template<typename T>
inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
return ExpressionLhs<T const&>( *this, operand );
}
inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
return ExpressionLhs<bool>( *this, value );
}
}
#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
#include <string>
namespace Catch {
struct MessageInfo {
MessageInfo( std::string const& _macroName,
SourceLineInfo const& _lineInfo,
ResultWas::OfType _type );
std::string macroName;
SourceLineInfo lineInfo;
ResultWas::OfType type;
std::string message;
unsigned int sequence;
bool operator == ( MessageInfo const& other ) const {
return sequence == other.sequence;
}
bool operator < ( MessageInfo const& other ) const {
return sequence < other.sequence;
}
private:
static unsigned int globalCount;
};
struct MessageBuilder {
MessageBuilder( std::string const& macroName,
SourceLineInfo const& lineInfo,
ResultWas::OfType type )
: m_info( macroName, lineInfo, type )
{}
template<typename T>
MessageBuilder& operator << ( T const& value ) {
m_stream << value;
return *this;
}
MessageInfo m_info;
std::ostringstream m_stream;
};
class ScopedMessage {
public:
ScopedMessage( MessageBuilder const& builder );
ScopedMessage( ScopedMessage const& other );
~ScopedMessage();
MessageInfo m_info;
};
}
#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
#include <string>
namespace Catch {
class TestCase;
class AssertionResult;
struct AssertionInfo;
struct SectionInfo;
struct SectionEndInfo;
struct MessageInfo;
class ScopedMessageBuilder;
struct Counts;
struct IResultCapture {
virtual ~IResultCapture();
virtual void assertionEnded( AssertionResult const& result ) = 0;
virtual bool sectionStarted( SectionInfo const& sectionInfo,
Counts& assertions ) = 0;
virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
virtual void pushScopedMessage( MessageInfo const& message ) = 0;
virtual void popScopedMessage( MessageInfo const& message ) = 0;
virtual std::string getCurrentTestName() const = 0;
virtual const AssertionResult* getLastResult() const = 0;
virtual void handleFatalErrorCondition( std::string const& message ) = 0;
};
IResultCapture& getResultCapture();
}
#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
#define CATCH_PLATFORM_MAC
#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#define CATCH_PLATFORM_IPHONE
#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
#define CATCH_PLATFORM_WINDOWS
#endif
#include <string>
namespace Catch{
bool isDebuggerActive();
void writeToDebugConsole( std::string const& text );
}
#ifdef CATCH_PLATFORM_MAC
#ifdef DEBUG
#if defined(__ppc64__) || defined(__ppc__)
#define CATCH_BREAK_INTO_DEBUGGER() \
if( Catch::isDebuggerActive() ) { \
__asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
: : : "memory","r0","r3","r4" ); \
}
#else
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
#endif
#endif
#elif defined(_MSC_VER)
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
#elif defined(__MINGW32__)
extern "C" __declspec(dllimport) void __stdcall DebugBreak();
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
#endif
#ifndef CATCH_BREAK_INTO_DEBUGGER
#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
#endif
#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
namespace Catch {
class TestCase;
struct IRunner {
virtual ~IRunner();
virtual bool aborting() const = 0;
};
}
#define INTERNAL_CATCH_REACT( resultBuilder ) \
if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
resultBuilder.react();
#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
try { \
( __catchResult <= expr ).endExpression(); \
} \
catch( ... ) { \
__catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
} \
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::isTrue( false && static_cast<bool>(expr) ) )
#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
if( Catch::getResultCapture().getLastResult()->succeeded() )
#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
if( !Catch::getResultCapture().getLastResult()->succeeded() )
#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
try { \
expr; \
__catchResult.captureResult( Catch::ResultWas::Ok ); \
} \
catch( ... ) { \
__catchResult.useActiveException( resultDisposition ); \
} \
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::alwaysFalse() )
#define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \
if( __catchResult.allowThrows() ) \
try { \
expr; \
__catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
} \
catch( ... ) { \
__catchResult.captureExpectedException( matcher ); \
} \
else \
__catchResult.captureResult( Catch::ResultWas::Ok ); \
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::alwaysFalse() )
#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
if( __catchResult.allowThrows() ) \
try { \
expr; \
__catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
} \
catch( exceptionType ) { \
__catchResult.captureResult( Catch::ResultWas::Ok ); \
} \
catch( ... ) { \
__catchResult.useActiveException( resultDisposition ); \
} \
else \
__catchResult.captureResult( Catch::ResultWas::Ok ); \
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::alwaysFalse() )
#ifdef CATCH_CONFIG_VARIADIC_MACROS
#define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
__catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
__catchResult.captureResult( messageType ); \
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::alwaysFalse() )
#else
#define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
__catchResult << log + ::Catch::StreamEndStop(); \
__catchResult.captureResult( messageType ); \
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::alwaysFalse() )
#endif
#define INTERNAL_CATCH_INFO( log, macroName ) \
Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
do { \
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
try { \
std::string matcherAsString = (matcher).toString(); \
__catchResult \
.setLhs( Catch::toString( arg ) ) \
.setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
.setOp( "matches" ) \
.setResultType( (matcher).match( arg ) ); \
__catchResult.captureExpression(); \
} catch( ... ) { \
__catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
} \
INTERNAL_CATCH_REACT( __catchResult ) \
} while( Catch::alwaysFalse() )
#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
#include <cstddef>
namespace Catch {
struct Counts {
Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
Counts operator - ( Counts const& other ) const {
Counts diff;
diff.passed = passed - other.passed;
diff.failed = failed - other.failed;
diff.failedButOk = failedButOk - other.failedButOk;
return diff;
}
Counts& operator += ( Counts const& other ) {
passed += other.passed;
failed += other.failed;
failedButOk += other.failedButOk;
return *this;
}
std::size_t total() const {
return passed + failed + failedButOk;
}
bool allPassed() const {
return failed == 0 && failedButOk == 0;
}
bool allOk() const {
return failed == 0;
}
std::size_t passed;
std::size_t failed;
std::size_t failedButOk;
};
struct Totals {
Totals operator - ( Totals const& other ) const {
Totals diff;
diff.assertions = assertions - other.assertions;
diff.testCases = testCases - other.testCases;
return diff;
}
Totals delta( Totals const& prevTotals ) const {
Totals diff = *this - prevTotals;
if( diff.assertions.failed > 0 )
++diff.testCases.failed;
else if( diff.assertions.failedButOk > 0 )
++diff.testCases.failedButOk;
else
++diff.testCases.passed;
return diff;
}
Totals& operator += ( Totals const& other ) {
assertions += other.assertions;
testCases += other.testCases;
return *this;
}
Counts assertions;
Counts testCases;
};
}
namespace Catch {
struct SectionInfo {
SectionInfo
( SourceLineInfo const& _lineInfo,
std::string const& _name,
std::string const& _description = std::string() );
std::string name;
std::string description;
SourceLineInfo lineInfo;
};
struct SectionEndInfo {
SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
: sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
{}
SectionInfo sectionInfo;
Counts prevAssertions;
double durationInSeconds;
};
}
#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
#ifdef CATCH_PLATFORM_WINDOWS
typedef unsigned long long uint64_t;
#else
#include <stdint.h>
#endif
namespace Catch {
class Timer {
public:
Timer() : m_ticks( 0 ) {}
void start();
unsigned int getElapsedMicroseconds() const;
unsigned int getElapsedMilliseconds() const;
double getElapsedSeconds() const;
private:
uint64_t m_ticks;
};
}
#include <string>
namespace Catch {
class Section : NonCopyable {
public:
Section( SectionInfo const& info );
~Section();
operator bool() const;
private:
SectionInfo m_info;
std::string m_name;
Counts m_assertions;
bool m_sectionIncluded;
Timer m_timer;
};
}
#ifdef CATCH_CONFIG_VARIADIC_MACROS
#define INTERNAL_CATCH_SECTION( ... ) \
if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
#else
#define INTERNAL_CATCH_SECTION( name, desc ) \
if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
#endif
#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
#include <iterator>
#include <vector>
#include <string>
#include <stdlib.h>
namespace Catch {
template<typename T>
struct IGenerator {
virtual ~IGenerator() {}
virtual T getValue( std::size_t index ) const = 0;
virtual std::size_t size () const = 0;
};
template<typename T>
class BetweenGenerator : public IGenerator<T> {
public:
BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
virtual T getValue( std::size_t index ) const {
return m_from+static_cast<int>( index );
}
virtual std::size_t size() const {
return static_cast<std::size_t>( 1+m_to-m_from );
}
private:
T m_from;
T m_to;
};
template<typename T>
class ValuesGenerator : public IGenerator<T> {
public:
ValuesGenerator(){}
void add( T value ) {
m_values.push_back( value );
}
virtual T getValue( std::size_t index ) const {
return m_values[index];
}
virtual std::size_t size() const {
return m_values.size();
}
private:
std::vector<T> m_values;
};
template<typename T>
class CompositeGenerator {
public:
CompositeGenerator() : m_totalSize( 0 ) {}
CompositeGenerator( CompositeGenerator& other )
: m_fileInfo( other.m_fileInfo ),
m_totalSize( 0 )
{
move( other );
}
CompositeGenerator& setFileInfo( const char* fileInfo ) {
m_fileInfo = fileInfo;
return *this;
}
~CompositeGenerator() {
deleteAll( m_composed );
}
operator T () const {
size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
for( size_t index = 0; it != itEnd; ++it )
{
const IGenerator<T>* generator = *it;
if( overallIndex >= index && overallIndex < index + generator->size() )
{
return generator->getValue( overallIndex-index );
}
index += generator->size();
}
CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
return T();
}
void add( const IGenerator<T>* generator ) {
m_totalSize += generator->size();
m_composed.push_back( generator );
}
CompositeGenerator& then( CompositeGenerator& other ) {
move( other );
return *this;
}
CompositeGenerator& then( T value ) {
ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
valuesGen->add( value );
add( valuesGen );
return *this;
}
private:
void move( CompositeGenerator& other ) {
std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
m_totalSize += other.m_totalSize;
other.m_composed.clear();
}
std::vector<const IGenerator<T>*> m_composed;
std::string m_fileInfo;
size_t m_totalSize;
};
namespace Generators
{
template<typename T>
CompositeGenerator<T> between( T from, T to ) {
CompositeGenerator<T> generators;
generators.add( new BetweenGenerator<T>( from, to ) );
return generators;
}
template<typename T>
CompositeGenerator<T> values( T val1, T val2 ) {
CompositeGenerator<T> generators;
ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
valuesGen->add( val1 );
valuesGen->add( val2 );
generators.add( valuesGen );
return generators;
}
template<typename T>
CompositeGenerator<T> values( T val1, T val2, T val3 ){
CompositeGenerator<T> generators;
ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
valuesGen->add( val1 );
valuesGen->add( val2 );
valuesGen->add( val3 );
generators.add( valuesGen );
return generators;
}
template<typename T>
CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
CompositeGenerator<T> generators;
ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
valuesGen->add( val1 );
valuesGen->add( val2 );
valuesGen->add( val3 );
valuesGen->add( val4 );
generators.add( valuesGen );
return generators;
}
}
using namespace Generators;
}
#define INTERNAL_CATCH_LINESTR2( line ) #line
#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
#include <string>
#include <vector>
#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
#include <string>
namespace Catch {
class TestCase;
struct ITestCaseRegistry;
struct IExceptionTranslatorRegistry;
struct IExceptionTranslator;
struct IReporterRegistry;
struct IReporterFactory;
struct IRegistryHub {
virtual ~IRegistryHub();
virtual IReporterRegistry const& getReporterRegistry() const = 0;
virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
};
struct IMutableRegistryHub {
virtual ~IMutableRegistryHub();
virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) = 0;
virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;
virtual void registerTest( TestCase const& testInfo ) = 0;
virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
};
IRegistryHub& getRegistryHub();
IMutableRegistryHub& getMutableRegistryHub();
void cleanUp();
std::string translateActiveException();
}
namespace Catch {
typedef std::string(*exceptionTranslateFunction)();
struct IExceptionTranslator;
typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;
struct IExceptionTranslator {
virtual ~IExceptionTranslator();
virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
};
struct IExceptionTranslatorRegistry {
virtual ~IExceptionTranslatorRegistry();
virtual std::string translateActiveException() const = 0;
};
class ExceptionTranslatorRegistrar {
template<typename T>
class ExceptionTranslator : public IExceptionTranslator {
public:
ExceptionTranslator( std::string(*translateFunction)( T& ) )
: m_translateFunction( translateFunction )
{}
virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {
try {
if( it == itEnd )
throw;
else
return (*it)->translate( it+1, itEnd );
}
catch( T& ex ) {
return m_translateFunction( ex );
}
}
protected:
std::string(*m_translateFunction)( T& );
};
public:
template<typename T>
ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
getMutableRegistryHub().registerTranslator
( new ExceptionTranslator<T>( translateFunction ) );
}
};
}
#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \
static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \
namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\
static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature )
#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
#include <cmath>
#include <limits>
namespace Catch {
namespace Detail {
class Approx {
public:
explicit Approx ( double value )
: m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
m_scale( 1.0 ),
m_value( value )
{}
Approx( Approx const& other )
: m_epsilon( other.m_epsilon ),
m_scale( other.m_scale ),
m_value( other.m_value )
{}
static Approx custom() {
return Approx( 0 );
}
Approx operator()( double value ) {
Approx approx( value );
approx.epsilon( m_epsilon );
approx.scale( m_scale );
return approx;
}
friend bool operator == ( double lhs, Approx const& rhs ) {
return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
}
friend bool operator == ( Approx const& lhs, double rhs ) {
return operator==( rhs, lhs );
}
friend bool operator != ( double lhs, Approx const& rhs ) {
return !operator==( lhs, rhs );
}
friend bool operator != ( Approx const& lhs, double rhs ) {
return !operator==( rhs, lhs );
}
Approx& epsilon( double newEpsilon ) {
m_epsilon = newEpsilon;
return *this;
}
Approx& scale( double newScale ) {
m_scale = newScale;
return *this;
}
std::string toString() const {
std::ostringstream oss;
oss << "Approx( " << Catch::toString( m_value ) << " )";
return oss.str();
}
private:
double m_epsilon;
double m_scale;
double m_value;
};
}
template<>
inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
return value.toString();
}
}
#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
#include <string>
namespace Catch {
struct TagAlias {
TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
std::string tag;
SourceLineInfo lineInfo;
};
struct RegistrarForTagAliases {
RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
};
}
#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
namespace Catch {
template<typename T>
class Option {
public:
Option() : nullableValue( CATCH_NULL ) {}
Option( T const& _value )
: nullableValue( new( storage ) T( _value ) )
{}
Option( Option const& _other )
: nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL )
{}
~Option() {
reset();
}
Option& operator= ( Option const& _other ) {
if( &_other != this ) {
reset();
if( _other )
nullableValue = new( storage ) T( *_other );
}
return *this;
}
Option& operator = ( T const& _value ) {
reset();
nullableValue = new( storage ) T( _value );
return *this;
}
void reset() {
if( nullableValue )
nullableValue->~T();
nullableValue = CATCH_NULL;
}
T& operator*() { return *nullableValue; }
T const& operator*() const { return *nullableValue; }
T* operator->() { return nullableValue; }
const T* operator->() const { return nullableValue; }
T valueOr( T const& defaultValue ) const {
return nullableValue ? *nullableValue : defaultValue;
}
bool some() const { return nullableValue != CATCH_NULL; }
bool none() const { return nullableValue == CATCH_NULL; }
bool operator !() const { return nullableValue == CATCH_NULL; }
operator SafeBool::type() const {
return SafeBool::makeSafe( some() );
}
private:
T* nullableValue;
char storage[sizeof(T)];
};
}
namespace Catch {
struct ITagAliasRegistry {
virtual ~ITagAliasRegistry();
virtual Option<TagAlias> find( std::string const& alias ) const = 0;
virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
static ITagAliasRegistry const& get();
};
}
#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
#include <string>
#include <set>
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#endif
namespace Catch {
struct ITestCase;
struct TestCaseInfo {
enum SpecialProperties{
None = 0,
IsHidden = 1 << 1,
ShouldFail = 1 << 2,
MayFail = 1 << 3,
Throws = 1 << 4
};
TestCaseInfo( std::string const& _name,
std::string const& _className,
std::string const& _description,
std::set<std::string> const& _tags,
SourceLineInfo const& _lineInfo );
TestCaseInfo( TestCaseInfo const& other );
friend void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags );
bool isHidden() const;
bool throws() const;
bool okToFail() const;
bool expectedToFail() const;
std::string name;
std::string className;
std::string description;
std::set<std::string> tags;
std::set<std::string> lcaseTags;
std::string tagsAsString;
SourceLineInfo lineInfo;
SpecialProperties properties;
};
class TestCase : public TestCaseInfo {
public:
TestCase( ITestCase* testCase, TestCaseInfo const& info );
TestCase( TestCase const& other );
TestCase withName( std::string const& _newName ) const;
void invoke() const;
TestCaseInfo const& getTestCaseInfo() const;
void swap( TestCase& other );
bool operator == ( TestCase const& other ) const;
bool operator < ( TestCase const& other ) const;
TestCase& operator = ( TestCase const& other );
private:
Ptr<ITestCase> test;
};
TestCase makeTestCase( ITestCase* testCase,
std::string const& className,
std::string const& name,
std::string const& description,
SourceLineInfo const& lineInfo );
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#ifdef __OBJC__
#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
#import <objc/runtime.h>
#include <string>
@protocol OcFixture
@optional
-(void) setUp;
-(void) tearDown;
@end
namespace Catch {
class OcMethod : public SharedImpl<ITestCase> {
public:
OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
virtual void invoke() const {
id obj = [[m_cls alloc] init];
performOptionalSelector( obj, @selector(setUp) );
performOptionalSelector( obj, m_sel );
performOptionalSelector( obj, @selector(tearDown) );
arcSafeRelease( obj );
}
private:
virtual ~OcMethod() {}
Class m_cls;
SEL m_sel;
};
namespace Detail{
inline std::string getAnnotation( Class cls,
std::string const& annotationName,
std::string const& testCaseName ) {
NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
SEL sel = NSSelectorFromString( selStr );
arcSafeRelease( selStr );
id value = performOptionalSelector( cls, sel );
if( value )
return [(NSString*)value UTF8String];
return "";
}
}
inline size_t registerTestMethods() {
size_t noTestMethods = 0;
int noClasses = objc_getClassList( CATCH_NULL, 0 );
Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
objc_getClassList( classes, noClasses );
for( int c = 0; c < noClasses; c++ ) {
Class cls = classes[c];
{
u_int count;
Method* methods = class_copyMethodList( cls, &count );
for( u_int m = 0; m < count ; m++ ) {
SEL selector = method_getName(methods[m]);
std::string methodName = sel_getName(selector);
if( startsWith( methodName, "Catch_TestCase_" ) ) {
std::string testCaseName = methodName.substr( 15 );
std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
const char* className = class_getName( cls );
getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
noTestMethods++;
}
}
free(methods);
}
}
return noTestMethods;
}
namespace Matchers {
namespace Impl {
namespace NSStringMatchers {
template<typename MatcherT>
struct StringHolder : MatcherImpl<MatcherT, NSString*>{
StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
StringHolder() {
arcSafeRelease( m_substr );
}
NSString* m_substr;
};
struct Equals : StringHolder<Equals> {
Equals( NSString* substr ) : StringHolder( substr ){}
virtual bool match( ExpressionType const& str ) const {
return (str != nil || m_substr == nil ) &&
[str isEqualToString:m_substr];
}
virtual std::string toString() const {
return "equals string: " + Catch::toString( m_substr );
}
};
struct Contains : StringHolder<Contains> {
Contains( NSString* substr ) : StringHolder( substr ){}
virtual bool match( ExpressionType const& str ) const {
return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location != NSNotFound;
}
virtual std::string toString() const {
return "contains string: " + Catch::toString( m_substr );
}
};
struct StartsWith : StringHolder<StartsWith> {
StartsWith( NSString* substr ) : StringHolder( substr ){}
virtual bool match( ExpressionType const& str ) const {
return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location == 0;
}
virtual std::string toString() const {
return "starts with: " + Catch::toString( m_substr );
}
};
struct EndsWith : StringHolder<EndsWith> {
EndsWith( NSString* substr ) : StringHolder( substr ){}
virtual bool match( ExpressionType const& str ) const {
return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location == [str length] - [m_substr length];
}
virtual std::string toString() const {
return "ends with: " + Catch::toString( m_substr );
}
};
}
}
inline Impl::NSStringMatchers::Equals
Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
inline Impl::NSStringMatchers::Contains
Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
inline Impl::NSStringMatchers::StartsWith
StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
inline Impl::NSStringMatchers::EndsWith
EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
}
using namespace Matchers;
}
#define OC_TEST_CASE( name, desc )\
+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
{\
return @ name; \
}\
+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
{ \
return @ desc; \
} \
-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
#endif
#ifdef CATCH_IMPL
#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wweak-vtables"
#endif
#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#endif
#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#endif
#define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED
namespace Catch
{
class WildcardPattern {
enum WildcardPosition {
NoWildcard = 0,
WildcardAtStart = 1,
WildcardAtEnd = 2,
WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
};
public:
WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity )
: m_caseSensitivity( caseSensitivity ),
m_wildcard( NoWildcard ),
m_pattern( adjustCase( pattern ) )
{
if( startsWith( m_pattern, "*" ) ) {
m_pattern = m_pattern.substr( 1 );
m_wildcard = WildcardAtStart;
}
if( endsWith( m_pattern, "*" ) ) {
m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
}
}
virtual ~WildcardPattern();
virtual bool matches( std::string const& str ) const {
switch( m_wildcard ) {
case NoWildcard:
return m_pattern == adjustCase( str );
case WildcardAtStart:
return endsWith( adjustCase( str ), m_pattern );
case WildcardAtEnd:
return startsWith( adjustCase( str ), m_pattern );
case WildcardAtBothEnds:
return contains( adjustCase( str ), m_pattern );
}
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
#endif
throw std::logic_error( "Unknown enum" );
#ifdef __clang__
#pragma clang diagnostic pop
#endif
}
private:
std::string adjustCase( std::string const& str ) const {
return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
}
CaseSensitive::Choice m_caseSensitivity;
WildcardPosition m_wildcard;
std::string m_pattern;
};
}
#include <string>
#include <vector>
namespace Catch {
class TestSpec {
struct Pattern : SharedImpl<> {
virtual ~Pattern();
virtual bool matches( TestCaseInfo const& testCase ) const = 0;
};
class NamePattern : public Pattern {
public:
NamePattern( std::string const& name )
: m_wildcardPattern( toLower( name ), CaseSensitive::No )
{}
virtual ~NamePattern();
virtual bool matches( TestCaseInfo const& testCase ) const {
return m_wildcardPattern.matches( toLower( testCase.name ) );
}
private:
WildcardPattern m_wildcardPattern;
};
class TagPattern : public Pattern {
public:
TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
virtual ~TagPattern();
virtual bool matches( TestCaseInfo const& testCase ) const {
return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
}
private:
std::string m_tag;
};
class ExcludedPattern : public Pattern {
public:
ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
virtual ~ExcludedPattern();
virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
private:
Ptr<Pattern> m_underlyingPattern;
};
struct Filter {
std::vector<Ptr<Pattern> > m_patterns;
bool matches( TestCaseInfo const& testCase ) const {
for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
if( !(*it)->matches( testCase ) )
return false;
return true;
}
};
public:
bool hasFilters() const {
return !m_filters.empty();
}
bool matches( TestCaseInfo const& testCase ) const {
for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
if( it->matches( testCase ) )
return true;
return false;
}
private:
std::vector<Filter> m_filters;
friend class TestSpecParser;
};
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif
namespace Catch {
class TestSpecParser {
enum Mode{ None, Name, QuotedName, Tag };
Mode m_mode;
bool m_exclusion;
std::size_t m_start, m_pos;
std::string m_arg;
TestSpec::Filter m_currentFilter;
TestSpec m_testSpec;
ITagAliasRegistry const* m_tagAliases;
public:
TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
TestSpecParser& parse( std::string const& arg ) {
m_mode = None;
m_exclusion = false;
m_start = std::string::npos;
m_arg = m_tagAliases->expandAliases( arg );
for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
visitChar( m_arg[m_pos] );
if( m_mode == Name )
addPattern<TestSpec::NamePattern>();
return *this;
}
TestSpec testSpec() {
addFilter();
return m_testSpec;
}
private:
void visitChar( char c ) {
if( m_mode == None ) {
switch( c ) {
case ' ': return;
case '~': m_exclusion = true; return;
case '[': return startNewMode( Tag, ++m_pos );
case '"': return startNewMode( QuotedName, ++m_pos );
default: startNewMode( Name, m_pos ); break;
}
}
if( m_mode == Name ) {
if( c == ',' ) {
addPattern<TestSpec::NamePattern>();
addFilter();
}
else if( c == '[' ) {
if( subString() == "exclude:" )
m_exclusion = true;
else
addPattern<TestSpec::NamePattern>();
startNewMode( Tag, ++m_pos );
}
}
else if( m_mode == QuotedName && c == '"' )
addPattern<TestSpec::NamePattern>();
else if( m_mode == Tag && c == ']' )
addPattern<TestSpec::TagPattern>();
}
void startNewMode( Mode mode, std::size_t start ) {
m_mode = mode;
m_start = start;
}
std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
template<typename T>
void addPattern() {
std::string token = subString();
if( startsWith( token, "exclude:" ) ) {
m_exclusion = true;
token = token.substr( 8 );
}
if( !token.empty() ) {
Ptr<TestSpec::Pattern> pattern = new T( token );
if( m_exclusion )
pattern = new TestSpec::ExcludedPattern( pattern );
m_currentFilter.m_patterns.push_back( pattern );
}
m_exclusion = false;
m_mode = None;
}
void addFilter() {
if( !m_currentFilter.m_patterns.empty() ) {
m_testSpec.m_filters.push_back( m_currentFilter );
m_currentFilter = TestSpec::Filter();
}
}
};
inline TestSpec parseTestSpec( std::string const& arg ) {
return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
}
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
#include <iostream>
#include <string>
#include <vector>
namespace Catch {
struct Verbosity { enum Level {
NoOutput = 0,
Quiet,
Normal
}; };
struct WarnAbout { enum What {
Nothing = 0x00,
NoAssertions = 0x01
}; };
struct ShowDurations { enum OrNot {
DefaultForReporter,
Always,
Never
}; };
struct RunTests { enum InWhatOrder {
InDeclarationOrder,
InLexicographicalOrder,
InRandomOrder
}; };
class TestSpec;
struct IConfig : IShared {
virtual ~IConfig();
virtual bool allowThrows() const = 0;
virtual std::ostream& stream() const = 0;
virtual std::string name() const = 0;
virtual bool includeSuccessfulResults() const = 0;
virtual bool shouldDebugBreak() const = 0;
virtual bool warnAboutMissingAssertions() const = 0;
virtual int abortAfter() const = 0;
virtual bool showInvisibles() const = 0;
virtual ShowDurations::OrNot showDurations() const = 0;
virtual TestSpec const& testSpec() const = 0;
virtual RunTests::InWhatOrder runOrder() const = 0;
virtual unsigned int rngSeed() const = 0;
virtual bool forceColour() const = 0;
};
}
#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
#include <streambuf>
namespace Catch {
class StreamBufBase : public std::streambuf {
public:
virtual ~StreamBufBase() CATCH_NOEXCEPT;
};
}
#include <streambuf>
#include <ostream>
#include <fstream>
namespace Catch {
std::ostream& cout();
std::ostream& cerr();
struct IStream {
virtual ~IStream() CATCH_NOEXCEPT;
virtual std::ostream& stream() const = 0;
};
class FileStream : public IStream {
mutable std::ofstream m_ofs;
public:
FileStream( std::string const& filename );
virtual ~FileStream() CATCH_NOEXCEPT;
public:
virtual std::ostream& stream() const CATCH_OVERRIDE;
};
class CoutStream : public IStream {
mutable std::ostream m_os;
public:
CoutStream();
virtual ~CoutStream() CATCH_NOEXCEPT;
public:
virtual std::ostream& stream() const CATCH_OVERRIDE;
};
class DebugOutStream : public IStream {
std::auto_ptr<StreamBufBase> m_streamBuf;
mutable std::ostream m_os;
public:
DebugOutStream();
virtual ~DebugOutStream() CATCH_NOEXCEPT;
public:
virtual std::ostream& stream() const CATCH_OVERRIDE;
};
}
#include <memory>
#include <vector>
#include <string>
#include <iostream>
#include <ctime>
#ifndef CATCH_CONFIG_CONSOLE_WIDTH
#define CATCH_CONFIG_CONSOLE_WIDTH 80
#endif
namespace Catch {
struct ConfigData {
ConfigData()
: listTests( false ),
listTags( false ),
listReporters( false ),
listTestNamesOnly( false ),
showSuccessfulTests( false ),
shouldDebugBreak( false ),
noThrow( false ),
showHelp( false ),
showInvisibles( false ),
forceColour( false ),
filenamesAsTags( false ),
abortAfter( -1 ),
rngSeed( 0 ),
verbosity( Verbosity::Normal ),
warnings( WarnAbout::Nothing ),
showDurations( ShowDurations::DefaultForReporter ),
runOrder( RunTests::InDeclarationOrder )
{}
bool listTests;
bool listTags;
bool listReporters;
bool listTestNamesOnly;
bool showSuccessfulTests;
bool shouldDebugBreak;
bool noThrow;
bool showHelp;
bool showInvisibles;
bool forceColour;
bool filenamesAsTags;
int abortAfter;
unsigned int rngSeed;
Verbosity::Level verbosity;
WarnAbout::What warnings;
ShowDurations::OrNot showDurations;
RunTests::InWhatOrder runOrder;
std::string outputFilename;
std::string name;
std::string processName;
std::vector<std::string> reporterNames;
std::vector<std::string> testsOrTags;
};
class Config : public SharedImpl<IConfig> {
private:
Config( Config const& other );
Config& operator = ( Config const& other );
virtual void dummy();
public:
Config()
{}
Config( ConfigData const& data )
: m_data( data ),
m_stream( openStream() )
{
if( !data.testsOrTags.empty() ) {
TestSpecParser parser( ITagAliasRegistry::get() );
for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
parser.parse( data.testsOrTags[i] );
m_testSpec = parser.testSpec();
}
}
virtual ~Config() {
}
std::string const& getFilename() const {
return m_data.outputFilename ;
}
bool listTests() const { return m_data.listTests; }
bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
bool listTags() const { return m_data.listTags; }
bool listReporters() const { return m_data.listReporters; }
std::string getProcessName() const { return m_data.processName; }
bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
std::vector<std::string> getReporterNames() const { return m_data.reporterNames; }
int abortAfter() const { return m_data.abortAfter; }
TestSpec const& testSpec() const { return m_testSpec; }
bool showHelp() const { return m_data.showHelp; }
bool showInvisibles() const { return m_data.showInvisibles; }
virtual bool allowThrows() const { return !m_data.noThrow; }
virtual std::ostream& stream() const { return m_stream->stream(); }
virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; }
virtual unsigned int rngSeed() const { return m_data.rngSeed; }
virtual bool forceColour() const { return m_data.forceColour; }
private:
IStream const* openStream() {
if( m_data.outputFilename.empty() )
return new CoutStream();
else if( m_data.outputFilename[0] == '%' ) {
if( m_data.outputFilename == "%debug" )
return new DebugOutStream();
else
throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename );
}
else
return new FileStream( m_data.outputFilename );
}
ConfigData m_data;
std::auto_ptr<IStream const> m_stream;
TestSpec m_testSpec;
};
}
#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
#ifdef CLARA_CONFIG_CONSOLE_WIDTH
#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
#undef CLARA_CONFIG_CONSOLE_WIDTH
#endif
#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
#ifndef STITCH_CLARA_OPEN_NAMESPACE
#define TWOBLUECUBES_CLARA_H_INCLUDED
#define STITCH_CLARA_OPEN_NAMESPACE
#define STITCH_CLARA_CLOSE_NAMESPACE
#else
#define STITCH_CLARA_CLOSE_NAMESPACE }
#endif
#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
#define TBC_TEXT_FORMAT_H_INCLUDED
#endif
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
#endif
namespace Tbc {
#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
#else
const unsigned int consoleWidth = 80;
#endif
struct TextAttributes {
TextAttributes()
: initialIndent( std::string::npos ),
indent( 0 ),
width( consoleWidth-1 ),
tabChar( '\t' )
{}
TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
std::size_t initialIndent;
std::size_t indent;
std::size_t width;
char tabChar;
};
class Text {
public:
Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
: attr( _attr )
{
std::string wrappableChars = " [({.,/|\\-";
std::size_t indent = _attr.initialIndent != std::string::npos
? _attr.initialIndent
: _attr.indent;
std::string remainder = _str;
while( !remainder.empty() ) {
if( lines.size() >= 1000 ) {
lines.push_back( "... message truncated due to excessive size" );
return;
}
std::size_t tabPos = std::string::npos;
std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
std::size_t pos = remainder.find_first_of( '\n' );
if( pos <= width ) {
width = pos;
}
pos = remainder.find_last_of( _attr.tabChar, width );
if( pos != std::string::npos ) {
tabPos = pos;
if( remainder[width] == '\n' )
width--;
remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
}
if( width == remainder.size() ) {
spliceLine( indent, remainder, width );
}
else if( remainder[width] == '\n' ) {
spliceLine( indent, remainder, width );
if( width <= 1 || remainder.size() != 1 )
remainder = remainder.substr( 1 );
indent = _attr.indent;
}
else {
pos = remainder.find_last_of( wrappableChars, width );
if( pos != std::string::npos && pos > 0 ) {
spliceLine( indent, remainder, pos );
if( remainder[0] == ' ' )
remainder = remainder.substr( 1 );
}
else {
spliceLine( indent, remainder, width-1 );
lines.back() += "-";
}
if( lines.size() == 1 )
indent = _attr.indent;
if( tabPos != std::string::npos )
indent += tabPos;
}
}
}
void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
_remainder = _remainder.substr( _pos );
}
typedef std::vector<std::string>::const_iterator const_iterator;
const_iterator begin() const { return lines.begin(); }
const_iterator end() const { return lines.end(); }
std::string const& last() const { return lines.back(); }
std::size_t size() const { return lines.size(); }
std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
std::string toString() const {
std::ostringstream oss;
oss << *this;
return oss.str();
}
inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
it != itEnd; ++it ) {
if( it != _text.begin() )
_stream << "\n";
_stream << *it;
}
return _stream;
}
private:
std::string str;
TextAttributes attr;
std::vector<std::string> lines;
};
}
#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
}
#endif
#endif
#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
#ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
#define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
#ifdef __clang__
#if __has_feature(cxx_nullptr)
#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
#endif
#if __has_feature(cxx_noexcept)
#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
#endif
#endif
#ifdef __GNUC__
#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
#endif
#endif
#ifdef _MSC_VER
#if (_MSC_VER >= 1600)
#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
#endif
#if (_MSC_VER >= 1900 )
#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
#endif
#endif
#if defined(__cplusplus) && __cplusplus >= 201103L
#define CLARA_CPP11_OR_GREATER
#if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR)
#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
#endif
#ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
#endif
#ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
#endif
#if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE)
#define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE
#endif
#if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
#endif
#endif
#if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11)
#define CLARA_CONFIG_CPP11_NULLPTR
#endif
#if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11)
#define CLARA_CONFIG_CPP11_NOEXCEPT
#endif
#if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11)
#define CLARA_CONFIG_CPP11_GENERATED_METHODS
#endif
#if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11)
#define CLARA_CONFIG_CPP11_OVERRIDE
#endif
#if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11)
#define CLARA_CONFIG_CPP11_UNIQUE_PTR
#endif
#if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT)
#define CLARA_NOEXCEPT noexcept
# define CLARA_NOEXCEPT_IS(x) noexcept(x)
#else
#define CLARA_NOEXCEPT throw()
# define CLARA_NOEXCEPT_IS(x)
#endif
#ifdef CLARA_CONFIG_CPP11_NULLPTR
#define CLARA_NULL nullptr
#else
#define CLARA_NULL NULL
#endif
#ifdef CLARA_CONFIG_CPP11_OVERRIDE
#define CLARA_OVERRIDE override
#else
#define CLARA_OVERRIDE
#endif
#ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR
# define CLARA_AUTO_PTR( T ) std::unique_ptr<T>
#else
# define CLARA_AUTO_PTR( T ) std::auto_ptr<T>
#endif
#endif
#include <map>
#include <stdexcept>
#include <memory>
#ifdef STITCH_CLARA_OPEN_NAMESPACE
STITCH_CLARA_OPEN_NAMESPACE
#endif
namespace Clara {
struct UnpositionalTag {};
extern UnpositionalTag _;
#ifdef CLARA_CONFIG_MAIN
UnpositionalTag _;
#endif
namespace Detail {
#ifdef CLARA_CONSOLE_WIDTH
const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
#else
const unsigned int consoleWidth = 80;
#endif
inline bool isTrue( bool value ) { return value; }
using namespace Tbc;
inline bool startsWith( std::string const& str, std::string const& prefix ) {
return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
}
template<typename T> struct RemoveConstRef{ typedef T type; };
template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
template<typename T> struct IsBool { static const bool value = false; };
template<> struct IsBool<bool> { static const bool value = true; };
template<typename T>
void convertInto( std::string const& _source, T& _dest ) {
std::stringstream ss;
ss << _source;
ss >> _dest;
if( ss.fail() )
throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
}
inline void convertInto( std::string const& _source, std::string& _dest ) {
_dest = _source;
}
inline void convertInto( std::string const& _source, bool& _dest ) {
std::string sourceLC = _source;
std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
_dest = true;
else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
_dest = false;
else
throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" );
}
inline void convertInto( bool _source, bool& _dest ) {
_dest = _source;
}
template<typename T>
inline void convertInto( bool, T& ) {
if( isTrue( true ) )
throw std::runtime_error( "Invalid conversion" );
}
template<typename ConfigT>
struct IArgFunction {
virtual ~IArgFunction() {}
#ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS
IArgFunction() = default;
IArgFunction( IArgFunction const& ) = default;
#endif
virtual void set( ConfigT& config, std::string const& value ) const = 0;
virtual void setFlag( ConfigT& config ) const = 0;
virtual bool takesArg() const = 0;
virtual IArgFunction* clone() const = 0;
};
template<typename ConfigT>
class BoundArgFunction {
public:
BoundArgFunction() : functionObj( CLARA_NULL ) {}
BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {}
BoundArgFunction& operator = ( BoundArgFunction const& other ) {
IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL;
delete functionObj;
functionObj = newFunctionObj;
return *this;
}
~BoundArgFunction() { delete functionObj; }
void set( ConfigT& config, std::string const& value ) const {
functionObj->set( config, value );
}
void setFlag( ConfigT& config ) const {
functionObj->setFlag( config );
}
bool takesArg() const { return functionObj->takesArg(); }
bool isSet() const {
return functionObj != CLARA_NULL;
}
private:
IArgFunction<ConfigT>* functionObj;
};
template<typename C>
struct NullBinder : IArgFunction<C>{
virtual void set( C&, std::string const& ) const {}
virtual void setFlag( C& ) const {}
virtual bool takesArg() const { return true; }
virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
};
template<typename C, typename M>
struct BoundDataMember : IArgFunction<C>{
BoundDataMember( M C::* _member ) : member( _member ) {}
virtual void set( C& p, std::string const& stringValue ) const {
convertInto( stringValue, p.*member );
}
virtual void setFlag( C& p ) const {
convertInto( true, p.*member );
}
virtual bool takesArg() const { return !IsBool<M>::value; }
virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
M C::* member;
};
template<typename C, typename M>
struct BoundUnaryMethod : IArgFunction<C>{
BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
virtual void set( C& p, std::string const& stringValue ) const {
typename RemoveConstRef<M>::type value;
convertInto( stringValue, value );
(p.*member)( value );
}
virtual void setFlag( C& p ) const {
typename RemoveConstRef<M>::type value;
convertInto( true, value );
(p.*member)( value );
}
virtual bool takesArg() const { return !IsBool<M>::value; }
virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
void (C::*member)( M );
};
template<typename C>
struct BoundNullaryMethod : IArgFunction<C>{
BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
virtual void set( C& p, std::string const& stringValue ) const {
bool value;
convertInto( stringValue, value );
if( value )
(p.*member)();
}
virtual void setFlag( C& p ) const {
(p.*member)();
}
virtual bool takesArg() const { return false; }
virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
void (C::*member)();
};
template<typename C>
struct BoundUnaryFunction : IArgFunction<C>{
BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
virtual void set( C& obj, std::string const& stringValue ) const {
bool value;
convertInto( stringValue, value );
if( value )
function( obj );
}
virtual void setFlag( C& p ) const {
function( p );
}
virtual bool takesArg() const { return false; }
virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
void (*function)( C& );
};
template<typename C, typename T>
struct BoundBinaryFunction : IArgFunction<C>{
BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
virtual void set( C& obj, std::string const& stringValue ) const {
typename RemoveConstRef<T>::type value;
convertInto( stringValue, value );
function( obj, value );
}
virtual void setFlag( C& obj ) const {
typename RemoveConstRef<T>::type value;
convertInto( true, value );
function( obj, value );
}
virtual bool takesArg() const { return !IsBool<T>::value; }
virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
void (*function)( C&, T );
};
}
struct Parser {
Parser() : separators( " \t=:" ) {}
struct Token {
enum Type { Positional, ShortOpt, LongOpt };
Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
Type type;
std::string data;
};
void parseIntoTokens( int argc, char const* const argv[], std::vector<Parser::Token>& tokens ) const {
const std::string doubleDash = "--";
for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
parseIntoTokens( argv[i] , tokens);
}
void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const {
while( !arg.empty() ) {
Parser::Token token( Parser::Token::Positional, arg );
arg = "";
if( token.data[0] == '-' ) {
if( token.data.size() > 1 && token.data[1] == '-' ) {
token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
}
else {
token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
arg = "-" + token.data.substr( 1 );
token.data = token.data.substr( 0, 1 );
}
}
}
if( token.type != Parser::Token::Positional ) {
std::size_t pos = token.data.find_first_of( separators );
if( pos != std::string::npos ) {
arg = token.data.substr( pos+1 );
token.data = token.data.substr( 0, pos );
}
}
tokens.push_back( token );
}
}
std::string separators;
};
template<typename ConfigT>
struct CommonArgProperties {
CommonArgProperties() {}
CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
Detail::BoundArgFunction<ConfigT> boundField;
std::string description;
std::string detail;
std::string placeholder;
bool takesArg() const {
return !placeholder.empty();
}
void validate() const {
if( !boundField.isSet() )
throw std::logic_error( "option not bound" );
}
};
struct OptionArgProperties {
std::vector<std::string> shortNames;
std::string longName;
bool hasShortName( std::string const& shortName ) const {
return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
}
bool hasLongName( std::string const& _longName ) const {
return _longName == longName;
}
};
struct PositionalArgProperties {
PositionalArgProperties() : position( -1 ) {}
int position;
bool isFixedPositional() const {
return position != -1;
}
};
template<typename ConfigT>
class CommandLine {
struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
Arg() {}
Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
using CommonArgProperties<ConfigT>::placeholder;
std::string dbgName() const {
if( !longName.empty() )
return "--" + longName;
if( !shortNames.empty() )
return "-" + shortNames[0];
return "positional args";
}
std::string commands() const {
std::ostringstream oss;
bool first = true;
std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
for(; it != itEnd; ++it ) {
if( first )
first = false;
else
oss << ", ";
oss << "-" << *it;
}
if( !longName.empty() ) {
if( !first )
oss << ", ";
oss << "--" << longName;
}
if( !placeholder.empty() )
oss << " <" << placeholder << ">";
return oss.str();
}
};
typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr;
friend void addOptName( Arg& arg, std::string const& optName )
{
if( optName.empty() )
return;
if( Detail::startsWith( optName, "--" ) ) {
if( !arg.longName.empty() )
throw std::logic_error( "Only one long opt may be specified. '"
+ arg.longName
+ "' already specified, now attempting to add '"
+ optName + "'" );
arg.longName = optName.substr( 2 );
}
else if( Detail::startsWith( optName, "-" ) )
arg.shortNames.push_back( optName.substr( 1 ) );
else
throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
}
friend void setPositionalArg( Arg& arg, int position )
{
arg.position = position;
}
class ArgBuilder {
public:
ArgBuilder( Arg* arg ) : m_arg( arg ) {}
template<typename C, typename M>
void bind( M C::* field, std::string const& placeholder ) {
m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
m_arg->placeholder = placeholder;
}
template<typename C>
void bind( bool C::* field ) {
m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
}
template<typename C, typename M>
void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
m_arg->placeholder = placeholder;
}
template<typename C>
void bind( void (C::* unaryMethod)( bool ) ) {
m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
}
template<typename C>
void bind( void (C::* nullaryMethod)() ) {
m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
}
template<typename C>
void bind( void (* unaryFunction)( C& ) ) {
m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
}
template<typename C, typename T>
void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
m_arg->placeholder = placeholder;
}
ArgBuilder& describe( std::string const& description ) {
m_arg->description = description;
return *this;
}
ArgBuilder& detail( std::string const& detail ) {
m_arg->detail = detail;
return *this;
}
protected:
Arg* m_arg;
};
class OptBuilder : public ArgBuilder {
public:
OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
OptBuilder& operator[]( std::string const& optName ) {
addOptName( *ArgBuilder::m_arg, optName );
return *this;
}
};
public:
CommandLine()
: m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
m_highestSpecifiedArgPosition( 0 ),
m_throwOnUnrecognisedTokens( false )
{}
CommandLine( CommandLine const& other )
: m_boundProcessName( other.m_boundProcessName ),
m_options ( other.m_options ),
m_positionalArgs( other.m_positionalArgs ),
m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
{
if( other.m_floatingArg.get() )
m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
}
CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
m_throwOnUnrecognisedTokens = shouldThrow;
return *this;
}
OptBuilder operator[]( std::string const& optName ) {
m_options.push_back( Arg() );
addOptName( m_options.back(), optName );
OptBuilder builder( &m_options.back() );
return builder;
}
ArgBuilder operator[]( int position ) {
m_positionalArgs.insert( std::make_pair( position, Arg() ) );
if( position > m_highestSpecifiedArgPosition )
m_highestSpecifiedArgPosition = position;
setPositionalArg( m_positionalArgs[position], position );
ArgBuilder builder( &m_positionalArgs[position] );
return builder;
}
ArgBuilder operator[]( UnpositionalTag ) {
if( m_floatingArg.get() )
throw std::logic_error( "Only one unpositional argument can be added" );
m_floatingArg.reset( new Arg() );
ArgBuilder builder( m_floatingArg.get() );
return builder;
}
template<typename C, typename M>
void bindProcessName( M C::* field ) {
m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
}
template<typename C, typename M>
void bindProcessName( void (C::*_unaryMethod)( M ) ) {
m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
}
void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
std::size_t maxWidth = 0;
for( it = itBegin; it != itEnd; ++it )
maxWidth = (std::max)( maxWidth, it->commands().size() );
for( it = itBegin; it != itEnd; ++it ) {
Detail::Text usage( it->commands(), Detail::TextAttributes()
.setWidth( maxWidth+indent )
.setIndent( indent ) );
Detail::Text desc( it->description, Detail::TextAttributes()
.setWidth( width - maxWidth - 3 ) );
for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
std::string usageCol = i < usage.size() ? usage[i] : "";
os << usageCol;
if( i < desc.size() && !desc[i].empty() )
os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
<< desc[i];
os << "\n";
}
}
}
std::string optUsage() const {
std::ostringstream oss;
optUsage( oss );
return oss.str();
}
void argSynopsis( std::ostream& os ) const {
for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
if( i > 1 )
os << " ";
typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
if( it != m_positionalArgs.end() )
os << "<" << it->second.placeholder << ">";
else if( m_floatingArg.get() )
os << "<" << m_floatingArg->placeholder << ">";
else
throw std::logic_error( "non consecutive positional arguments with no floating args" );
}
if( m_floatingArg.get() ) {
if( m_highestSpecifiedArgPosition > 1 )
os << " ";
os << "[<" << m_floatingArg->placeholder << "> ...]";
}
}
std::string argSynopsis() const {
std::ostringstream oss;
argSynopsis( oss );
return oss.str();
}
void usage( std::ostream& os, std::string const& procName ) const {
validate();
os << "usage:\n " << procName << " ";
argSynopsis( os );
if( !m_options.empty() ) {
os << " [options]\n\nwhere options are: \n";
optUsage( os, 2 );
}
os << "\n";
}
std::string usage( std::string const& procName ) const {
std::ostringstream oss;
usage( oss, procName );
return oss.str();
}
ConfigT parse( int argc, char const* const argv[] ) const {
ConfigT config;
parseInto( argc, argv, config );
return config;
}
std::vector<Parser::Token> parseInto( int argc, char const* argv[], ConfigT& config ) const {
std::string processName = argv[0];
std::size_t lastSlash = processName.find_last_of( "/\\" );
if( lastSlash != std::string::npos )
processName = processName.substr( lastSlash+1 );
m_boundProcessName.set( config, processName );
std::vector<Parser::Token> tokens;
Parser parser;
parser.parseIntoTokens( argc, argv, tokens );
return populate( tokens, config );
}
std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
validate();
std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
unusedTokens = populateFixedArgs( unusedTokens, config );
unusedTokens = populateFloatingArgs( unusedTokens, config );
return unusedTokens;
}
std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
std::vector<Parser::Token> unusedTokens;
std::vector<std::string> errors;
for( std::size_t i = 0; i < tokens.size(); ++i ) {
Parser::Token const& token = tokens[i];
typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
for(; it != itEnd; ++it ) {
Arg const& arg = *it;
try {
if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
if( arg.takesArg() ) {
if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
errors.push_back( "Expected argument to option: " + token.data );
else
arg.boundField.set( config, tokens[++i].data );
}
else {
arg.boundField.setFlag( config );
}
break;
}
}
catch( std::exception& ex ) {
errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
}
}
if( it == itEnd ) {
if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
unusedTokens.push_back( token );
else if( errors.empty() && m_throwOnUnrecognisedTokens )
errors.push_back( "unrecognised option: " + token.data );
}
}
if( !errors.empty() ) {
std::ostringstream oss;
for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
it != itEnd;
++it ) {
if( it != errors.begin() )
oss << "\n";
oss << *it;
}
throw std::runtime_error( oss.str() );
}
return unusedTokens;
}
std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
std::vector<Parser::Token> unusedTokens;
int position = 1;
for( std::size_t i = 0; i < tokens.size(); ++i ) {
Parser::Token const& token = tokens[i];
typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
if( it != m_positionalArgs.end() )
it->second.boundField.set( config, token.data );
else
unusedTokens.push_back( token );
if( token.type == Parser::Token::Positional )
position++;
}
return unusedTokens;
}
std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
if( !m_floatingArg.get() )
return tokens;
std::vector<Parser::Token> unusedTokens;
for( std::size_t i = 0; i < tokens.size(); ++i ) {
Parser::Token const& token = tokens[i];
if( token.type == Parser::Token::Positional )
m_floatingArg->boundField.set( config, token.data );
else
unusedTokens.push_back( token );
}
return unusedTokens;
}
void validate() const
{
if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
throw std::logic_error( "No options or arguments specified" );
for( typename std::vector<Arg>::const_iterator it = m_options.begin(),
itEnd = m_options.end();
it != itEnd; ++it )
it->validate();
}
private:
Detail::BoundArgFunction<ConfigT> m_boundProcessName;
std::vector<Arg> m_options;
std::map<int, Arg> m_positionalArgs;
ArgAutoPtr m_floatingArg;
int m_highestSpecifiedArgPosition;
bool m_throwOnUnrecognisedTokens;
};
}
STITCH_CLARA_CLOSE_NAMESPACE
#undef STITCH_CLARA_OPEN_NAMESPACE
#undef STITCH_CLARA_CLOSE_NAMESPACE
#endif
#undef STITCH_CLARA_OPEN_NAMESPACE
#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
#endif
#include <fstream>
namespace Catch {
inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
inline void abortAfterX( ConfigData& config, int x ) {
if( x < 1 )
throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
config.abortAfter = x;
}
inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
inline void addWarning( ConfigData& config, std::string const& _warning ) {
if( _warning == "NoAssertions" )
config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
else
throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
}
inline void setOrder( ConfigData& config, std::string const& order ) {
if( startsWith( "declared", order ) )
config.runOrder = RunTests::InDeclarationOrder;
else if( startsWith( "lexical", order ) )
config.runOrder = RunTests::InLexicographicalOrder;
else if( startsWith( "random", order ) )
config.runOrder = RunTests::InRandomOrder;
else
throw std::runtime_error( "Unrecognised ordering: '" + order + "'" );
}
inline void setRngSeed( ConfigData& config, std::string const& seed ) {
if( seed == "time" ) {
config.rngSeed = static_cast<unsigned int>( std::time(0) );
}
else {
std::stringstream ss;
ss << seed;
ss >> config.rngSeed;
if( ss.fail() )
throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" );
}
}
inline void setVerbosity( ConfigData& config, int level ) {
config.verbosity = static_cast<Verbosity::Level>( level );
}
inline void setShowDurations( ConfigData& config, bool _showDurations ) {
config.showDurations = _showDurations
? ShowDurations::Always
: ShowDurations::Never;
}
inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
std::ifstream f( _filename.c_str() );
if( !f.is_open() )
throw std::domain_error( "Unable to load input file: " + _filename );
std::string line;
while( std::getline( f, line ) ) {
line = trim(line);
if( !line.empty() && !startsWith( line, "#" ) )
addTestOrTags( config, "\"" + line + "\"," );
}
}
inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
using namespace Clara;
CommandLine<ConfigData> cli;
cli.bindProcessName( &ConfigData::processName );
cli["-?"]["-h"]["--help"]
.describe( "display usage information" )
.bind( &ConfigData::showHelp );
cli["-l"]["--list-tests"]
.describe( "list all/matching test cases" )
.bind( &ConfigData::listTests );
cli["-t"]["--list-tags"]
.describe( "list all/matching tags" )
.bind( &ConfigData::listTags );
cli["-s"]["--success"]
.describe( "include successful tests in output" )
.bind( &ConfigData::showSuccessfulTests );
cli["-b"]["--break"]
.describe( "break into debugger on failure" )
.bind( &ConfigData::shouldDebugBreak );
cli["-e"]["--nothrow"]
.describe( "skip exception tests" )
.bind( &ConfigData::noThrow );
cli["-i"]["--invisibles"]
.describe( "show invisibles (tabs, newlines)" )
.bind( &ConfigData::showInvisibles );
cli["-o"]["--out"]
.describe( "output filename" )
.bind( &ConfigData::outputFilename, "filename" );
cli["-r"]["--reporter"]
.describe( "reporter to use (defaults to console)" )
.bind( &addReporterName, "name" );
cli["-n"]["--name"]
.describe( "suite name" )
.bind( &ConfigData::name, "name" );
cli["-a"]["--abort"]
.describe( "abort at first failure" )
.bind( &abortAfterFirst );
cli["-x"]["--abortx"]
.describe( "abort after x failures" )
.bind( &abortAfterX, "no. failures" );
cli["-w"]["--warn"]
.describe( "enable warnings" )
.bind( &addWarning, "warning name" );
cli[_]
.describe( "which test or tests to use" )
.bind( &addTestOrTags, "test name, pattern or tags" );
cli["-d"]["--durations"]
.describe( "show test durations" )
.bind( &setShowDurations, "yes/no" );
cli["-f"]["--input-file"]
.describe( "load test names to run from a file" )
.bind( &loadTestNamesFromFile, "filename" );
cli["-#"]["--filenames-as-tags"]
.describe( "adds a tag for the filename" )
.bind( &ConfigData::filenamesAsTags );
cli["--list-test-names-only"]
.describe( "list all/matching test cases names only" )
.bind( &ConfigData::listTestNamesOnly );
cli["--list-reporters"]
.describe( "list all reporters" )
.bind( &ConfigData::listReporters );
cli["--order"]
.describe( "test case order (defaults to decl)" )
.bind( &setOrder, "decl|lex|rand" );
cli["--rng-seed"]
.describe( "set a specific seed for random numbers" )
.bind( &setRngSeed, "'time'|number" );
cli["--force-colour"]
.describe( "force colourised output" )
.bind( &ConfigData::forceColour );
return cli;
}
}
#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
# ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
# define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
# endif
# else
# define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
# endif
#endif
#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
#include <string>
#include <vector>
#include <sstream>
#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
#endif
namespace Tbc {
#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
#else
const unsigned int consoleWidth = 80;
#endif
struct TextAttributes {
TextAttributes()
: initialIndent( std::string::npos ),
indent( 0 ),
width( consoleWidth-1 ),
tabChar( '\t' )
{}
TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
std::size_t initialIndent;
std::size_t indent;
std::size_t width;
char tabChar;
};
class Text {
public:
Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
: attr( _attr )
{
std::string wrappableChars = " [({.,/|\\-";
std::size_t indent = _attr.initialIndent != std::string::npos
? _attr.initialIndent
: _attr.indent;
std::string remainder = _str;
while( !remainder.empty() ) {
if( lines.size() >= 1000 ) {
lines.push_back( "... message truncated due to excessive size" );
return;
}
std::size_t tabPos = std::string::npos;
std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
std::size_t pos = remainder.find_first_of( '\n' );
if( pos <= width ) {
width = pos;
}
pos = remainder.find_last_of( _attr.tabChar, width );
if( pos != std::string::npos ) {
tabPos = pos;
if( remainder[width] == '\n' )
width--;
remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
}
if( width == remainder.size() ) {
spliceLine( indent, remainder, width );
}
else if( remainder[width] == '\n' ) {
spliceLine( indent, remainder, width );
if( width <= 1 || remainder.size() != 1 )
remainder = remainder.substr( 1 );
indent = _attr.indent;
}
else {
pos = remainder.find_last_of( wrappableChars, width );
if( pos != std::string::npos && pos > 0 ) {
spliceLine( indent, remainder, pos );
if( remainder[0] == ' ' )
remainder = remainder.substr( 1 );
}
else {
spliceLine( indent, remainder, width-1 );
lines.back() += "-";
}
if( lines.size() == 1 )
indent = _attr.indent;
if( tabPos != std::string::npos )
indent += tabPos;
}
}
}
void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
_remainder = _remainder.substr( _pos );
}
typedef std::vector<std::string>::const_iterator const_iterator;
const_iterator begin() const { return lines.begin(); }
const_iterator end() const { return lines.end(); }
std::string const& last() const { return lines.back(); }
std::size_t size() const { return lines.size(); }
std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
std::string toString() const {
std::ostringstream oss;
oss << *this;
return oss.str();
}
inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
it != itEnd; ++it ) {
if( it != _text.begin() )
_stream << "\n";
_stream << *it;
}
return _stream;
}
private:
std::string str;
TextAttributes attr;
std::vector<std::string> lines;
};
}
#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
}
#endif
#endif
#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
namespace Catch {
using Tbc::Text;
using Tbc::TextAttributes;
}
#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
namespace Catch {
struct Colour {
enum Code {
None = 0,
White,
Red,
Green,
Blue,
Cyan,
Yellow,
Grey,
Bright = 0x10,
BrightRed = Bright | Red,
BrightGreen = Bright | Green,
LightGrey = Bright | Grey,
BrightWhite = Bright | White,
FileName = LightGrey,
Warning = Yellow,
ResultError = BrightRed,
ResultSuccess = BrightGreen,
ResultExpectedFailure = Warning,
Error = BrightRed,
Success = Green,
OriginalExpression = Cyan,
ReconstructedExpression = Yellow,
SecondaryText = LightGrey,
Headers = White
};
Colour( Code _colourCode );
Colour( Colour const& other );
~Colour();
static void use( Code _colourCode );
private:
bool m_moved;
};
inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
}
#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
#include <string>
#include <ostream>
#include <map>
#include <assert.h>
namespace Catch
{
struct ReporterConfig {
explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig )
: m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream )
: m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
std::ostream& stream() const { return *m_stream; }
Ptr<IConfig const> fullConfig() const { return m_fullConfig; }
private:
std::ostream* m_stream;
Ptr<IConfig const> m_fullConfig;
};
struct ReporterPreferences {
ReporterPreferences()
: shouldRedirectStdOut( false )
{}
bool shouldRedirectStdOut;
};
template<typename T>
struct LazyStat : Option<T> {
LazyStat() : used( false ) {}
LazyStat& operator=( T const& _value ) {
Option<T>::operator=( _value );
used = false;
return *this;
}
void reset() {
Option<T>::reset();
used = false;
}
bool used;
};
struct TestRunInfo {
TestRunInfo( std::string const& _name ) : name( _name ) {}
std::string name;
};
struct GroupInfo {
GroupInfo( std::string const& _name,
std::size_t _groupIndex,
std::size_t _groupsCount )
: name( _name ),
groupIndex( _groupIndex ),
groupsCounts( _groupsCount )
{}
std::string name;
std::size_t groupIndex;
std::size_t groupsCounts;
};
struct AssertionStats {
AssertionStats( AssertionResult const& _assertionResult,
std::vector<MessageInfo> const& _infoMessages,
Totals const& _totals )
: assertionResult( _assertionResult ),
infoMessages( _infoMessages ),
totals( _totals )
{
if( assertionResult.hasMessage() ) {
MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
builder << assertionResult.getMessage();
builder.m_info.message = builder.m_stream.str();
infoMessages.push_back( builder.m_info );
}
}
virtual ~AssertionStats();
# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
AssertionStats( AssertionStats const& ) = default;
AssertionStats( AssertionStats && ) = default;
AssertionStats& operator = ( AssertionStats const& ) = default;
AssertionStats& operator = ( AssertionStats && ) = default;
# endif
AssertionResult assertionResult;
std::vector<MessageInfo> infoMessages;
Totals totals;
};
struct SectionStats {
SectionStats( SectionInfo const& _sectionInfo,
Counts const& _assertions,
double _durationInSeconds,
bool _missingAssertions )
: sectionInfo( _sectionInfo ),
assertions( _assertions ),
durationInSeconds( _durationInSeconds ),
missingAssertions( _missingAssertions )
{}
virtual ~SectionStats();
# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
SectionStats( SectionStats const& ) = default;
SectionStats( SectionStats && ) = default;
SectionStats& operator = ( SectionStats const& ) = default;
SectionStats& operator = ( SectionStats && ) = default;
# endif
SectionInfo sectionInfo;
Counts assertions;
double durationInSeconds;
bool missingAssertions;
};
struct TestCaseStats {
TestCaseStats( TestCaseInfo const& _testInfo,
Totals const& _totals,
std::string const& _stdOut,
std::string const& _stdErr,
bool _aborting )
: testInfo( _testInfo ),
totals( _totals ),
stdOut( _stdOut ),
stdErr( _stdErr ),
aborting( _aborting )
{}
virtual ~TestCaseStats();
# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
TestCaseStats( TestCaseStats const& ) = default;
TestCaseStats( TestCaseStats && ) = default;
TestCaseStats& operator = ( TestCaseStats const& ) = default;
TestCaseStats& operator = ( TestCaseStats && ) = default;
# endif
TestCaseInfo testInfo;
Totals totals;
std::string stdOut;
std::string stdErr;
bool aborting;
};
struct TestGroupStats {
TestGroupStats( GroupInfo const& _groupInfo,
Totals const& _totals,
bool _aborting )
: groupInfo( _groupInfo ),
totals( _totals ),
aborting( _aborting )
{}
TestGroupStats( GroupInfo const& _groupInfo )
: groupInfo( _groupInfo ),
aborting( false )
{}
virtual ~TestGroupStats();
# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
TestGroupStats( TestGroupStats const& ) = default;
TestGroupStats( TestGroupStats && ) = default;
TestGroupStats& operator = ( TestGroupStats const& ) = default;
TestGroupStats& operator = ( TestGroupStats && ) = default;
# endif
GroupInfo groupInfo;
Totals totals;
bool aborting;
};
struct TestRunStats {
TestRunStats( TestRunInfo const& _runInfo,
Totals const& _totals,
bool _aborting )
: runInfo( _runInfo ),
totals( _totals ),
aborting( _aborting )
{}
virtual ~TestRunStats();
# ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
TestRunStats( TestRunStats const& _other )
: runInfo( _other.runInfo ),
totals( _other.totals ),
aborting( _other.aborting )
{}
# else
TestRunStats( TestRunStats const& ) = default;
TestRunStats( TestRunStats && ) = default;
TestRunStats& operator = ( TestRunStats const& ) = default;
TestRunStats& operator = ( TestRunStats && ) = default;
# endif
TestRunInfo runInfo;
Totals totals;
bool aborting;
};
struct IStreamingReporter : IShared {
virtual ~IStreamingReporter();
virtual ReporterPreferences getPreferences() const = 0;
virtual void noMatchingTestCases( std::string const& spec ) = 0;
virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
};
struct IReporterFactory : IShared {
virtual ~IReporterFactory();
virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
virtual std::string getDescription() const = 0;
};
struct IReporterRegistry {
typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;
typedef std::vector<Ptr<IReporterFactory> > Listeners;
virtual ~IReporterRegistry();
virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0;
virtual FactoryMap const& getFactories() const = 0;
virtual Listeners const& getListeners() const = 0;
};
Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );
}
#include <limits>
#include <algorithm>
namespace Catch {
inline std::size_t listTests( Config const& config ) {
TestSpec testSpec = config.testSpec();
if( config.testSpec().hasFilters() )
Catch::cout() << "Matching test cases:\n";
else {
Catch::cout() << "All available test cases:\n";
testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
}
std::size_t matchedTests = 0;
TextAttributes nameAttr, tagsAttr;
nameAttr.setInitialIndent( 2 ).setIndent( 4 );
tagsAttr.setIndent( 6 );
std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
it != itEnd;
++it ) {
matchedTests++;
TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
Colour::Code colour = testCaseInfo.isHidden()
? Colour::SecondaryText
: Colour::None;
Colour colourGuard( colour );
Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
if( !testCaseInfo.tags.empty() )
Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
}
if( !config.testSpec().hasFilters() )
Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
else
Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
return matchedTests;
}
inline std::size_t listTestsNamesOnly( Config const& config ) {
TestSpec testSpec = config.testSpec();
if( !config.testSpec().hasFilters() )
testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
std::size_t matchedTests = 0;
std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
it != itEnd;
++it ) {
matchedTests++;
TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
Catch::cout() << testCaseInfo.name << std::endl;
}
return matchedTests;
}
struct TagInfo {
TagInfo() : count ( 0 ) {}
void add( std::string const& spelling ) {
++count;
spellings.insert( spelling );
}
std::string all() const {
std::string out;
for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
it != itEnd;
++it )
out += "[" + *it + "]";
return out;
}
std::set<std::string> spellings;
std::size_t count;
};
inline std::size_t listTags( Config const& config ) {
TestSpec testSpec = config.testSpec();
if( config.testSpec().hasFilters() )
Catch::cout() << "Tags for matching test cases:\n";
else {
Catch::cout() << "All available tags:\n";
testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
}
std::map<std::string, TagInfo> tagCounts;
std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
it != itEnd;
++it ) {
for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
tagItEnd = it->getTestCaseInfo().tags.end();
tagIt != tagItEnd;
++tagIt ) {
std::string tagName = *tagIt;
std::string lcaseTagName = toLower( tagName );
std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
if( countIt == tagCounts.end() )
countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
countIt->second.add( tagName );
}
}
for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
countItEnd = tagCounts.end();
countIt != countItEnd;
++countIt ) {
std::ostringstream oss;
oss << " " << std::setw(2) << countIt->second.count << " ";
Text wrapper( countIt->second.all(), TextAttributes()
.setInitialIndent( 0 )
.setIndent( oss.str().size() )
.setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
Catch::cout() << oss.str() << wrapper << "\n";
}
Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl;
return tagCounts.size();
}
inline std::size_t listReporters( Config const& ) {
Catch::cout() << "Available reporters:\n";
IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
std::size_t maxNameLen = 0;
for(it = itBegin; it != itEnd; ++it )
maxNameLen = (std::max)( maxNameLen, it->first.size() );
for(it = itBegin; it != itEnd; ++it ) {
Text wrapper( it->second->getDescription(), TextAttributes()
.setInitialIndent( 0 )
.setIndent( 7+maxNameLen )
.setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
Catch::cout() << " "
<< it->first
<< ":"
<< std::string( maxNameLen - it->first.size() + 2, ' ' )
<< wrapper << "\n";
}
Catch::cout() << std::endl;
return factories.size();
}
inline Option<std::size_t> list( Config const& config ) {
Option<std::size_t> listedCount;
if( config.listTests() )
listedCount = listedCount.valueOr(0) + listTests( config );
if( config.listTestNamesOnly() )
listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
if( config.listTags() )
listedCount = listedCount.valueOr(0) + listTags( config );
if( config.listReporters() )
listedCount = listedCount.valueOr(0) + listReporters( config );
return listedCount;
}
}
#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
#include <map>
#include <string>
#include <assert.h>
#include <vector>
namespace Catch {
namespace TestCaseTracking {
struct ITracker : SharedImpl<> {
virtual ~ITracker();
virtual std::string name() const = 0;
virtual bool isComplete() const = 0;
virtual bool isSuccessfullyCompleted() const = 0;
virtual bool isOpen() const = 0;
virtual bool hasChildren() const = 0;
virtual ITracker& parent() = 0;
virtual void close() = 0;
virtual void fail() = 0;
virtual void markAsNeedingAnotherRun() = 0;
virtual void addChild( Ptr<ITracker> const& child ) = 0;
virtual ITracker* findChild( std::string const& name ) = 0;
virtual void openChild() = 0;
};
class TrackerContext {
enum RunState {
NotStarted,
Executing,
CompletedCycle
};
Ptr<ITracker> m_rootTracker;
ITracker* m_currentTracker;
RunState m_runState;
public:
static TrackerContext& instance() {
static TrackerContext s_instance;
return s_instance;
}
TrackerContext()
: m_currentTracker( CATCH_NULL ),
m_runState( NotStarted )
{}
ITracker& startRun();
void endRun() {
m_rootTracker.reset();
m_currentTracker = CATCH_NULL;
m_runState = NotStarted;
}
void startCycle() {
m_currentTracker = m_rootTracker.get();
m_runState = Executing;
}
void completeCycle() {
m_runState = CompletedCycle;
}
bool completedCycle() const {
return m_runState == CompletedCycle;
}
ITracker& currentTracker() {
return *m_currentTracker;
}
void setCurrentTracker( ITracker* tracker ) {
m_currentTracker = tracker;
}
};
class TrackerBase : public ITracker {
protected:
enum CycleState {
NotStarted,
Executing,
ExecutingChildren,
NeedsAnotherRun,
CompletedSuccessfully,
Failed
};
class TrackerHasName {
std::string m_name;
public:
TrackerHasName( std::string const& name ) : m_name( name ) {}
bool operator ()( Ptr<ITracker> const& tracker ) {
return tracker->name() == m_name;
}
};
typedef std::vector<Ptr<ITracker> > Children;
std::string m_name;
TrackerContext& m_ctx;
ITracker* m_parent;
Children m_children;
CycleState m_runState;
public:
TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent )
: m_name( name ),
m_ctx( ctx ),
m_parent( parent ),
m_runState( NotStarted )
{}
virtual ~TrackerBase();
virtual std::string name() const CATCH_OVERRIDE {
return m_name;
}
virtual bool isComplete() const CATCH_OVERRIDE {
return m_runState == CompletedSuccessfully || m_runState == Failed;
}
virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE {
return m_runState == CompletedSuccessfully;
}
virtual bool isOpen() const CATCH_OVERRIDE {
return m_runState != NotStarted && !isComplete();
}
virtual bool hasChildren() const CATCH_OVERRIDE {
return !m_children.empty();
}
virtual void addChild( Ptr<ITracker> const& child ) CATCH_OVERRIDE {
m_children.push_back( child );
}
virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE {
Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) );
return( it != m_children.end() )
? it->get()
: CATCH_NULL;
}
virtual ITracker& parent() CATCH_OVERRIDE {
assert( m_parent );
return *m_parent;
}
virtual void openChild() CATCH_OVERRIDE {
if( m_runState != ExecutingChildren ) {
m_runState = ExecutingChildren;
if( m_parent )
m_parent->openChild();
}
}
void open() {
m_runState = Executing;
moveToThis();
if( m_parent )
m_parent->openChild();
}
virtual void close() CATCH_OVERRIDE {
while( &m_ctx.currentTracker() != this )
m_ctx.currentTracker().close();
switch( m_runState ) {
case NotStarted:
case CompletedSuccessfully:
case Failed:
throw std::logic_error( "Illogical state" );
case NeedsAnotherRun:
break;;
case Executing:
m_runState = CompletedSuccessfully;
break;
case ExecutingChildren:
if( m_children.empty() || m_children.back()->isComplete() )
m_runState = CompletedSuccessfully;
break;
default:
throw std::logic_error( "Unexpected state" );
}
moveToParent();
m_ctx.completeCycle();
}
virtual void fail() CATCH_OVERRIDE {
m_runState = Failed;
if( m_parent )
m_parent->markAsNeedingAnotherRun();
moveToParent();
m_ctx.completeCycle();
}
virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE {
m_runState = NeedsAnotherRun;
}
private:
void moveToParent() {
assert( m_parent );
m_ctx.setCurrentTracker( m_parent );
}
void moveToThis() {
m_ctx.setCurrentTracker( this );
}
};
class SectionTracker : public TrackerBase {
public:
SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent )
: TrackerBase( name, ctx, parent )
{}
virtual ~SectionTracker();
static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) {
SectionTracker* section = CATCH_NULL;
ITracker& currentTracker = ctx.currentTracker();
if( ITracker* childTracker = currentTracker.findChild( name ) ) {
section = dynamic_cast<SectionTracker*>( childTracker );
assert( section );
}
else {
section = new SectionTracker( name, ctx, &currentTracker );
currentTracker.addChild( section );
}
if( !ctx.completedCycle() && !section->isComplete() ) {
section->open();
}
return *section;
}
};
class IndexTracker : public TrackerBase {
int m_size;
int m_index;
public:
IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size )
: TrackerBase( name, ctx, parent ),
m_size( size ),
m_index( -1 )
{}
virtual ~IndexTracker();
static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) {
IndexTracker* tracker = CATCH_NULL;
ITracker& currentTracker = ctx.currentTracker();
if( ITracker* childTracker = currentTracker.findChild( name ) ) {
tracker = dynamic_cast<IndexTracker*>( childTracker );
assert( tracker );
}
else {
tracker = new IndexTracker( name, ctx, &currentTracker, size );
currentTracker.addChild( tracker );
}
if( !ctx.completedCycle() && !tracker->isComplete() ) {
if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
tracker->moveNext();
tracker->open();
}
return *tracker;
}
int index() const { return m_index; }
void moveNext() {
m_index++;
m_children.clear();
}
virtual void close() CATCH_OVERRIDE {
TrackerBase::close();
if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
m_runState = Executing;
}
};
inline ITracker& TrackerContext::startRun() {
m_rootTracker = new SectionTracker( "{root}", *this, CATCH_NULL );
m_currentTracker = CATCH_NULL;
m_runState = Executing;
return *m_rootTracker;
}
}
using TestCaseTracking::ITracker;
using TestCaseTracking::TrackerContext;
using TestCaseTracking::SectionTracker;
using TestCaseTracking::IndexTracker;
}
#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
namespace Catch {
inline void fatal( std::string const& message, int exitCode ) {
IContext& context = Catch::getCurrentContext();
IResultCapture* resultCapture = context.getResultCapture();
resultCapture->handleFatalErrorCondition( message );
if( Catch::alwaysTrue() )
exit( exitCode );
}
}
#if defined ( CATCH_PLATFORM_WINDOWS )
namespace Catch {
struct FatalConditionHandler {
void reset() {}
};
}
#else
#include <signal.h>
namespace Catch {
struct SignalDefs { int id; const char* name; };
extern SignalDefs signalDefs[];
SignalDefs signalDefs[] = {
{ SIGINT, "SIGINT - Terminal interrupt signal" },
{ SIGILL, "SIGILL - Illegal instruction signal" },
{ SIGFPE, "SIGFPE - Floating point error signal" },
{ SIGSEGV, "SIGSEGV - Segmentation violation signal" },
{ SIGTERM, "SIGTERM - Termination request signal" },
{ SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
};
struct FatalConditionHandler {
static void handleSignal( int sig ) {
for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
if( sig == signalDefs[i].id )
fatal( signalDefs[i].name, -sig );
fatal( "<unknown signal>", -sig );
}
FatalConditionHandler() : m_isSet( true ) {
for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
signal( signalDefs[i].id, handleSignal );
}
~FatalConditionHandler() {
reset();
}
void reset() {
if( m_isSet ) {
for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
signal( signalDefs[i].id, SIG_DFL );
m_isSet = false;
}
}
bool m_isSet;
};
}
#endif
#include <set>
#include <string>
namespace Catch {
class StreamRedirect {
public:
StreamRedirect( std::ostream& stream, std::string& targetString )
: m_stream( stream ),
m_prevBuf( stream.rdbuf() ),
m_targetString( targetString )
{
stream.rdbuf( m_oss.rdbuf() );
}
~StreamRedirect() {
m_targetString += m_oss.str();
m_stream.rdbuf( m_prevBuf );
}
private:
std::ostream& m_stream;
std::streambuf* m_prevBuf;
std::ostringstream m_oss;
std::string& m_targetString;
};
class RunContext : public IResultCapture, public IRunner {
RunContext( RunContext const& );
void operator =( RunContext const& );
public:
explicit RunContext( Ptr<IConfig const> const& _config, Ptr<IStreamingReporter> const& reporter )
: m_runInfo( _config->name() ),
m_context( getCurrentMutableContext() ),
m_activeTestCase( CATCH_NULL ),
m_config( _config ),
m_reporter( reporter )
{
m_context.setRunner( this );
m_context.setConfig( m_config );
m_context.setResultCapture( this );
m_reporter->testRunStarting( m_runInfo );
}
virtual ~RunContext() {
m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
}
void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
}
void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
}
Totals runTest( TestCase const& testCase ) {
Totals prevTotals = m_totals;
std::string redirectedCout;
std::string redirectedCerr;
TestCaseInfo testInfo = testCase.getTestCaseInfo();
m_reporter->testCaseStarting( testInfo );
m_activeTestCase = &testCase;
do {
m_trackerContext.startRun();
do {
m_trackerContext.startCycle();
m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name );
runCurrentTest( redirectedCout, redirectedCerr );
}
while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );
}
while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
Totals deltaTotals = m_totals.delta( prevTotals );
m_totals.testCases += deltaTotals.testCases;
m_reporter->testCaseEnded( TestCaseStats( testInfo,
deltaTotals,
redirectedCout,
redirectedCerr,
aborting() ) );
m_activeTestCase = CATCH_NULL;
m_testCaseTracker = CATCH_NULL;
return deltaTotals;
}
Ptr<IConfig const> config() const {
return m_config;
}
private:
virtual void assertionEnded( AssertionResult const& result ) {
if( result.getResultType() == ResultWas::Ok ) {
m_totals.assertions.passed++;
}
else if( !result.isOk() ) {
m_totals.assertions.failed++;
}
if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
m_messages.clear();
m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
m_lastResult = result;
}
virtual bool sectionStarted (
SectionInfo const& sectionInfo,
Counts& assertions
)
{
std::ostringstream oss;
oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, oss.str() );
if( !sectionTracker.isOpen() )
return false;
m_activeSections.push_back( &sectionTracker );
m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
m_reporter->sectionStarting( sectionInfo );
assertions = m_totals.assertions;
return true;
}
bool testForMissingAssertions( Counts& assertions ) {
if( assertions.total() != 0 )
return false;
if( !m_config->warnAboutMissingAssertions() )
return false;
if( m_trackerContext.currentTracker().hasChildren() )
return false;
m_totals.assertions.failed++;
assertions.failed++;
return true;
}
virtual void sectionEnded( SectionEndInfo const& endInfo ) {
Counts assertions = m_totals.assertions - endInfo.prevAssertions;
bool missingAssertions = testForMissingAssertions( assertions );
if( !m_activeSections.empty() ) {
m_activeSections.back()->close();
m_activeSections.pop_back();
}
m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) );
m_messages.clear();
}
virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) {
if( m_unfinishedSections.empty() )
m_activeSections.back()->fail();
else
m_activeSections.back()->close();
m_activeSections.pop_back();
m_unfinishedSections.push_back( endInfo );
}
virtual void pushScopedMessage( MessageInfo const& message ) {
m_messages.push_back( message );
}
virtual void popScopedMessage( MessageInfo const& message ) {
m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
}
virtual std::string getCurrentTestName() const {
return m_activeTestCase
? m_activeTestCase->getTestCaseInfo().name
: "";
}
virtual const AssertionResult* getLastResult() const {
return &m_lastResult;
}
virtual void handleFatalErrorCondition( std::string const& message ) {
ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
resultBuilder.setResultType( ResultWas::FatalErrorCondition );
resultBuilder << message;
resultBuilder.captureExpression();
handleUnfinishedSections();
TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
Counts assertions;
assertions.failed = 1;
SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
m_reporter->sectionEnded( testCaseSectionStats );
TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
Totals deltaTotals;
deltaTotals.testCases.failed = 1;
m_reporter->testCaseEnded( TestCaseStats( testInfo,
deltaTotals,
"",
"",
false ) );
m_totals.testCases.failed++;
testGroupEnded( "", m_totals, 1, 1 );
m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
}
public:
bool aborting() const {
return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
}
private:
void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
m_reporter->sectionStarting( testCaseSection );
Counts prevAssertions = m_totals.assertions;
double duration = 0;
try {
m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
seedRng( *m_config );
Timer timer;
timer.start();
if( m_reporter->getPreferences().shouldRedirectStdOut ) {
StreamRedirect coutRedir( Catch::cout(), redirectedCout );
StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
invokeActiveTestCase();
}
else {
invokeActiveTestCase();
}
duration = timer.getElapsedSeconds();
}
catch( TestFailureException& ) {
}
catch(...) {
makeUnexpectedResultBuilder().useActiveException();
}
m_testCaseTracker->close();
handleUnfinishedSections();
m_messages.clear();
Counts assertions = m_totals.assertions - prevAssertions;
bool missingAssertions = testForMissingAssertions( assertions );
if( testCaseInfo.okToFail() ) {
std::swap( assertions.failedButOk, assertions.failed );
m_totals.assertions.failed -= assertions.failedButOk;
m_totals.assertions.failedButOk += assertions.failedButOk;
}
SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
m_reporter->sectionEnded( testCaseSectionStats );
}
void invokeActiveTestCase() {
FatalConditionHandler fatalConditionHandler;
m_activeTestCase->invoke();
fatalConditionHandler.reset();
}
private:
ResultBuilder makeUnexpectedResultBuilder() const {
return ResultBuilder( m_lastAssertionInfo.macroName.c_str(),
m_lastAssertionInfo.lineInfo,
m_lastAssertionInfo.capturedExpression.c_str(),
m_lastAssertionInfo.resultDisposition );
}
void handleUnfinishedSections() {
for( std::vector<SectionEndInfo>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
itEnd = m_unfinishedSections.rend();
it != itEnd;
++it )
sectionEnded( *it );
m_unfinishedSections.clear();
}
TestRunInfo m_runInfo;
IMutableContext& m_context;
TestCase const* m_activeTestCase;
ITracker* m_testCaseTracker;
ITracker* m_currentSectionTracker;
AssertionResult m_lastResult;
Ptr<IConfig const> m_config;
Totals m_totals;
Ptr<IStreamingReporter> m_reporter;
std::vector<MessageInfo> m_messages;
AssertionInfo m_lastAssertionInfo;
std::vector<SectionEndInfo> m_unfinishedSections;
std::vector<ITracker*> m_activeSections;
TrackerContext m_trackerContext;
};
IResultCapture& getResultCapture() {
if( IResultCapture* capture = getCurrentContext().getResultCapture() )
return *capture;
else
throw std::logic_error( "No result capture instance" );
}
}
#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
namespace Catch {
struct Version {
Version( unsigned int _majorVersion,
unsigned int _minorVersion,
unsigned int _patchNumber,
std::string const& _branchName,
unsigned int _buildNumber );
unsigned int const majorVersion;
unsigned int const minorVersion;
unsigned int const patchNumber;
std::string const branchName;
unsigned int const buildNumber;
friend std::ostream& operator << ( std::ostream& os, Version const& version );
private:
void operator=( Version const& );
};
extern Version libraryVersion;
}
#include <fstream>
#include <stdlib.h>
#include <limits>
namespace Catch {
Ptr<IStreamingReporter> createReporter( std::string const& reporterName, Ptr<Config> const& config ) {
Ptr<IStreamingReporter> reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() );
if( !reporter ) {
std::ostringstream oss;
oss << "No reporter registered with name: '" << reporterName << "'";
throw std::domain_error( oss.str() );
}
return reporter;
}
Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {
std::vector<std::string> reporters = config->getReporterNames();
if( reporters.empty() )
reporters.push_back( "console" );
Ptr<IStreamingReporter> reporter;
for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
it != itEnd;
++it )
reporter = addReporter( reporter, createReporter( *it, config ) );
return reporter;
}
Ptr<IStreamingReporter> addListeners( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> reporters ) {
IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
it != itEnd;
++it )
reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );
return reporters;
}
Totals runTests( Ptr<Config> const& config ) {
Ptr<IConfig const> iconfig = config.get();
Ptr<IStreamingReporter> reporter = makeReporter( config );
reporter = addListeners( iconfig, reporter );
RunContext context( iconfig, reporter );
Totals totals;
context.testGroupStarting( config->name(), 1, 1 );
TestSpec testSpec = config->testSpec();
if( !testSpec.hasFilters() )
testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec();
std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *iconfig );
for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();
it != itEnd;
++it ) {
if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) )
totals += context.runTest( *it );
else
reporter->skipTest( *it );
}
context.testGroupEnded( iconfig->name(), totals, 1, 1 );
return totals;
}
void applyFilenamesAsTags( IConfig const& config ) {
std::vector<TestCase> const& tests = getAllTestCasesSorted( config );
for(std::size_t i = 0; i < tests.size(); ++i ) {
TestCase& test = const_cast<TestCase&>( tests[i] );
std::set<std::string> tags = test.tags;
std::string filename = test.lineInfo.file;
std::string::size_type lastSlash = filename.find_last_of( "\\/" );
if( lastSlash != std::string::npos )
filename = filename.substr( lastSlash+1 );
std::string::size_type lastDot = filename.find_last_of( "." );
if( lastDot != std::string::npos )
filename = filename.substr( 0, lastDot );
tags.insert( "#" + filename );
setTags( test, tags );
}
}
class Session : NonCopyable {
static bool alreadyInstantiated;
public:
struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
Session()
: m_cli( makeCommandLineParser() ) {
if( alreadyInstantiated ) {
std::string msg = "Only one instance of Catch::Session can ever be used";
Catch::cerr() << msg << std::endl;
throw std::logic_error( msg );
}
alreadyInstantiated = true;
}
~Session() {
Catch::cleanUp();
}
void showHelp( std::string const& processName ) {
Catch::cout() << "\nCatch v" << libraryVersion << "\n";
m_cli.usage( Catch::cout(), processName );
Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
}
int applyCommandLine( int argc, char const* argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
try {
m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
if( m_configData.showHelp )
showHelp( m_configData.processName );
m_config.reset();
}
catch( std::exception& ex ) {
{
Colour colourGuard( Colour::Red );
Catch::cerr()
<< "\nError(s) in input:\n"
<< Text( ex.what(), TextAttributes().setIndent(2) )
<< "\n\n";
}
m_cli.usage( Catch::cout(), m_configData.processName );
return (std::numeric_limits<int>::max)();
}
return 0;
}
void useConfigData( ConfigData const& _configData ) {
m_configData = _configData;
m_config.reset();
}
int run( int argc, char const* argv[] ) {
int returnCode = applyCommandLine( argc, argv );
if( returnCode == 0 )
returnCode = run();
return returnCode;
}
int run( int argc, char* argv[] ) {
return run( argc, const_cast<char const**>( argv ) );
}
int run() {
if( m_configData.showHelp )
return 0;
try
{
config();
seedRng( *m_config );
if( m_configData.filenamesAsTags )
applyFilenamesAsTags( *m_config );
if( Option<std::size_t> listed = list( config() ) )
return static_cast<int>( *listed );
return static_cast<int>( runTests( m_config ).assertions.failed );
}
catch( std::exception& ex ) {
Catch::cerr() << ex.what() << std::endl;
return (std::numeric_limits<int>::max)();
}
}
Clara::CommandLine<ConfigData> const& cli() const {
return m_cli;
}
std::vector<Clara::Parser::Token> const& unusedTokens() const {
return m_unusedTokens;
}
ConfigData& configData() {
return m_configData;
}
Config& config() {
if( !m_config )
m_config = new Config( m_configData );
return *m_config;
}
private:
Clara::CommandLine<ConfigData> m_cli;
std::vector<Clara::Parser::Token> m_unusedTokens;
ConfigData m_configData;
Ptr<Config> m_config;
};
bool Session::alreadyInstantiated = false;
}
#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
#include <vector>
#include <set>
#include <sstream>
#include <iostream>
#include <algorithm>
namespace Catch {
struct LexSort {
bool operator() (TestCase i,TestCase j) const { return (i<j);}
};
struct RandomNumberGenerator {
int operator()( int n ) const { return std::rand() % n; }
};
inline std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
std::vector<TestCase> sorted = unsortedTestCases;
switch( config.runOrder() ) {
case RunTests::InLexicographicalOrder:
std::sort( sorted.begin(), sorted.end(), LexSort() );
break;
case RunTests::InRandomOrder:
{
seedRng( config );
RandomNumberGenerator rng;
std::random_shuffle( sorted.begin(), sorted.end(), rng );
}
break;
case RunTests::InDeclarationOrder:
break;
}
return sorted;
}
bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
}
void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
std::set<TestCase> seenFunctions;
for( std::vector<TestCase>::const_iterator it = functions.begin(), itEnd = functions.end();
it != itEnd;
++it ) {
std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );
if( !prev.second ){
Catch::cerr()
<< Colour( Colour::Red )
<< "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
<< "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
<< "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
exit(1);
}
}
}
std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
std::vector<TestCase> filtered;
filtered.reserve( testCases.size() );
for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
it != itEnd;
++it )
if( matchTest( *it, testSpec, config ) )
filtered.push_back( *it );
return filtered;
}
std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
}
class TestRegistry : public ITestCaseRegistry {
public:
TestRegistry()
: m_currentSortOrder( RunTests::InDeclarationOrder ),
m_unnamedCount( 0 )
{}
virtual ~TestRegistry();
virtual void registerTest( TestCase const& testCase ) {
std::string name = testCase.getTestCaseInfo().name;
if( name == "" ) {
std::ostringstream oss;
oss << "Anonymous test case " << ++m_unnamedCount;
return registerTest( testCase.withName( oss.str() ) );
}
m_functions.push_back( testCase );
}
virtual std::vector<TestCase> const& getAllTests() const {
return m_functions;
}
virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const {
if( m_sortedFunctions.empty() )
enforceNoDuplicateTestCases( m_functions );
if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
m_sortedFunctions = sortTests( config, m_functions );
m_currentSortOrder = config.runOrder();
}
return m_sortedFunctions;
}
private:
std::vector<TestCase> m_functions;
mutable RunTests::InWhatOrder m_currentSortOrder;
mutable std::vector<TestCase> m_sortedFunctions;
size_t m_unnamedCount;
std::ios_base::Init m_ostreamInit;
};
class FreeFunctionTestCase : public SharedImpl<ITestCase> {
public:
FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
virtual void invoke() const {
m_fun();
}
private:
virtual ~FreeFunctionTestCase();
TestFunction m_fun;
};
inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
std::string className = classOrQualifiedMethodName;
if( startsWith( className, "&" ) )
{
std::size_t lastColons = className.rfind( "::" );
std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
if( penultimateColons == std::string::npos )
penultimateColons = 1;
className = className.substr( penultimateColons, lastColons-penultimateColons );
}
return className;
}
void registerTestCase
( ITestCase* testCase,
char const* classOrQualifiedMethodName,
NameAndDesc const& nameAndDesc,
SourceLineInfo const& lineInfo ) {
getMutableRegistryHub().registerTest
( makeTestCase
( testCase,
extractClassName( classOrQualifiedMethodName ),
nameAndDesc.name,
nameAndDesc.description,
lineInfo ) );
}
void registerTestCaseFunction
( TestFunction function,
SourceLineInfo const& lineInfo,
NameAndDesc const& nameAndDesc ) {
registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
}
AutoReg::AutoReg
( TestFunction function,
SourceLineInfo const& lineInfo,
NameAndDesc const& nameAndDesc ) {
registerTestCaseFunction( function, lineInfo, nameAndDesc );
}
AutoReg::~AutoReg() {}
}
#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
#include <map>
namespace Catch {
class ReporterRegistry : public IReporterRegistry {
public:
virtual ~ReporterRegistry() CATCH_OVERRIDE {}
virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE {
FactoryMap::const_iterator it = m_factories.find( name );
if( it == m_factories.end() )
return CATCH_NULL;
return it->second->create( ReporterConfig( config ) );
}
void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) {
m_factories.insert( std::make_pair( name, factory ) );
}
void registerListener( Ptr<IReporterFactory> const& factory ) {
m_listeners.push_back( factory );
}
virtual FactoryMap const& getFactories() const CATCH_OVERRIDE {
return m_factories;
}
virtual Listeners const& getListeners() const CATCH_OVERRIDE {
return m_listeners;
}
private:
FactoryMap m_factories;
Listeners m_listeners;
};
}
#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
#ifdef __OBJC__
#import "Foundation/Foundation.h"
#endif
namespace Catch {
class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
public:
~ExceptionTranslatorRegistry() {
deleteAll( m_translators );
}
virtual void registerTranslator( const IExceptionTranslator* translator ) {
m_translators.push_back( translator );
}
virtual std::string translateActiveException() const {
try {
#ifdef __OBJC__
@try {
return tryTranslators();
}
@catch (NSException *exception) {
return Catch::toString( [exception description] );
}
#else
return tryTranslators();
#endif
}
catch( TestFailureException& ) {
throw;
}
catch( std::exception& ex ) {
return ex.what();
}
catch( std::string& msg ) {
return msg;
}
catch( const char* msg ) {
return msg;
}
catch(...) {
return "Unknown exception";
}
}
std::string tryTranslators() const {
if( m_translators.empty() )
throw;
else
return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
}
private:
std::vector<const IExceptionTranslator*> m_translators;
};
}
namespace Catch {
namespace {
class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
RegistryHub( RegistryHub const& );
void operator=( RegistryHub const& );
public:
RegistryHub() {
}
virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE {
return m_reporterRegistry;
}
virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE {
return m_testCaseRegistry;
}
virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE {
return m_exceptionTranslatorRegistry;
}
public:
virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
m_reporterRegistry.registerReporter( name, factory );
}
virtual void registerListener( Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
m_reporterRegistry.registerListener( factory );
}
virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE {
m_testCaseRegistry.registerTest( testInfo );
}
virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE {
m_exceptionTranslatorRegistry.registerTranslator( translator );
}
private:
TestRegistry m_testCaseRegistry;
ReporterRegistry m_reporterRegistry;
ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
};
inline RegistryHub*& getTheRegistryHub() {
static RegistryHub* theRegistryHub = CATCH_NULL;
if( !theRegistryHub )
theRegistryHub = new RegistryHub();
return theRegistryHub;
}
}
IRegistryHub& getRegistryHub() {
return *getTheRegistryHub();
}
IMutableRegistryHub& getMutableRegistryHub() {
return *getTheRegistryHub();
}
void cleanUp() {
delete getTheRegistryHub();
getTheRegistryHub() = CATCH_NULL;
cleanUpContext();
}
std::string translateActiveException() {
return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
}
}
#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
#include <ostream>
namespace Catch {
NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
: m_lineInfo( lineInfo ) {
std::ostringstream oss;
oss << lineInfo << ": function ";
oss << "not implemented";
m_what = oss.str();
}
const char* NotImplementedException::what() const CATCH_NOEXCEPT {
return m_what.c_str();
}
}
#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
#include <stdexcept>
#include <cstdio>
#include <iostream>
namespace Catch {
template<typename WriterF, size_t bufferSize=256>
class StreamBufImpl : public StreamBufBase {
char data[bufferSize];
WriterF m_writer;
public:
StreamBufImpl() {
setp( data, data + sizeof(data) );
}
~StreamBufImpl() CATCH_NOEXCEPT {
sync();
}
private:
int overflow( int c ) {
sync();
if( c != EOF ) {
if( pbase() == epptr() )
m_writer( std::string( 1, static_cast<char>( c ) ) );
else
sputc( static_cast<char>( c ) );
}
return 0;
}
int sync() {
if( pbase() != pptr() ) {
m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
setp( pbase(), epptr() );
}
return 0;
}
};
FileStream::FileStream( std::string const& filename ) {
m_ofs.open( filename.c_str() );
if( m_ofs.fail() ) {
std::ostringstream oss;
oss << "Unable to open file: '" << filename << "'";
throw std::domain_error( oss.str() );
}
}
std::ostream& FileStream::stream() const {
return m_ofs;
}
struct OutputDebugWriter {
void operator()( std::string const&str ) {
writeToDebugConsole( str );
}
};
DebugOutStream::DebugOutStream()
: m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
m_os( m_streamBuf.get() )
{}
std::ostream& DebugOutStream::stream() const {
return m_os;
}
CoutStream::CoutStream()
: m_os( Catch::cout().rdbuf() )
{}
std::ostream& CoutStream::stream() const {
return m_os;
}
#ifndef CATCH_CONFIG_NOSTDOUT
std::ostream& cout() {
return std::cout;
}
std::ostream& cerr() {
return std::cerr;
}
#endif
}
namespace Catch {
class Context : public IMutableContext {
Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}
Context( Context const& );
void operator=( Context const& );
public:
virtual IResultCapture* getResultCapture() {
return m_resultCapture;
}
virtual IRunner* getRunner() {
return m_runner;
}
virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
return getGeneratorsForCurrentTest()
.getGeneratorInfo( fileInfo, totalSize )
.getCurrentIndex();
}
virtual bool advanceGeneratorsForCurrentTest() {
IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
return generators && generators->moveNext();
}
virtual Ptr<IConfig const> getConfig() const {
return m_config;
}
public:
virtual void setResultCapture( IResultCapture* resultCapture ) {
m_resultCapture = resultCapture;
}
virtual void setRunner( IRunner* runner ) {
m_runner = runner;
}
virtual void setConfig( Ptr<IConfig const> const& config ) {
m_config = config;
}
friend IMutableContext& getCurrentMutableContext();
private:
IGeneratorsForTest* findGeneratorsForCurrentTest() {
std::string testName = getResultCapture()->getCurrentTestName();
std::map<std::string, IGeneratorsForTest*>::const_iterator it =
m_generatorsByTestName.find( testName );
return it != m_generatorsByTestName.end()
? it->second
: CATCH_NULL;
}
IGeneratorsForTest& getGeneratorsForCurrentTest() {
IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
if( !generators ) {
std::string testName = getResultCapture()->getCurrentTestName();
generators = createGeneratorsForTest();
m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
}
return *generators;
}
private:
Ptr<IConfig const> m_config;
IRunner* m_runner;
IResultCapture* m_resultCapture;
std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
};
namespace {
Context* currentContext = CATCH_NULL;
}
IMutableContext& getCurrentMutableContext() {
if( !currentContext )
currentContext = new Context();
return *currentContext;
}
IContext& getCurrentContext() {
return getCurrentMutableContext();
}
void cleanUpContext() {
delete currentContext;
currentContext = CATCH_NULL;
}
}
#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
namespace Catch {
namespace {
struct IColourImpl {
virtual ~IColourImpl() {}
virtual void use( Colour::Code _colourCode ) = 0;
};
struct NoColourImpl : IColourImpl {
void use( Colour::Code ) {}
static IColourImpl* instance() {
static NoColourImpl s_instance;
return &s_instance;
}
};
}
}
#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
# ifdef CATCH_PLATFORM_WINDOWS
# define CATCH_CONFIG_COLOUR_WINDOWS
# else
# define CATCH_CONFIG_COLOUR_ANSI
# endif
#endif
#if defined ( CATCH_CONFIG_COLOUR_WINDOWS )
#ifndef NOMINMAX
#define NOMINMAX
#endif
#ifdef __AFXDLL
#include <AfxWin.h>
#else
#include <windows.h>
#endif
namespace Catch {
namespace {
class Win32ColourImpl : public IColourImpl {
public:
Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
{
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
}
virtual void use( Colour::Code _colourCode ) {
switch( _colourCode ) {
case Colour::None: return setTextAttribute( originalForegroundAttributes );
case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
case Colour::Red: return setTextAttribute( FOREGROUND_RED );
case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
case Colour::Grey: return setTextAttribute( 0 );
case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
case Colour::Bright: throw std::logic_error( "not a colour" );
}
}
private:
void setTextAttribute( WORD _textAttribute ) {
SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
}
HANDLE stdoutHandle;
WORD originalForegroundAttributes;
WORD originalBackgroundAttributes;
};
IColourImpl* platformColourInstance() {
static Win32ColourImpl s_instance;
return &s_instance;
}
}
}
#elif defined( CATCH_CONFIG_COLOUR_ANSI )
#include <unistd.h>
namespace Catch {
namespace {
class PosixColourImpl : public IColourImpl {
public:
virtual void use( Colour::Code _colourCode ) {
switch( _colourCode ) {
case Colour::None:
case Colour::White: return setColour( "[0m" );
case Colour::Red: return setColour( "[0;31m" );
case Colour::Green: return setColour( "[0;32m" );
case Colour::Blue: return setColour( "[0:34m" );
case Colour::Cyan: return setColour( "[0;36m" );
case Colour::Yellow: return setColour( "[0;33m" );
case Colour::Grey: return setColour( "[1;30m" );
case Colour::LightGrey: return setColour( "[0;37m" );
case Colour::BrightRed: return setColour( "[1;31m" );
case Colour::BrightGreen: return setColour( "[1;32m" );
case Colour::BrightWhite: return setColour( "[1;37m" );
case Colour::Bright: throw std::logic_error( "not a colour" );
}
}
static IColourImpl* instance() {
static PosixColourImpl s_instance;
return &s_instance;
}
private:
void setColour( const char* _escapeCode ) {
Catch::cout() << '\033' << _escapeCode;
}
};
IColourImpl* platformColourInstance() {
Ptr<IConfig const> config = getCurrentContext().getConfig();
return (config && config->forceColour()) || isatty(STDOUT_FILENO)
? PosixColourImpl::instance()
: NoColourImpl::instance();
}
}
}
#else
namespace Catch {
static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
}
#endif
namespace Catch {
Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
Colour::~Colour(){ if( !m_moved ) use( None ); }
void Colour::use( Code _colourCode ) {
static IColourImpl* impl = isDebuggerActive()
? NoColourImpl::instance()
: platformColourInstance();
impl->use( _colourCode );
}
}
#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
#include <vector>
#include <string>
#include <map>
namespace Catch {
struct GeneratorInfo : IGeneratorInfo {
GeneratorInfo( std::size_t size )
: m_size( size ),
m_currentIndex( 0 )
{}
bool moveNext() {
if( ++m_currentIndex == m_size ) {
m_currentIndex = 0;
return false;
}
return true;
}
std::size_t getCurrentIndex() const {
return m_currentIndex;
}
std::size_t m_size;
std::size_t m_currentIndex;
};
class GeneratorsForTest : public IGeneratorsForTest {
public:
~GeneratorsForTest() {
deleteAll( m_generatorsInOrder );
}
IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
if( it == m_generatorsByName.end() ) {
IGeneratorInfo* info = new GeneratorInfo( size );
m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
m_generatorsInOrder.push_back( info );
return *info;
}
return *it->second;
}
bool moveNext() {
std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
for(; it != itEnd; ++it ) {
if( (*it)->moveNext() )
return true;
}
return false;
}
private:
std::map<std::string, IGeneratorInfo*> m_generatorsByName;
std::vector<IGeneratorInfo*> m_generatorsInOrder;
};
IGeneratorsForTest* createGeneratorsForTest()
{
return new GeneratorsForTest();
}
}
#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
namespace Catch {
AssertionInfo::AssertionInfo( std::string const& _macroName,
SourceLineInfo const& _lineInfo,
std::string const& _capturedExpression,
ResultDisposition::Flags _resultDisposition )
: macroName( _macroName ),
lineInfo( _lineInfo ),
capturedExpression( _capturedExpression ),
resultDisposition( _resultDisposition )
{}
AssertionResult::AssertionResult() {}
AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
: m_info( info ),
m_resultData( data )
{}
AssertionResult::~AssertionResult() {}
bool AssertionResult::succeeded() const {
return Catch::isOk( m_resultData.resultType );
}
bool AssertionResult::isOk() const {
return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
}
ResultWas::OfType AssertionResult::getResultType() const {
return m_resultData.resultType;
}
bool AssertionResult::hasExpression() const {
return !m_info.capturedExpression.empty();
}
bool AssertionResult::hasMessage() const {
return !m_resultData.message.empty();
}
std::string AssertionResult::getExpression() const {
if( isFalseTest( m_info.resultDisposition ) )
return "!" + m_info.capturedExpression;
else
return m_info.capturedExpression;
}
std::string AssertionResult::getExpressionInMacro() const {
if( m_info.macroName.empty() )
return m_info.capturedExpression;
else
return m_info.macroName + "( " + m_info.capturedExpression + " )";
}
bool AssertionResult::hasExpandedExpression() const {
return hasExpression() && getExpandedExpression() != getExpression();
}
std::string AssertionResult::getExpandedExpression() const {
return m_resultData.reconstructedExpression;
}
std::string AssertionResult::getMessage() const {
return m_resultData.message;
}
SourceLineInfo AssertionResult::getSourceInfo() const {
return m_info.lineInfo;
}
std::string AssertionResult::getTestMacroName() const {
return m_info.macroName;
}
}
#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
namespace Catch {
inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
if( startsWith( tag, "." ) ||
tag == "hide" ||
tag == "!hide" )
return TestCaseInfo::IsHidden;
else if( tag == "!throws" )
return TestCaseInfo::Throws;
else if( tag == "!shouldfail" )
return TestCaseInfo::ShouldFail;
else if( tag == "!mayfail" )
return TestCaseInfo::MayFail;
else
return TestCaseInfo::None;
}
inline bool isReservedTag( std::string const& tag ) {
return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
}
inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
if( isReservedTag( tag ) ) {
{
Colour colourGuard( Colour::Red );
Catch::cerr()
<< "Tag name [" << tag << "] not allowed.\n"
<< "Tag names starting with non alpha-numeric characters are reserved\n";
}
{
Colour colourGuard( Colour::FileName );
Catch::cerr() << _lineInfo << std::endl;
}
exit(1);
}
}
TestCase makeTestCase( ITestCase* _testCase,
std::string const& _className,
std::string const& _name,
std::string const& _descOrTags,
SourceLineInfo const& _lineInfo )
{
bool isHidden( startsWith( _name, "./" ) );
std::set<std::string> tags;
std::string desc, tag;
bool inTag = false;
for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
char c = _descOrTags[i];
if( !inTag ) {
if( c == '[' )
inTag = true;
else
desc += c;
}
else {
if( c == ']' ) {
TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
if( prop == TestCaseInfo::IsHidden )
isHidden = true;
else if( prop == TestCaseInfo::None )
enforceNotReservedTag( tag, _lineInfo );
tags.insert( tag );
tag.clear();
inTag = false;
}
else
tag += c;
}
}
if( isHidden ) {
tags.insert( "hide" );
tags.insert( "." );
}
TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
return TestCase( _testCase, info );
}
void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags )
{
testCaseInfo.tags = tags;
testCaseInfo.lcaseTags.clear();
std::ostringstream oss;
for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
oss << "[" << *it << "]";
std::string lcaseTag = toLower( *it );
testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
testCaseInfo.lcaseTags.insert( lcaseTag );
}
testCaseInfo.tagsAsString = oss.str();
}
TestCaseInfo::TestCaseInfo( std::string const& _name,
std::string const& _className,
std::string const& _description,
std::set<std::string> const& _tags,
SourceLineInfo const& _lineInfo )
: name( _name ),
className( _className ),
description( _description ),
lineInfo( _lineInfo ),
properties( None )
{
setTags( *this, _tags );
}
TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
: name( other.name ),
className( other.className ),
description( other.description ),
tags( other.tags ),
lcaseTags( other.lcaseTags ),
tagsAsString( other.tagsAsString ),
lineInfo( other.lineInfo ),
properties( other.properties )
{}
bool TestCaseInfo::isHidden() const {
return ( properties & IsHidden ) != 0;
}
bool TestCaseInfo::throws() const {
return ( properties & Throws ) != 0;
}
bool TestCaseInfo::okToFail() const {
return ( properties & (ShouldFail | MayFail ) ) != 0;
}
bool TestCaseInfo::expectedToFail() const {
return ( properties & (ShouldFail ) ) != 0;
}
TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
TestCase::TestCase( TestCase const& other )
: TestCaseInfo( other ),
test( other.test )
{}
TestCase TestCase::withName( std::string const& _newName ) const {
TestCase other( *this );
other.name = _newName;
return other;
}
void TestCase::swap( TestCase& other ) {
test.swap( other.test );
name.swap( other.name );
className.swap( other.className );
description.swap( other.description );
tags.swap( other.tags );
lcaseTags.swap( other.lcaseTags );
tagsAsString.swap( other.tagsAsString );
std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
std::swap( lineInfo, other.lineInfo );
}
void TestCase::invoke() const {
test->invoke();
}
bool TestCase::operator == ( TestCase const& other ) const {
return test.get() == other.test.get() &&
name == other.name &&
className == other.className;
}
bool TestCase::operator < ( TestCase const& other ) const {
return name < other.name;
}
TestCase& TestCase::operator = ( TestCase const& other ) {
TestCase temp( other );
swap( temp );
return *this;
}
TestCaseInfo const& TestCase::getTestCaseInfo() const
{
return *this;
}
}
#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
namespace Catch {
Version::Version
( unsigned int _majorVersion,
unsigned int _minorVersion,
unsigned int _patchNumber,
std::string const& _branchName,
unsigned int _buildNumber )
: majorVersion( _majorVersion ),
minorVersion( _minorVersion ),
patchNumber( _patchNumber ),
branchName( _branchName ),
buildNumber( _buildNumber )
{}
std::ostream& operator << ( std::ostream& os, Version const& version ) {
os << version.majorVersion << "."
<< version.minorVersion << "."
<< version.patchNumber;
if( !version.branchName.empty() ) {
os << "-" << version.branchName
<< "." << version.buildNumber;
}
return os;
}
Version libraryVersion( 1, 3, 4, "", 0 );
}
#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
namespace Catch {
MessageInfo::MessageInfo( std::string const& _macroName,
SourceLineInfo const& _lineInfo,
ResultWas::OfType _type )
: macroName( _macroName ),
lineInfo( _lineInfo ),
type( _type ),
sequence( ++globalCount )
{}
unsigned int MessageInfo::globalCount = 0;
ScopedMessage::ScopedMessage( MessageBuilder const& builder )
: m_info( builder.m_info )
{
m_info.message = builder.m_stream.str();
getResultCapture().pushScopedMessage( m_info );
}
ScopedMessage::ScopedMessage( ScopedMessage const& other )
: m_info( other.m_info )
{}
ScopedMessage::~ScopedMessage() {
getResultCapture().popScopedMessage( m_info );
}
}
#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
namespace Catch
{
struct IReporter : IShared {
virtual ~IReporter();
virtual bool shouldRedirectStdout() const = 0;
virtual void StartTesting() = 0;
virtual void EndTesting( Totals const& totals ) = 0;
virtual void StartGroup( std::string const& groupName ) = 0;
virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
virtual void Aborted() = 0;
virtual void Result( AssertionResult const& result ) = 0;
};
class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
{
public:
LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
virtual ~LegacyReporterAdapter();
virtual ReporterPreferences getPreferences() const;
virtual void noMatchingTestCases( std::string const& );
virtual void testRunStarting( TestRunInfo const& );
virtual void testGroupStarting( GroupInfo const& groupInfo );
virtual void testCaseStarting( TestCaseInfo const& testInfo );
virtual void sectionStarting( SectionInfo const& sectionInfo );
virtual void assertionStarting( AssertionInfo const& );
virtual bool assertionEnded( AssertionStats const& assertionStats );
virtual void sectionEnded( SectionStats const& sectionStats );
virtual void testCaseEnded( TestCaseStats const& testCaseStats );
virtual void testGroupEnded( TestGroupStats const& testGroupStats );
virtual void testRunEnded( TestRunStats const& testRunStats );
virtual void skipTest( TestCaseInfo const& );
private:
Ptr<IReporter> m_legacyReporter;
};
}
namespace Catch
{
LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
: m_legacyReporter( legacyReporter )
{}
LegacyReporterAdapter::~LegacyReporterAdapter() {}
ReporterPreferences LegacyReporterAdapter::getPreferences() const {
ReporterPreferences prefs;
prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
return prefs;
}
void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
m_legacyReporter->StartTesting();
}
void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
m_legacyReporter->StartGroup( groupInfo.name );
}
void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
m_legacyReporter->StartTestCase( testInfo );
}
void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
}
void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
}
bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
it != itEnd;
++it ) {
if( it->type == ResultWas::Info ) {
ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
rb << it->message;
rb.setResultType( ResultWas::Info );
AssertionResult result = rb.build();
m_legacyReporter->Result( result );
}
}
}
m_legacyReporter->Result( assertionStats.assertionResult );
return true;
}
void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
if( sectionStats.missingAssertions )
m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
}
void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
m_legacyReporter->EndTestCase
( testCaseStats.testInfo,
testCaseStats.totals,
testCaseStats.stdOut,
testCaseStats.stdErr );
}
void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
if( testGroupStats.aborting )
m_legacyReporter->Aborted();
m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
}
void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
m_legacyReporter->EndTesting( testRunStats.totals );
}
void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
}
}
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wc++11-long-long"
#endif
#ifdef CATCH_PLATFORM_WINDOWS
#include <windows.h>
#else
#include <sys/time.h>
#endif
namespace Catch {
namespace {
#ifdef CATCH_PLATFORM_WINDOWS
uint64_t getCurrentTicks() {
static uint64_t hz=0, hzo=0;
if (!hz) {
QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
}
uint64_t t;
QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
return ((t-hzo)*1000000)/hz;
}
#else
uint64_t getCurrentTicks() {
timeval t;
gettimeofday(&t,CATCH_NULL);
return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
}
#endif
}
void Timer::start() {
m_ticks = getCurrentTicks();
}
unsigned int Timer::getElapsedMicroseconds() const {
return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
}
unsigned int Timer::getElapsedMilliseconds() const {
return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
}
double Timer::getElapsedSeconds() const {
return getElapsedMicroseconds()/1000000.0;
}
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
namespace Catch {
bool startsWith( std::string const& s, std::string const& prefix ) {
return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
}
bool endsWith( std::string const& s, std::string const& suffix ) {
return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
}
bool contains( std::string const& s, std::string const& infix ) {
return s.find( infix ) != std::string::npos;
}
void toLowerInPlace( std::string& s ) {
std::transform( s.begin(), s.end(), s.begin(), ::tolower );
}
std::string toLower( std::string const& s ) {
std::string lc = s;
toLowerInPlace( lc );
return lc;
}
std::string trim( std::string const& str ) {
static char const* whitespaceChars = "\n\r\t ";
std::string::size_type start = str.find_first_not_of( whitespaceChars );
std::string::size_type end = str.find_last_not_of( whitespaceChars );
return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
}
bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
bool replaced = false;
std::size_t i = str.find( replaceThis );
while( i != std::string::npos ) {
replaced = true;
str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
if( i < str.size()-withThis.size() )
i = str.find( replaceThis, i+withThis.size() );
else
i = std::string::npos;
}
return replaced;
}
pluralise::pluralise( std::size_t count, std::string const& label )
: m_count( count ),
m_label( label )
{}
std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
os << pluraliser.m_count << " " << pluraliser.m_label;
if( pluraliser.m_count != 1 )
os << "s";
return os;
}
SourceLineInfo::SourceLineInfo() : line( 0 ){}
SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
: file( _file ),
line( _line )
{}
SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
: file( other.file ),
line( other.line )
{}
bool SourceLineInfo::empty() const {
return file.empty();
}
bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
return line == other.line && file == other.file;
}
bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
return line < other.line || ( line == other.line && file < other.file );
}
void seedRng( IConfig const& config ) {
if( config.rngSeed() != 0 )
std::srand( config.rngSeed() );
}
unsigned int rngSeed() {
return getCurrentContext().getConfig()->rngSeed();
}
std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
#ifndef __GNUG__
os << info.file << "(" << info.line << ")";
#else
os << info.file << ":" << info.line;
#endif
return os;
}
void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
std::ostringstream oss;
oss << locationInfo << ": Internal Catch error: '" << message << "'";
if( alwaysTrue() )
throw std::logic_error( oss.str() );
}
}
#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
namespace Catch {
SectionInfo::SectionInfo
( SourceLineInfo const& _lineInfo,
std::string const& _name,
std::string const& _description )
: name( _name ),
description( _description ),
lineInfo( _lineInfo )
{}
Section::Section( SectionInfo const& info )
: m_info( info ),
m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
{
m_timer.start();
}
Section::~Section() {
if( m_sectionIncluded ) {
SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
if( std::uncaught_exception() )
getResultCapture().sectionEndedEarly( endInfo );
else
getResultCapture().sectionEnded( endInfo );
}
}
Section::operator bool() const {
return m_sectionIncluded;
}
}
#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
#include <iostream>
#ifdef CATCH_PLATFORM_MAC
#include <assert.h>
#include <stdbool.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sysctl.h>
namespace Catch{
bool isDebuggerActive(){
int mib[4];
struct kinfo_proc info;
size_t size;
info.kp_proc.p_flag = 0;
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PID;
mib[3] = getpid();
size = sizeof(info);
if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) {
Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
return false;
}
return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
}
}
#elif defined(_MSC_VER)
extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
namespace Catch {
bool isDebuggerActive() {
return IsDebuggerPresent() != 0;
}
}
#elif defined(__MINGW32__)
extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
namespace Catch {
bool isDebuggerActive() {
return IsDebuggerPresent() != 0;
}
}
#else
namespace Catch {
inline bool isDebuggerActive() { return false; }
}
#endif
#ifdef CATCH_PLATFORM_WINDOWS
extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
namespace Catch {
void writeToDebugConsole( std::string const& text ) {
::OutputDebugStringA( text.c_str() );
}
}
#else
namespace Catch {
void writeToDebugConsole( std::string const& text ) {
Catch::cout() << text;
}
}
#endif
#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
namespace Catch {
namespace Detail {
const std::string unprintableString = "{?}";
namespace {
const int hexThreshold = 255;
struct Endianness {
enum Arch { Big, Little };
static Arch which() {
union _{
int asInt;
char asChar[sizeof (int)];
} u;
u.asInt = 1;
return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
}
};
}
std::string rawMemoryToString( const void *object, std::size_t size )
{
int i = 0, end = static_cast<int>( size ), inc = 1;
if( Endianness::which() == Endianness::Little ) {
i = end-1;
end = inc = -1;
}
unsigned char const *bytes = static_cast<unsigned char const *>(object);
std::ostringstream os;
os << "0x" << std::setfill('0') << std::hex;
for( ; i != end; i += inc )
os << std::setw(2) << static_cast<unsigned>(bytes[i]);
return os.str();
}
}
std::string toString( std::string const& value ) {
std::string s = value;
if( getCurrentContext().getConfig()->showInvisibles() ) {
for(size_t i = 0; i < s.size(); ++i ) {
std::string subs;
switch( s[i] ) {
case '\n': subs = "\\n"; break;
case '\t': subs = "\\t"; break;
default: break;
}
if( !subs.empty() ) {
s = s.substr( 0, i ) + subs + s.substr( i+1 );
++i;
}
}
}
return "\"" + s + "\"";
}
std::string toString( std::wstring const& value ) {
std::string s;
s.reserve( value.size() );
for(size_t i = 0; i < value.size(); ++i )
s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
return Catch::toString( s );
}
std::string toString( const char* const value ) {
return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
}
std::string toString( char* const value ) {
return Catch::toString( static_cast<const char*>( value ) );
}
std::string toString( const wchar_t* const value )
{
return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
}
std::string toString( wchar_t* const value )
{
return Catch::toString( static_cast<const wchar_t*>( value ) );
}
std::string toString( int value ) {
std::ostringstream oss;
oss << value;
if( value > Detail::hexThreshold )
oss << " (0x" << std::hex << value << ")";
return oss.str();
}
std::string toString( unsigned long value ) {
std::ostringstream oss;
oss << value;
if( value > Detail::hexThreshold )
oss << " (0x" << std::hex << value << ")";
return oss.str();
}
std::string toString( unsigned int value ) {
return Catch::toString( static_cast<unsigned long>( value ) );
}
template<typename T>
std::string fpToString( T value, int precision ) {
std::ostringstream oss;
oss << std::setprecision( precision )
<< std::fixed
<< value;
std::string d = oss.str();
std::size_t i = d.find_last_not_of( '0' );
if( i != std::string::npos && i != d.size()-1 ) {
if( d[i] == '.' )
i++;
d = d.substr( 0, i+1 );
}
return d;
}
std::string toString( const double value ) {
return fpToString( value, 10 );
}
std::string toString( const float value ) {
return fpToString( value, 5 ) + "f";
}
std::string toString( bool value ) {
return value ? "true" : "false";
}
std::string toString( char value ) {
return value < ' '
? toString( static_cast<unsigned int>( value ) )
: Detail::makeString( value );
}
std::string toString( signed char value ) {
return toString( static_cast<char>( value ) );
}
std::string toString( unsigned char value ) {
return toString( static_cast<char>( value ) );
}
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
std::string toString( long long value ) {
std::ostringstream oss;
oss << value;
if( value > Detail::hexThreshold )
oss << " (0x" << std::hex << value << ")";
return oss.str();
}
std::string toString( unsigned long long value ) {
std::ostringstream oss;
oss << value;
if( value > Detail::hexThreshold )
oss << " (0x" << std::hex << value << ")";
return oss.str();
}
#endif
#ifdef CATCH_CONFIG_CPP11_NULLPTR
std::string toString( std::nullptr_t ) {
return "nullptr";
}
#endif
#ifdef __OBJC__
std::string toString( NSString const * const& nsstring ) {
if( !nsstring )
return "nil";
return "@" + toString([nsstring UTF8String]);
}
std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
if( !nsstring )
return "nil";
return "@" + toString([nsstring UTF8String]);
}
std::string toString( NSObject* const& nsObject ) {
return toString( [nsObject description] );
}
#endif
}
#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
namespace Catch {
std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) {
return secondArg.empty() || secondArg == "\"\""
? capturedExpression
: capturedExpression + ", " + secondArg;
}
ResultBuilder::ResultBuilder( char const* macroName,
SourceLineInfo const& lineInfo,
char const* capturedExpression,
ResultDisposition::Flags resultDisposition,
char const* secondArg )
: m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ),
m_shouldDebugBreak( false ),
m_shouldThrow( false )
{}
ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
m_data.resultType = result;
return *this;
}
ResultBuilder& ResultBuilder::setResultType( bool result ) {
m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
return *this;
}
ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {
m_exprComponents.lhs = lhs;
return *this;
}
ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {
m_exprComponents.rhs = rhs;
return *this;
}
ResultBuilder& ResultBuilder::setOp( std::string const& op ) {
m_exprComponents.op = op;
return *this;
}
void ResultBuilder::endExpression() {
m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );
captureExpression();
}
void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
m_assertionInfo.resultDisposition = resultDisposition;
m_stream.oss << Catch::translateActiveException();
captureResult( ResultWas::ThrewException );
}
void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
setResultType( resultType );
captureExpression();
}
void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {
if( expectedMessage.empty() )
captureExpectedException( Matchers::Impl::Generic::AllOf<std::string>() );
else
captureExpectedException( Matchers::Equals( expectedMessage ) );
}
void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) {
assert( m_exprComponents.testFalse == false );
AssertionResultData data = m_data;
data.resultType = ResultWas::Ok;
data.reconstructedExpression = m_assertionInfo.capturedExpression;
std::string actualMessage = Catch::translateActiveException();
if( !matcher.match( actualMessage ) ) {
data.resultType = ResultWas::ExpressionFailed;
data.reconstructedExpression = actualMessage;
}
AssertionResult result( m_assertionInfo, data );
handleResult( result );
}
void ResultBuilder::captureExpression() {
AssertionResult result = build();
handleResult( result );
}
void ResultBuilder::handleResult( AssertionResult const& result )
{
getResultCapture().assertionEnded( result );
if( !result.isOk() ) {
if( getCurrentContext().getConfig()->shouldDebugBreak() )
m_shouldDebugBreak = true;
if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
m_shouldThrow = true;
}
}
void ResultBuilder::react() {
if( m_shouldThrow )
throw Catch::TestFailureException();
}
bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
AssertionResult ResultBuilder::build() const
{
assert( m_data.resultType != ResultWas::Unknown );
AssertionResultData data = m_data;
if( m_exprComponents.testFalse ) {
if( data.resultType == ResultWas::Ok )
data.resultType = ResultWas::ExpressionFailed;
else if( data.resultType == ResultWas::ExpressionFailed )
data.resultType = ResultWas::Ok;
}
data.message = m_stream.oss.str();
data.reconstructedExpression = reconstructExpression();
if( m_exprComponents.testFalse ) {
if( m_exprComponents.op == "" )
data.reconstructedExpression = "!" + data.reconstructedExpression;
else
data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
}
return AssertionResult( m_assertionInfo, data );
}
std::string ResultBuilder::reconstructExpression() const {
if( m_exprComponents.op == "" )
return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
else if( m_exprComponents.op == "matches" )
return m_exprComponents.lhs + " " + m_exprComponents.rhs;
else if( m_exprComponents.op != "!" ) {
if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
m_exprComponents.lhs.find("\n") == std::string::npos &&
m_exprComponents.rhs.find("\n") == std::string::npos )
return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
else
return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
}
else
return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}";
}
}
#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
#include <map>
namespace Catch {
class TagAliasRegistry : public ITagAliasRegistry {
public:
virtual ~TagAliasRegistry();
virtual Option<TagAlias> find( std::string const& alias ) const;
virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
static TagAliasRegistry& get();
private:
std::map<std::string, TagAlias> m_registry;
};
}
#include <map>
#include <iostream>
namespace Catch {
TagAliasRegistry::~TagAliasRegistry() {}
Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
if( it != m_registry.end() )
return it->second;
else
return Option<TagAlias>();
}
std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
std::string expandedTestSpec = unexpandedTestSpec;
for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
it != itEnd;
++it ) {
std::size_t pos = expandedTestSpec.find( it->first );
if( pos != std::string::npos ) {
expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
it->second.tag +
expandedTestSpec.substr( pos + it->first.size() );
}
}
return expandedTestSpec;
}
void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) {
std::ostringstream oss;
oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
throw std::domain_error( oss.str().c_str() );
}
if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
std::ostringstream oss;
oss << "error: tag alias, \"" << alias << "\" already registered.\n"
<< "\tFirst seen at " << find(alias)->lineInfo << "\n"
<< "\tRedefined at " << lineInfo;
throw std::domain_error( oss.str().c_str() );
}
}
TagAliasRegistry& TagAliasRegistry::get() {
static TagAliasRegistry instance;
return instance;
}
ITagAliasRegistry::~ITagAliasRegistry() {}
ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
try {
TagAliasRegistry::get().add( alias, tag, lineInfo );
}
catch( std::exception& ex ) {
Colour colourGuard( Colour::Red );
Catch::cerr() << ex.what() << std::endl;
exit(1);
}
}
}
#define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
namespace Catch {
class MultipleReporters : public SharedImpl<IStreamingReporter> {
typedef std::vector<Ptr<IStreamingReporter> > Reporters;
Reporters m_reporters;
public:
void add( Ptr<IStreamingReporter> const& reporter ) {
m_reporters.push_back( reporter );
}
public:
virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
return m_reporters[0]->getPreferences();
}
virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->noMatchingTestCases( spec );
}
virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->testRunStarting( testRunInfo );
}
virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->testGroupStarting( groupInfo );
}
virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->testCaseStarting( testInfo );
}
virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->sectionStarting( sectionInfo );
}
virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->assertionStarting( assertionInfo );
}
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
bool clearBuffer = false;
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
clearBuffer |= (*it)->assertionEnded( assertionStats );
return clearBuffer;
}
virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->sectionEnded( sectionStats );
}
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->testCaseEnded( testCaseStats );
}
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->testGroupEnded( testGroupStats );
}
virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->testRunEnded( testRunStats );
}
virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->skipTest( testInfo );
}
};
Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
Ptr<IStreamingReporter> resultingReporter;
if( existingReporter ) {
MultipleReporters* multi = dynamic_cast<MultipleReporters*>( existingReporter.get() );
if( !multi ) {
multi = new MultipleReporters;
resultingReporter = Ptr<IStreamingReporter>( multi );
if( existingReporter )
multi->add( existingReporter );
}
else
resultingReporter = existingReporter;
multi->add( additionalReporter );
}
else
resultingReporter = additionalReporter;
return resultingReporter;
}
}
#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
#include <cstring>
namespace Catch {
struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
StreamingReporterBase( ReporterConfig const& _config )
: m_config( _config.fullConfig() ),
stream( _config.stream() )
{
m_reporterPrefs.shouldRedirectStdOut = false;
}
virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
return m_reporterPrefs;
}
virtual ~StreamingReporterBase() CATCH_OVERRIDE;
virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {}
virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE {
currentTestRunInfo = _testRunInfo;
}
virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE {
currentGroupInfo = _groupInfo;
}
virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE {
currentTestCaseInfo = _testInfo;
}
virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
m_sectionStack.push_back( _sectionInfo );
}
virtual void sectionEnded( SectionStats const& ) CATCH_OVERRIDE {
m_sectionStack.pop_back();
}
virtual void testCaseEnded( TestCaseStats const& ) CATCH_OVERRIDE {
currentTestCaseInfo.reset();
}
virtual void testGroupEnded( TestGroupStats const& ) CATCH_OVERRIDE {
currentGroupInfo.reset();
}
virtual void testRunEnded( TestRunStats const& ) CATCH_OVERRIDE {
currentTestCaseInfo.reset();
currentGroupInfo.reset();
currentTestRunInfo.reset();
}
virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {
}
Ptr<IConfig const> m_config;
std::ostream& stream;
LazyStat<TestRunInfo> currentTestRunInfo;
LazyStat<GroupInfo> currentGroupInfo;
LazyStat<TestCaseInfo> currentTestCaseInfo;
std::vector<SectionInfo> m_sectionStack;
ReporterPreferences m_reporterPrefs;
};
struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
template<typename T, typename ChildNodeT>
struct Node : SharedImpl<> {
explicit Node( T const& _value ) : value( _value ) {}
virtual ~Node() {}
typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
T value;
ChildNodes children;
};
struct SectionNode : SharedImpl<> {
explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
virtual ~SectionNode();
bool operator == ( SectionNode const& other ) const {
return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
}
bool operator == ( Ptr<SectionNode> const& other ) const {
return operator==( *other );
}
SectionStats stats;
typedef std::vector<Ptr<SectionNode> > ChildSections;
typedef std::vector<AssertionStats> Assertions;
ChildSections childSections;
Assertions assertions;
std::string stdOut;
std::string stdErr;
};
struct BySectionInfo {
BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
bool operator() ( Ptr<SectionNode> const& node ) const {
return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
}
private:
void operator=( BySectionInfo const& );
SectionInfo const& m_other;
};
typedef Node<TestCaseStats, SectionNode> TestCaseNode;
typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
typedef Node<TestRunStats, TestGroupNode> TestRunNode;
CumulativeReporterBase( ReporterConfig const& _config )
: m_config( _config.fullConfig() ),
stream( _config.stream() )
{
m_reporterPrefs.shouldRedirectStdOut = false;
}
~CumulativeReporterBase();
virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
return m_reporterPrefs;
}
virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {}
virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {}
virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {}
virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
Ptr<SectionNode> node;
if( m_sectionStack.empty() ) {
if( !m_rootSection )
m_rootSection = new SectionNode( incompleteStats );
node = m_rootSection;
}
else {
SectionNode& parentNode = *m_sectionStack.back();
SectionNode::ChildSections::const_iterator it =
std::find_if( parentNode.childSections.begin(),
parentNode.childSections.end(),
BySectionInfo( sectionInfo ) );
if( it == parentNode.childSections.end() ) {
node = new SectionNode( incompleteStats );
parentNode.childSections.push_back( node );
}
else
node = *it;
}
m_sectionStack.push_back( node );
m_deepestSection = node;
}
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
virtual bool assertionEnded( AssertionStats const& assertionStats ) {
assert( !m_sectionStack.empty() );
SectionNode& sectionNode = *m_sectionStack.back();
sectionNode.assertions.push_back( assertionStats );
return true;
}
virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
assert( !m_sectionStack.empty() );
SectionNode& node = *m_sectionStack.back();
node.stats = sectionStats;
m_sectionStack.pop_back();
}
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
assert( m_sectionStack.size() == 0 );
node->children.push_back( m_rootSection );
m_testCases.push_back( node );
m_rootSection.reset();
assert( m_deepestSection );
m_deepestSection->stdOut = testCaseStats.stdOut;
m_deepestSection->stdErr = testCaseStats.stdErr;
}
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
node->children.swap( m_testCases );
m_testGroups.push_back( node );
}
virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
Ptr<TestRunNode> node = new TestRunNode( testRunStats );
node->children.swap( m_testGroups );
m_testRuns.push_back( node );
testRunEndedCumulative();
}
virtual void testRunEndedCumulative() = 0;
virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
Ptr<IConfig const> m_config;
std::ostream& stream;
std::vector<AssertionStats> m_assertions;
std::vector<std::vector<Ptr<SectionNode> > > m_sections;
std::vector<Ptr<TestCaseNode> > m_testCases;
std::vector<Ptr<TestGroupNode> > m_testGroups;
std::vector<Ptr<TestRunNode> > m_testRuns;
Ptr<SectionNode> m_rootSection;
Ptr<SectionNode> m_deepestSection;
std::vector<Ptr<SectionNode> > m_sectionStack;
ReporterPreferences m_reporterPrefs;
};
template<char C>
char const* getLineOfChars() {
static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
if( !*line ) {
memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
}
return line;
}
struct TestEventListenerBase : StreamingReporterBase {
TestEventListenerBase( ReporterConfig const& _config )
: StreamingReporterBase( _config )
{}
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE {
return false;
}
};
}
#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
namespace Catch {
template<typename T>
class LegacyReporterRegistrar {
class ReporterFactory : public IReporterFactory {
virtual IStreamingReporter* create( ReporterConfig const& config ) const {
return new LegacyReporterAdapter( new T( config ) );
}
virtual std::string getDescription() const {
return T::getDescription();
}
};
public:
LegacyReporterRegistrar( std::string const& name ) {
getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
}
};
template<typename T>
class ReporterRegistrar {
class ReporterFactory : public SharedImpl<IReporterFactory> {
virtual IStreamingReporter* create( ReporterConfig const& config ) const {
return new T( config );
}
virtual std::string getDescription() const {
return T::getDescription();
}
};
public:
ReporterRegistrar( std::string const& name ) {
getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
}
};
template<typename T>
class ListenerRegistrar {
class ListenerFactory : public SharedImpl<IReporterFactory> {
virtual IStreamingReporter* create( ReporterConfig const& config ) const {
return new T( config );
}
virtual std::string getDescription() const {
return "";
}
};
public:
ListenerRegistrar() {
getMutableRegistryHub().registerListener( new ListenerFactory() );
}
};
}
#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \
namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
#include <sstream>
#include <string>
#include <vector>
#include <iomanip>
namespace Catch {
class XmlEncode {
public:
enum ForWhat { ForTextNodes, ForAttributes };
XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes )
: m_str( str ),
m_forWhat( forWhat )
{}
void encodeTo( std::ostream& os ) const {
for( std::size_t i = 0; i < m_str.size(); ++ i ) {
char c = m_str[i];
switch( c ) {
case '<': os << "&lt;"; break;
case '&': os << "&amp;"; break;
case '>':
if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
os << "&gt;";
else
os << c;
break;
case '\"':
if( m_forWhat == ForAttributes )
os << "&quot;";
else
os << c;
break;
default:
if ( ( c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' )
os << "&#x" << std::uppercase << std::hex << static_cast<int>( c );
else
os << c;
}
}
}
friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
xmlEncode.encodeTo( os );
return os;
}
private:
std::string m_str;
ForWhat m_forWhat;
};
class XmlWriter {
public:
class ScopedElement {
public:
ScopedElement( XmlWriter* writer )
: m_writer( writer )
{}
ScopedElement( ScopedElement const& other )
: m_writer( other.m_writer ){
other.m_writer = CATCH_NULL;
}
~ScopedElement() {
if( m_writer )
m_writer->endElement();
}
ScopedElement& writeText( std::string const& text, bool indent = true ) {
m_writer->writeText( text, indent );
return *this;
}
template<typename T>
ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
m_writer->writeAttribute( name, attribute );
return *this;
}
private:
mutable XmlWriter* m_writer;
};
XmlWriter()
: m_tagIsOpen( false ),
m_needsNewline( false ),
m_os( &Catch::cout() )
{}
XmlWriter( std::ostream& os )
: m_tagIsOpen( false ),
m_needsNewline( false ),
m_os( &os )
{}
~XmlWriter() {
while( !m_tags.empty() )
endElement();
}
XmlWriter& startElement( std::string const& name ) {
ensureTagClosed();
newlineIfNecessary();
stream() << m_indent << "<" << name;
m_tags.push_back( name );
m_indent += " ";
m_tagIsOpen = true;
return *this;
}
ScopedElement scopedElement( std::string const& name ) {
ScopedElement scoped( this );
startElement( name );
return scoped;
}
XmlWriter& endElement() {
newlineIfNecessary();
m_indent = m_indent.substr( 0, m_indent.size()-2 );
if( m_tagIsOpen ) {
stream() << "/>\n";
m_tagIsOpen = false;
}
else {
stream() << m_indent << "</" << m_tags.back() << ">\n";
}
m_tags.pop_back();
return *this;
}
XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
if( !name.empty() && !attribute.empty() )
stream() << " " << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << "\"";
return *this;
}
XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
return *this;
}
template<typename T>
XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
std::ostringstream oss;
oss << attribute;
return writeAttribute( name, oss.str() );
}
XmlWriter& writeText( std::string const& text, bool indent = true ) {
if( !text.empty() ){
bool tagWasOpen = m_tagIsOpen;
ensureTagClosed();
if( tagWasOpen && indent )
stream() << m_indent;
stream() << XmlEncode( text );
m_needsNewline = true;
}
return *this;
}
XmlWriter& writeComment( std::string const& text ) {
ensureTagClosed();
stream() << m_indent << "<!--" << text << "-->";
m_needsNewline = true;
return *this;
}
XmlWriter& writeBlankLine() {
ensureTagClosed();
stream() << "\n";
return *this;
}
void setStream( std::ostream& os ) {
m_os = &os;
}
private:
XmlWriter( XmlWriter const& );
void operator=( XmlWriter const& );
std::ostream& stream() {
return *m_os;
}
void ensureTagClosed() {
if( m_tagIsOpen ) {
stream() << ">\n";
m_tagIsOpen = false;
}
}
void newlineIfNecessary() {
if( m_needsNewline ) {
stream() << "\n";
m_needsNewline = false;
}
}
bool m_tagIsOpen;
bool m_needsNewline;
std::vector<std::string> m_tags;
std::string m_indent;
std::ostream* m_os;
};
}
#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
#ifdef __clang__
# ifdef __ICC
# pragma warning(pop)
# else
# pragma clang diagnostic pop
# endif
#elif defined __GNUC__
# pragma GCC diagnostic pop
#endif
namespace Catch {
class XmlReporter : public StreamingReporterBase {
public:
XmlReporter( ReporterConfig const& _config )
: StreamingReporterBase( _config ),
m_sectionDepth( 0 )
{
m_reporterPrefs.shouldRedirectStdOut = true;
}
virtual ~XmlReporter() CATCH_OVERRIDE;
static std::string getDescription() {
return "Reports test results as an XML document";
}
public:
virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {
StreamingReporterBase::noMatchingTestCases( s );
}
virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {
StreamingReporterBase::testRunStarting( testInfo );
m_xml.setStream( stream );
m_xml.startElement( "Catch" );
if( !m_config->name().empty() )
m_xml.writeAttribute( "name", m_config->name() );
}
virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
StreamingReporterBase::testGroupStarting( groupInfo );
m_xml.startElement( "Group" )
.writeAttribute( "name", groupInfo.name );
}
virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
StreamingReporterBase::testCaseStarting(testInfo);
m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
if ( m_config->showDurations() == ShowDurations::Always )
m_testCaseTimer.start();
}
virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
StreamingReporterBase::sectionStarting( sectionInfo );
if( m_sectionDepth++ > 0 ) {
m_xml.startElement( "Section" )
.writeAttribute( "name", trim( sectionInfo.name ) )
.writeAttribute( "description", sectionInfo.description );
}
}
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
const AssertionResult& assertionResult = assertionStats.assertionResult;
if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
it != itEnd;
++it ) {
if( it->type == ResultWas::Info ) {
m_xml.scopedElement( "Info" )
.writeText( it->message );
} else if ( it->type == ResultWas::Warning ) {
m_xml.scopedElement( "Warning" )
.writeText( it->message );
}
}
}
if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
return true;
if( assertionResult.hasExpression() ) {
m_xml.startElement( "Expression" )
.writeAttribute( "success", assertionResult.succeeded() )
.writeAttribute( "type", assertionResult.getTestMacroName() )
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
.writeAttribute( "line", assertionResult.getSourceInfo().line );
m_xml.scopedElement( "Original" )
.writeText( assertionResult.getExpression() );
m_xml.scopedElement( "Expanded" )
.writeText( assertionResult.getExpandedExpression() );
}
switch( assertionResult.getResultType() ) {
case ResultWas::ThrewException:
m_xml.scopedElement( "Exception" )
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
.writeAttribute( "line", assertionResult.getSourceInfo().line )
.writeText( assertionResult.getMessage() );
break;
case ResultWas::FatalErrorCondition:
m_xml.scopedElement( "Fatal Error Condition" )
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
.writeAttribute( "line", assertionResult.getSourceInfo().line )
.writeText( assertionResult.getMessage() );
break;
case ResultWas::Info:
m_xml.scopedElement( "Info" )
.writeText( assertionResult.getMessage() );
break;
case ResultWas::Warning:
break;
case ResultWas::ExplicitFailure:
m_xml.scopedElement( "Failure" )
.writeText( assertionResult.getMessage() );
break;
default:
break;
}
if( assertionResult.hasExpression() )
m_xml.endElement();
return true;
}
virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
StreamingReporterBase::sectionEnded( sectionStats );
if( --m_sectionDepth > 0 ) {
XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
e.writeAttribute( "successes", sectionStats.assertions.passed );
e.writeAttribute( "failures", sectionStats.assertions.failed );
e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
if ( m_config->showDurations() == ShowDurations::Always )
e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
m_xml.endElement();
}
}
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
StreamingReporterBase::testCaseEnded( testCaseStats );
XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
if ( m_config->showDurations() == ShowDurations::Always )
e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
m_xml.endElement();
}
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
StreamingReporterBase::testGroupEnded( testGroupStats );
m_xml.scopedElement( "OverallResults" )
.writeAttribute( "successes", testGroupStats.totals.assertions.passed )
.writeAttribute( "failures", testGroupStats.totals.assertions.failed )
.writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
m_xml.endElement();
}
virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
StreamingReporterBase::testRunEnded( testRunStats );
m_xml.scopedElement( "OverallResults" )
.writeAttribute( "successes", testRunStats.totals.assertions.passed )
.writeAttribute( "failures", testRunStats.totals.assertions.failed )
.writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
m_xml.endElement();
}
private:
Timer m_testCaseTimer;
XmlWriter m_xml;
int m_sectionDepth;
};
INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
}
#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
#include <assert.h>
namespace Catch {
class JunitReporter : public CumulativeReporterBase {
public:
JunitReporter( ReporterConfig const& _config )
: CumulativeReporterBase( _config ),
xml( _config.stream() )
{
m_reporterPrefs.shouldRedirectStdOut = true;
}
virtual ~JunitReporter() CATCH_OVERRIDE;
static std::string getDescription() {
return "Reports test results in an XML format that looks like Ant's junitreport target";
}
virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {}
virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE {
CumulativeReporterBase::testRunStarting( runInfo );
xml.startElement( "testsuites" );
}
virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
suiteTimer.start();
stdOutForSuite.str("");
stdErrForSuite.str("");
unexpectedExceptions = 0;
CumulativeReporterBase::testGroupStarting( groupInfo );
}
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
unexpectedExceptions++;
return CumulativeReporterBase::assertionEnded( assertionStats );
}
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
stdOutForSuite << testCaseStats.stdOut;
stdErrForSuite << testCaseStats.stdErr;
CumulativeReporterBase::testCaseEnded( testCaseStats );
}
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
double suiteTime = suiteTimer.getElapsedSeconds();
CumulativeReporterBase::testGroupEnded( testGroupStats );
writeGroup( *m_testGroups.back(), suiteTime );
}
virtual void testRunEndedCumulative() CATCH_OVERRIDE {
xml.endElement();
}
void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
TestGroupStats const& stats = groupNode.value;
xml.writeAttribute( "name", stats.groupInfo.name );
xml.writeAttribute( "errors", unexpectedExceptions );
xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
xml.writeAttribute( "tests", stats.totals.assertions.total() );
xml.writeAttribute( "hostname", "tbd" );
if( m_config->showDurations() == ShowDurations::Never )
xml.writeAttribute( "time", "" );
else
xml.writeAttribute( "time", suiteTime );
xml.writeAttribute( "timestamp", "tbd" );
for( TestGroupNode::ChildNodes::const_iterator
it = groupNode.children.begin(), itEnd = groupNode.children.end();
it != itEnd;
++it )
writeTestCase( **it );
xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
}
void writeTestCase( TestCaseNode const& testCaseNode ) {
TestCaseStats const& stats = testCaseNode.value;
assert( testCaseNode.children.size() == 1 );
SectionNode const& rootSection = *testCaseNode.children.front();
std::string className = stats.testInfo.className;
if( className.empty() ) {
if( rootSection.childSections.empty() )
className = "global";
}
writeSection( className, "", rootSection );
}
void writeSection( std::string const& className,
std::string const& rootName,
SectionNode const& sectionNode ) {
std::string name = trim( sectionNode.stats.sectionInfo.name );
if( !rootName.empty() )
name = rootName + "/" + name;
if( !sectionNode.assertions.empty() ||
!sectionNode.stdOut.empty() ||
!sectionNode.stdErr.empty() ) {
XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
if( className.empty() ) {
xml.writeAttribute( "classname", name );
xml.writeAttribute( "name", "root" );
}
else {
xml.writeAttribute( "classname", className );
xml.writeAttribute( "name", name );
}
xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
writeAssertions( sectionNode );
if( !sectionNode.stdOut.empty() )
xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
if( !sectionNode.stdErr.empty() )
xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
}
for( SectionNode::ChildSections::const_iterator
it = sectionNode.childSections.begin(),
itEnd = sectionNode.childSections.end();
it != itEnd;
++it )
if( className.empty() )
writeSection( name, "", **it );
else
writeSection( className, name, **it );
}
void writeAssertions( SectionNode const& sectionNode ) {
for( SectionNode::Assertions::const_iterator
it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
it != itEnd;
++it )
writeAssertion( *it );
}
void writeAssertion( AssertionStats const& stats ) {
AssertionResult const& result = stats.assertionResult;
if( !result.isOk() ) {
std::string elementName;
switch( result.getResultType() ) {
case ResultWas::ThrewException:
case ResultWas::FatalErrorCondition:
elementName = "error";
break;
case ResultWas::ExplicitFailure:
elementName = "failure";
break;
case ResultWas::ExpressionFailed:
elementName = "failure";
break;
case ResultWas::DidntThrowException:
elementName = "failure";
break;
case ResultWas::Info:
case ResultWas::Warning:
case ResultWas::Ok:
case ResultWas::Unknown:
case ResultWas::FailureBit:
case ResultWas::Exception:
elementName = "internalError";
break;
}
XmlWriter::ScopedElement e = xml.scopedElement( elementName );
xml.writeAttribute( "message", result.getExpandedExpression() );
xml.writeAttribute( "type", result.getTestMacroName() );
std::ostringstream oss;
if( !result.getMessage().empty() )
oss << result.getMessage() << "\n";
for( std::vector<MessageInfo>::const_iterator
it = stats.infoMessages.begin(),
itEnd = stats.infoMessages.end();
it != itEnd;
++it )
if( it->type == ResultWas::Info )
oss << it->message << "\n";
oss << "at " << result.getSourceInfo();
xml.writeText( oss.str(), false );
}
}
XmlWriter xml;
Timer suiteTimer;
std::ostringstream stdOutForSuite;
std::ostringstream stdErrForSuite;
unsigned int unexpectedExceptions;
};
INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
}
#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
namespace Catch {
struct ConsoleReporter : StreamingReporterBase {
ConsoleReporter( ReporterConfig const& _config )
: StreamingReporterBase( _config ),
m_headerPrinted( false )
{}
virtual ~ConsoleReporter() CATCH_OVERRIDE;
static std::string getDescription() {
return "Reports test results as plain lines of text";
}
virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
stream << "No test cases matched '" << spec << "'" << std::endl;
}
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
}
virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
AssertionResult const& result = _assertionStats.assertionResult;
bool printInfoMessages = true;
if( !m_config->includeSuccessfulResults() && result.isOk() ) {
if( result.getResultType() != ResultWas::Warning )
return false;
printInfoMessages = false;
}
lazyPrint();
AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
printer.print();
stream << std::endl;
return true;
}
virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
m_headerPrinted = false;
StreamingReporterBase::sectionStarting( _sectionInfo );
}
virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE {
if( _sectionStats.missingAssertions ) {
lazyPrint();
Colour colour( Colour::ResultError );
if( m_sectionStack.size() > 1 )
stream << "\nNo assertions in section";
else
stream << "\nNo assertions in test case";
stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
}
if( m_headerPrinted ) {
if( m_config->showDurations() == ShowDurations::Always )
stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
m_headerPrinted = false;
}
else {
if( m_config->showDurations() == ShowDurations::Always )
stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
}
StreamingReporterBase::sectionEnded( _sectionStats );
}
virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {
StreamingReporterBase::testCaseEnded( _testCaseStats );
m_headerPrinted = false;
}
virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE {
if( currentGroupInfo.used ) {
printSummaryDivider();
stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
printTotals( _testGroupStats.totals );
stream << "\n" << std::endl;
}
StreamingReporterBase::testGroupEnded( _testGroupStats );
}
virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE {
printTotalsDivider( _testRunStats.totals );
printTotals( _testRunStats.totals );
stream << std::endl;
StreamingReporterBase::testRunEnded( _testRunStats );
}
private:
class AssertionPrinter {
void operator= ( AssertionPrinter const& );
public:
AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
: stream( _stream ),
stats( _stats ),
result( _stats.assertionResult ),
colour( Colour::None ),
message( result.getMessage() ),
messages( _stats.infoMessages ),
printInfoMessages( _printInfoMessages )
{
switch( result.getResultType() ) {
case ResultWas::Ok:
colour = Colour::Success;
passOrFail = "PASSED";
if( _stats.infoMessages.size() == 1 )
messageLabel = "with message";
if( _stats.infoMessages.size() > 1 )
messageLabel = "with messages";
break;
case ResultWas::ExpressionFailed:
if( result.isOk() ) {
colour = Colour::Success;
passOrFail = "FAILED - but was ok";
}
else {
colour = Colour::Error;
passOrFail = "FAILED";
}
if( _stats.infoMessages.size() == 1 )
messageLabel = "with message";
if( _stats.infoMessages.size() > 1 )
messageLabel = "with messages";
break;
case ResultWas::ThrewException:
colour = Colour::Error;
passOrFail = "FAILED";
messageLabel = "due to unexpected exception with message";
break;
case ResultWas::FatalErrorCondition:
colour = Colour::Error;
passOrFail = "FAILED";
messageLabel = "due to a fatal error condition";
break;
case ResultWas::DidntThrowException:
colour = Colour::Error;
passOrFail = "FAILED";
messageLabel = "because no exception was thrown where one was expected";
break;
case ResultWas::Info:
messageLabel = "info";
break;
case ResultWas::Warning:
messageLabel = "warning";
break;
case ResultWas::ExplicitFailure:
passOrFail = "FAILED";
colour = Colour::Error;
if( _stats.infoMessages.size() == 1 )
messageLabel = "explicitly with message";
if( _stats.infoMessages.size() > 1 )
messageLabel = "explicitly with messages";
break;
case ResultWas::Unknown:
case ResultWas::FailureBit:
case ResultWas::Exception:
passOrFail = "** internal error **";
colour = Colour::Error;
break;
}
}
void print() const {
printSourceInfo();
if( stats.totals.assertions.total() > 0 ) {
if( result.isOk() )
stream << "\n";
printResultType();
printOriginalExpression();
printReconstructedExpression();
}
else {
stream << "\n";
}
printMessage();
}
private:
void printResultType() const {
if( !passOrFail.empty() ) {
Colour colourGuard( colour );
stream << passOrFail << ":\n";
}
}
void printOriginalExpression() const {
if( result.hasExpression() ) {
Colour colourGuard( Colour::OriginalExpression );
stream << " ";
stream << result.getExpressionInMacro();
stream << "\n";
}
}
void printReconstructedExpression() const {
if( result.hasExpandedExpression() ) {
stream << "with expansion:\n";
Colour colourGuard( Colour::ReconstructedExpression );
stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n";
}
}
void printMessage() const {
if( !messageLabel.empty() )
stream << messageLabel << ":" << "\n";
for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
it != itEnd;
++it ) {
if( printInfoMessages || it->type != ResultWas::Info )
stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n";
}
}
void printSourceInfo() const {
Colour colourGuard( Colour::FileName );
stream << result.getSourceInfo() << ": ";
}
std::ostream& stream;
AssertionStats const& stats;
AssertionResult const& result;
Colour::Code colour;
std::string passOrFail;
std::string messageLabel;
std::string message;
std::vector<MessageInfo> messages;
bool printInfoMessages;
};
void lazyPrint() {
if( !currentTestRunInfo.used )
lazyPrintRunInfo();
if( !currentGroupInfo.used )
lazyPrintGroupInfo();
if( !m_headerPrinted ) {
printTestCaseAndSectionHeader();
m_headerPrinted = true;
}
}
void lazyPrintRunInfo() {
stream << "\n" << getLineOfChars<'~'>() << "\n";
Colour colour( Colour::SecondaryText );
stream << currentTestRunInfo->name
<< " is a Catch v" << libraryVersion << " host application.\n"
<< "Run with -? for options\n\n";
if( m_config->rngSeed() != 0 )
stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
currentTestRunInfo.used = true;
}
void lazyPrintGroupInfo() {
if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
printClosedHeader( "Group: " + currentGroupInfo->name );
currentGroupInfo.used = true;
}
}
void printTestCaseAndSectionHeader() {
assert( !m_sectionStack.empty() );
printOpenHeader( currentTestCaseInfo->name );
if( m_sectionStack.size() > 1 ) {
Colour colourGuard( Colour::Headers );
std::vector<SectionInfo>::const_iterator
it = m_sectionStack.begin()+1,
itEnd = m_sectionStack.end();
for( ; it != itEnd; ++it )
printHeaderString( it->name, 2 );
}
SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
if( !lineInfo.empty() ){
stream << getLineOfChars<'-'>() << "\n";
Colour colourGuard( Colour::FileName );
stream << lineInfo << "\n";
}
stream << getLineOfChars<'.'>() << "\n" << std::endl;
}
void printClosedHeader( std::string const& _name ) {
printOpenHeader( _name );
stream << getLineOfChars<'.'>() << "\n";
}
void printOpenHeader( std::string const& _name ) {
stream << getLineOfChars<'-'>() << "\n";
{
Colour colourGuard( Colour::Headers );
printHeaderString( _name );
}
}
void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
std::size_t i = _string.find( ": " );
if( i != std::string::npos )
i+=2;
else
i = 0;
stream << Text( _string, TextAttributes()
.setIndent( indent+i)
.setInitialIndent( indent ) ) << "\n";
}
struct SummaryColumn {
SummaryColumn( std::string const& _label, Colour::Code _colour )
: label( _label ),
colour( _colour )
{}
SummaryColumn addRow( std::size_t count ) {
std::ostringstream oss;
oss << count;
std::string row = oss.str();
for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
while( it->size() < row.size() )
*it = " " + *it;
while( it->size() > row.size() )
row = " " + row;
}
rows.push_back( row );
return *this;
}
std::string label;
Colour::Code colour;
std::vector<std::string> rows;
};
void printTotals( Totals const& totals ) {
if( totals.testCases.total() == 0 ) {
stream << Colour( Colour::Warning ) << "No tests ran\n";
}
else if( totals.assertions.total() > 0 && totals.assertions.allPassed() ) {
stream << Colour( Colour::ResultSuccess ) << "All tests passed";
stream << " ("
<< pluralise( totals.assertions.passed, "assertion" ) << " in "
<< pluralise( totals.testCases.passed, "test case" ) << ")"
<< "\n";
}
else {
std::vector<SummaryColumn> columns;
columns.push_back( SummaryColumn( "", Colour::None )
.addRow( totals.testCases.total() )
.addRow( totals.assertions.total() ) );
columns.push_back( SummaryColumn( "passed", Colour::Success )
.addRow( totals.testCases.passed )
.addRow( totals.assertions.passed ) );
columns.push_back( SummaryColumn( "failed", Colour::ResultError )
.addRow( totals.testCases.failed )
.addRow( totals.assertions.failed ) );
columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
.addRow( totals.testCases.failedButOk )
.addRow( totals.assertions.failedButOk ) );
printSummaryRow( "test cases", columns, 0 );
printSummaryRow( "assertions", columns, 1 );
}
}
void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
std::string value = it->rows[row];
if( it->label.empty() ) {
stream << label << ": ";
if( value != "0" )
stream << value;
else
stream << Colour( Colour::Warning ) << "- none -";
}
else if( value != "0" ) {
stream << Colour( Colour::LightGrey ) << " | ";
stream << Colour( it->colour )
<< value << " " << it->label;
}
}
stream << "\n";
}
static std::size_t makeRatio( std::size_t number, std::size_t total ) {
std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
return ( ratio == 0 && number > 0 ) ? 1 : ratio;
}
static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
if( i > j && i > k )
return i;
else if( j > k )
return j;
else
return k;
}
void printTotalsDivider( Totals const& totals ) {
if( totals.testCases.total() > 0 ) {
std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
findMax( failedRatio, failedButOkRatio, passedRatio )++;
while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
findMax( failedRatio, failedButOkRatio, passedRatio )--;
stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
if( totals.testCases.allPassed() )
stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
else
stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
}
else {
stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
}
stream << "\n";
}
void printSummaryDivider() {
stream << getLineOfChars<'-'>() << "\n";
}
private:
bool m_headerPrinted;
};
INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
}
#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
namespace Catch {
struct CompactReporter : StreamingReporterBase {
CompactReporter( ReporterConfig const& _config )
: StreamingReporterBase( _config )
{}
virtual ~CompactReporter();
static std::string getDescription() {
return "Reports test results on a single line, suitable for IDEs";
}
virtual ReporterPreferences getPreferences() const {
ReporterPreferences prefs;
prefs.shouldRedirectStdOut = false;
return prefs;
}
virtual void noMatchingTestCases( std::string const& spec ) {
stream << "No test cases matched '" << spec << "'" << std::endl;
}
virtual void assertionStarting( AssertionInfo const& ) {
}
virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
AssertionResult const& result = _assertionStats.assertionResult;
bool printInfoMessages = true;
if( !m_config->includeSuccessfulResults() && result.isOk() ) {
if( result.getResultType() != ResultWas::Warning )
return false;
printInfoMessages = false;
}
AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
printer.print();
stream << std::endl;
return true;
}
virtual void testRunEnded( TestRunStats const& _testRunStats ) {
printTotals( _testRunStats.totals );
stream << "\n" << std::endl;
StreamingReporterBase::testRunEnded( _testRunStats );
}
private:
class AssertionPrinter {
void operator= ( AssertionPrinter const& );
public:
AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
: stream( _stream )
, stats( _stats )
, result( _stats.assertionResult )
, messages( _stats.infoMessages )
, itMessage( _stats.infoMessages.begin() )
, printInfoMessages( _printInfoMessages )
{}
void print() {
printSourceInfo();
itMessage = messages.begin();
switch( result.getResultType() ) {
case ResultWas::Ok:
printResultType( Colour::ResultSuccess, passedString() );
printOriginalExpression();
printReconstructedExpression();
if ( ! result.hasExpression() )
printRemainingMessages( Colour::None );
else
printRemainingMessages();
break;
case ResultWas::ExpressionFailed:
if( result.isOk() )
printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
else
printResultType( Colour::Error, failedString() );
printOriginalExpression();
printReconstructedExpression();
printRemainingMessages();
break;
case ResultWas::ThrewException:
printResultType( Colour::Error, failedString() );
printIssue( "unexpected exception with message:" );
printMessage();
printExpressionWas();
printRemainingMessages();
break;
case ResultWas::FatalErrorCondition:
printResultType( Colour::Error, failedString() );
printIssue( "fatal error condition with message:" );
printMessage();
printExpressionWas();
printRemainingMessages();
break;
case ResultWas::DidntThrowException:
printResultType( Colour::Error, failedString() );
printIssue( "expected exception, got none" );
printExpressionWas();
printRemainingMessages();
break;
case ResultWas::Info:
printResultType( Colour::None, "info" );
printMessage();
printRemainingMessages();
break;
case ResultWas::Warning:
printResultType( Colour::None, "warning" );
printMessage();
printRemainingMessages();
break;
case ResultWas::ExplicitFailure:
printResultType( Colour::Error, failedString() );
printIssue( "explicitly" );
printRemainingMessages( Colour::None );
break;
case ResultWas::Unknown:
case ResultWas::FailureBit:
case ResultWas::Exception:
printResultType( Colour::Error, "** internal error **" );
break;
}
}
private:
static Colour::Code dimColour() { return Colour::FileName; }
#ifdef CATCH_PLATFORM_MAC
static const char* failedString() { return "FAILED"; }
static const char* passedString() { return "PASSED"; }
#else
static const char* failedString() { return "failed"; }
static const char* passedString() { return "passed"; }
#endif
void printSourceInfo() const {
Colour colourGuard( Colour::FileName );
stream << result.getSourceInfo() << ":";
}
void printResultType( Colour::Code colour, std::string passOrFail ) const {
if( !passOrFail.empty() ) {
{
Colour colourGuard( colour );
stream << " " << passOrFail;
}
stream << ":";
}
}
void printIssue( std::string issue ) const {
stream << " " << issue;
}
void printExpressionWas() {
if( result.hasExpression() ) {
stream << ";";
{
Colour colour( dimColour() );
stream << " expression was:";
}
printOriginalExpression();
}
}
void printOriginalExpression() const {
if( result.hasExpression() ) {
stream << " " << result.getExpression();
}
}
void printReconstructedExpression() const {
if( result.hasExpandedExpression() ) {
{
Colour colour( dimColour() );
stream << " for: ";
}
stream << result.getExpandedExpression();
}
}
void printMessage() {
if ( itMessage != messages.end() ) {
stream << " '" << itMessage->message << "'";
++itMessage;
}
}
void printRemainingMessages( Colour::Code colour = dimColour() ) {
if ( itMessage == messages.end() )
return;
std::vector<MessageInfo>::const_iterator itEnd = messages.end();
const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
{
Colour colourGuard( colour );
stream << " with " << pluralise( N, "message" ) << ":";
}
for(; itMessage != itEnd; ) {
if( printInfoMessages || itMessage->type != ResultWas::Info ) {
stream << " '" << itMessage->message << "'";
if ( ++itMessage != itEnd ) {
Colour colourGuard( dimColour() );
stream << " and";
}
}
}
}
private:
std::ostream& stream;
AssertionStats const& stats;
AssertionResult const& result;
std::vector<MessageInfo> messages;
std::vector<MessageInfo>::const_iterator itMessage;
bool printInfoMessages;
};
std::string bothOrAll( std::size_t count ) const {
return count == 1 ? "" : count == 2 ? "both " : "all " ;
}
void printTotals( const Totals& totals ) const {
if( totals.testCases.total() == 0 ) {
stream << "No tests ran.";
}
else if( totals.testCases.failed == totals.testCases.total() ) {
Colour colour( Colour::ResultError );
const std::string qualify_assertions_failed =
totals.assertions.failed == totals.assertions.total() ?
bothOrAll( totals.assertions.failed ) : "";
stream <<
"Failed " << bothOrAll( totals.testCases.failed )
<< pluralise( totals.testCases.failed, "test case" ) << ", "
"failed " << qualify_assertions_failed <<
pluralise( totals.assertions.failed, "assertion" ) << ".";
}
else if( totals.assertions.total() == 0 ) {
stream <<
"Passed " << bothOrAll( totals.testCases.total() )
<< pluralise( totals.testCases.total(), "test case" )
<< " (no assertions).";
}
else if( totals.assertions.failed ) {
Colour colour( Colour::ResultError );
stream <<
"Failed " << pluralise( totals.testCases.failed, "test case" ) << ", "
"failed " << pluralise( totals.assertions.failed, "assertion" ) << ".";
}
else {
Colour colour( Colour::ResultSuccess );
stream <<
"Passed " << bothOrAll( totals.testCases.passed )
<< pluralise( totals.testCases.passed, "test case" ) <<
" with " << pluralise( totals.assertions.passed, "assertion" ) << ".";
}
}
};
INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
}
namespace Catch {
NonCopyable::~NonCopyable() {}
IShared::~IShared() {}
IStream::~IStream() CATCH_NOEXCEPT {}
FileStream::~FileStream() CATCH_NOEXCEPT {}
CoutStream::~CoutStream() CATCH_NOEXCEPT {}
DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {}
StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
IContext::~IContext() {}
IResultCapture::~IResultCapture() {}
ITestCase::~ITestCase() {}
ITestCaseRegistry::~ITestCaseRegistry() {}
IRegistryHub::~IRegistryHub() {}
IMutableRegistryHub::~IMutableRegistryHub() {}
IExceptionTranslator::~IExceptionTranslator() {}
IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
IReporter::~IReporter() {}
IReporterFactory::~IReporterFactory() {}
IReporterRegistry::~IReporterRegistry() {}
IStreamingReporter::~IStreamingReporter() {}
AssertionStats::~AssertionStats() {}
SectionStats::~SectionStats() {}
TestCaseStats::~TestCaseStats() {}
TestGroupStats::~TestGroupStats() {}
TestRunStats::~TestRunStats() {}
CumulativeReporterBase::SectionNode::~SectionNode() {}
CumulativeReporterBase::~CumulativeReporterBase() {}
StreamingReporterBase::~StreamingReporterBase() {}
ConsoleReporter::~ConsoleReporter() {}
CompactReporter::~CompactReporter() {}
IRunner::~IRunner() {}
IMutableContext::~IMutableContext() {}
IConfig::~IConfig() {}
XmlReporter::~XmlReporter() {}
JunitReporter::~JunitReporter() {}
TestRegistry::~TestRegistry() {}
FreeFunctionTestCase::~FreeFunctionTestCase() {}
IGeneratorInfo::~IGeneratorInfo() {}
IGeneratorsForTest::~IGeneratorsForTest() {}
WildcardPattern::~WildcardPattern() {}
TestSpec::Pattern::~Pattern() {}
TestSpec::NamePattern::~NamePattern() {}
TestSpec::TagPattern::~TagPattern() {}
TestSpec::ExcludedPattern::~ExcludedPattern() {}
Matchers::Impl::StdString::Equals::~Equals() {}
Matchers::Impl::StdString::Contains::~Contains() {}
Matchers::Impl::StdString::StartsWith::~StartsWith() {}
Matchers::Impl::StdString::EndsWith::~EndsWith() {}
void Config::dummy() {}
namespace TestCaseTracking {
ITracker::~ITracker() {}
TrackerBase::~TrackerBase() {}
SectionTracker::~SectionTracker() {}
IndexTracker::~IndexTracker() {}
}
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#endif
#ifdef CATCH_CONFIG_MAIN
#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
#ifndef __OBJC__
int main (int argc, char * argv[]) {
return Catch::Session().run( argc, argv );
}
#else
int main (int argc, char * const argv[]) {
#if !CATCH_ARC_ENABLED
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
#endif
Catch::registerTestMethods();
int result = Catch::Session().run( argc, (char* const*)argv );
#if !CATCH_ARC_ENABLED
[pool drain];
#endif
return result;
}
#endif
#endif
#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
# undef CLARA_CONFIG_MAIN
#endif
#ifdef CATCH_CONFIG_PREFIX_ALL
#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "CATCH_REQUIRE_THROWS" )
#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "CATCH_REQUIRE_THROWS_WITH" )
#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" )
#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" )
#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" )
#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
#ifdef CATCH_CONFIG_VARIADIC_MACROS
#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
#else
#define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
#define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
#define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
#define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )
#define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
#define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
#define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
#endif
#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
#ifdef CATCH_CONFIG_VARIADIC_MACROS
#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
#else
#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
#endif
#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc, "" )
#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc, "" )
#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" )
#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc, "" )
#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" )
#else
#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "REQUIRE_THROWS" )
#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "REQUIRE_THROWS_WITH" )
#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" )
#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CHECK_THROWS" )
#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CHECK_THROWS_WITH" )
#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
#ifdef CATCH_CONFIG_VARIADIC_MACROS
#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
#define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
#else
#define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
#define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
#define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
#define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description )
#define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
#define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
#define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
#endif
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
#endif
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
#ifdef CATCH_CONFIG_VARIADIC_MACROS
#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
#else
#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
#endif
#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc, "" )
#define WHEN( desc ) SECTION( std::string(" When: ") + desc, "" )
#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" )
#define THEN( desc ) SECTION( std::string(" Then: ") + desc, "" )
#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc, "" )
using Catch::Detail::Approx;
#endif
namespace fakeit {
struct VerificationException : public FakeitException {
virtual ~VerificationException() = default;
void setFileInfo(std::string file, int line, std::string callingMethod) {
_file = file;
_callingMethod = callingMethod;
_line = line;
}
const std::string& file() const {
return _file;
}
int line() const {
return _line;
}
const std::string& callingMethod() const {
return _callingMethod;
}
private:
std::string _file;
int _line;
std::string _callingMethod;
};
struct NoMoreInvocationsVerificationException : public VerificationException {
NoMoreInvocationsVerificationException(std::string format) :
_format(format) {
}
virtual std::string what() const override {
return _format;
}
private:
std::string _format;
};
struct SequenceVerificationException : public VerificationException {
SequenceVerificationException(const std::string& format) :
_format(format)
{
}
virtual std::string what() const override {
return _format;
}
private:
std::string _format;
};
class CatchAdapter: public EventHandler {
EventFormatter& _formatter;
std::string formatLineNumner(std::string file, int num){
#ifndef __GNUG__
return file + std::string("(") + std::to_string(num) + std::string(")");
#else
return file + std::string(":")+ std::to_string(num);
#endif
}
public:
virtual ~CatchAdapter() = default;
CatchAdapter(EventFormatter& formatter)
: _formatter(formatter){}
virtual void handle(const UnexpectedMethodCallEvent &evt) override {
std::string format = _formatter.format(evt);
UnexpectedMethodCallException ex(format);
throw ex;
}
virtual void handle(const SequenceVerificationEvent &evt) override {
std::string format(formatLineNumner(evt.file(),evt.line()) + ": " + _formatter.format(evt));
SequenceVerificationException e(format);
e.setFileInfo(evt.file(), evt.line(), evt.callingMethod());
throw e;
}
virtual void handle(const NoMoreInvocationsVerificationEvent &evt) override {
std::string format(formatLineNumner(evt.file(), evt.line()) + ": " + _formatter.format(evt));
NoMoreInvocationsVerificationException e(format);
e.setFileInfo(evt.file(), evt.line(), evt.callingMethod());
throw e;
}
};
class CatchFakeit: public DefaultFakeit {
public:
virtual ~CatchFakeit() = default;
CatchFakeit() : _formatter(), _catchAdapter(_formatter) {}
static CatchFakeit &getInstance() {
static CatchFakeit instance;
return instance;
}
protected:
fakeit::EventHandler &accessTestingFrameworkAdapter() override {
return _catchAdapter;
}
EventFormatter &accessEventFormatter() override {
return _formatter;
}
private:
DefaultEventFormatter _formatter;
CatchAdapter _catchAdapter;
};
}
CATCH_TRANSLATE_EXCEPTION(fakeit::UnexpectedMethodCallException& ex) {
return ex.what();
}
CATCH_TRANSLATE_EXCEPTION(fakeit::SequenceVerificationException& ex) {
return ex.what();
}
CATCH_TRANSLATE_EXCEPTION(fakeit::NoMoreInvocationsVerificationException& ex) {
return ex.what();
}
static fakeit::DefaultFakeit& Fakeit = fakeit::CatchFakeit::getInstance();
#include <type_traits>
#include <unordered_set>
#include <memory>
#include <functional>
#include <type_traits>
#include <vector>
#include <array>
#include <new>
#include <functional>
#include <type_traits>
namespace fakeit {
struct VirtualOffsetSelector {
unsigned int offset;
virtual unsigned int offset0(int) {
return offset = 0;
}
virtual unsigned int offset1(int) {
return offset = 1;
}
virtual unsigned int offset2(int) {
return offset = 2;
}
virtual unsigned int offset3(int) {
return offset = 3;
}
virtual unsigned int offset4(int) {
return offset = 4;
}
virtual unsigned int offset5(int) {
return offset = 5;
}
virtual unsigned int offset6(int) {
return offset = 6;
}
virtual unsigned int offset7(int) {
return offset = 7;
}
virtual unsigned int offset8(int) {
return offset = 8;
}
virtual unsigned int offset9(int) {
return offset = 9;
}
virtual unsigned int offset10(int) {
return offset = 10;
}
virtual unsigned int offset11(int) {
return offset = 11;
}
virtual unsigned int offset12(int) {
return offset = 12;
}
virtual unsigned int offset13(int) {
return offset = 13;
}
virtual unsigned int offset14(int) {
return offset = 14;
}
virtual unsigned int offset15(int) {
return offset = 15;
}
virtual unsigned int offset16(int) {
return offset = 16;
}
virtual unsigned int offset17(int) {
return offset = 17;
}
virtual unsigned int offset18(int) {
return offset = 18;
}
virtual unsigned int offset19(int) {
return offset = 19;
}
virtual unsigned int offset20(int) {
return offset = 20;
}
virtual unsigned int offset21(int) {
return offset = 21;
}
virtual unsigned int offset22(int) {
return offset = 22;
}
virtual unsigned int offset23(int) {
return offset = 23;
}
virtual unsigned int offset24(int) {
return offset = 24;
}
virtual unsigned int offset25(int) {
return offset = 25;
}
virtual unsigned int offset26(int) {
return offset = 26;
}
virtual unsigned int offset27(int) {
return offset = 27;
}
virtual unsigned int offset28(int) {
return offset = 28;
}
virtual unsigned int offset29(int) {
return offset = 29;
}
virtual unsigned int offset30(int) {
return offset = 30;
}
virtual unsigned int offset31(int) {
return offset = 31;
}
virtual unsigned int offset32(int) {
return offset = 32;
}
virtual unsigned int offset33(int) {
return offset = 33;
}
virtual unsigned int offset34(int) {
return offset = 34;
}
virtual unsigned int offset35(int) {
return offset = 35;
}
virtual unsigned int offset36(int) {
return offset = 36;
}
virtual unsigned int offset37(int) {
return offset = 37;
}
virtual unsigned int offset38(int) {
return offset = 38;
}
virtual unsigned int offset39(int) {
return offset = 39;
}
virtual unsigned int offset40(int) {
return offset = 40;
}
virtual unsigned int offset41(int) {
return offset = 41;
}
virtual unsigned int offset42(int) {
return offset = 42;
}
virtual unsigned int offset43(int) {
return offset = 43;
}
virtual unsigned int offset44(int) {
return offset = 44;
}
virtual unsigned int offset45(int) {
return offset = 45;
}
virtual unsigned int offset46(int) {
return offset = 46;
}
virtual unsigned int offset47(int) {
return offset = 47;
}
virtual unsigned int offset48(int) {
return offset = 48;
}
virtual unsigned int offset49(int) {
return offset = 49;
}
virtual unsigned int offset50(int) {
return offset = 50;
}
virtual unsigned int offset51(int) {
return offset = 51;
}
virtual unsigned int offset52(int) {
return offset = 52;
}
virtual unsigned int offset53(int) {
return offset = 53;
}
virtual unsigned int offset54(int) {
return offset = 54;
}
virtual unsigned int offset55(int) {
return offset = 55;
}
virtual unsigned int offset56(int) {
return offset = 56;
}
virtual unsigned int offset57(int) {
return offset = 57;
}
virtual unsigned int offset58(int) {
return offset = 58;
}
virtual unsigned int offset59(int) {
return offset = 59;
}
virtual unsigned int offset60(int) {
return offset = 60;
}
virtual unsigned int offset61(int) {
return offset = 61;
}
virtual unsigned int offset62(int) {
return offset = 62;
}
virtual unsigned int offset63(int) {
return offset = 63;
}
virtual unsigned int offset64(int) {
return offset = 64;
}
virtual unsigned int offset65(int) {
return offset = 65;
}
virtual unsigned int offset66(int) {
return offset = 66;
}
virtual unsigned int offset67(int) {
return offset = 67;
}
virtual unsigned int offset68(int) {
return offset = 68;
}
virtual unsigned int offset69(int) {
return offset = 69;
}
virtual unsigned int offset70(int) {
return offset = 70;
}
virtual unsigned int offset71(int) {
return offset = 71;
}
virtual unsigned int offset72(int) {
return offset = 72;
}
virtual unsigned int offset73(int) {
return offset = 73;
}
virtual unsigned int offset74(int) {
return offset = 74;
}
virtual unsigned int offset75(int) {
return offset = 75;
}
virtual unsigned int offset76(int) {
return offset = 76;
}
virtual unsigned int offset77(int) {
return offset = 77;
}
virtual unsigned int offset78(int) {
return offset = 78;
}
virtual unsigned int offset79(int) {
return offset = 79;
}
virtual unsigned int offset80(int) {
return offset = 80;
}
virtual unsigned int offset81(int) {
return offset = 81;
}
virtual unsigned int offset82(int) {
return offset = 82;
}
virtual unsigned int offset83(int) {
return offset = 83;
}
virtual unsigned int offset84(int) {
return offset = 84;
}
virtual unsigned int offset85(int) {
return offset = 85;
}
virtual unsigned int offset86(int) {
return offset = 86;
}
virtual unsigned int offset87(int) {
return offset = 87;
}
virtual unsigned int offset88(int) {
return offset = 88;
}
virtual unsigned int offset89(int) {
return offset = 89;
}
virtual unsigned int offset90(int) {
return offset = 90;
}
virtual unsigned int offset91(int) {
return offset = 91;
}
virtual unsigned int offset92(int) {
return offset = 92;
}
virtual unsigned int offset93(int) {
return offset = 93;
}
virtual unsigned int offset94(int) {
return offset = 94;
}
virtual unsigned int offset95(int) {
return offset = 95;
}
virtual unsigned int offset96(int) {
return offset = 96;
}
virtual unsigned int offset97(int) {
return offset = 97;
}
virtual unsigned int offset98(int) {
return offset = 98;
}
virtual unsigned int offset99(int) {
return offset = 99;
}
virtual unsigned int offset100(int) {
return offset = 100;
}
virtual unsigned int offset101(int) {
return offset = 101;
}
virtual unsigned int offset102(int) {
return offset = 102;
}
virtual unsigned int offset103(int) {
return offset = 103;
}
virtual unsigned int offset104(int) {
return offset = 104;
}
virtual unsigned int offset105(int) {
return offset = 105;
}
virtual unsigned int offset106(int) {
return offset = 106;
}
virtual unsigned int offset107(int) {
return offset = 107;
}
virtual unsigned int offset108(int) {
return offset = 108;
}
virtual unsigned int offset109(int) {
return offset = 109;
}
virtual unsigned int offset110(int) {
return offset = 110;
}
virtual unsigned int offset111(int) {
return offset = 111;
}
virtual unsigned int offset112(int) {
return offset = 112;
}
virtual unsigned int offset113(int) {
return offset = 113;
}
virtual unsigned int offset114(int) {
return offset = 114;
}
virtual unsigned int offset115(int) {
return offset = 115;
}
virtual unsigned int offset116(int) {
return offset = 116;
}
virtual unsigned int offset117(int) {
return offset = 117;
}
virtual unsigned int offset118(int) {
return offset = 118;
}
virtual unsigned int offset119(int) {
return offset = 119;
}
virtual unsigned int offset120(int) {
return offset = 120;
}
virtual unsigned int offset121(int) {
return offset = 121;
}
virtual unsigned int offset122(int) {
return offset = 122;
}
virtual unsigned int offset123(int) {
return offset = 123;
}
virtual unsigned int offset124(int) {
return offset = 124;
}
virtual unsigned int offset125(int) {
return offset = 125;
}
virtual unsigned int offset126(int) {
return offset = 126;
}
virtual unsigned int offset127(int) {
return offset = 127;
}
virtual unsigned int offset128(int) {
return offset = 128;
}
virtual unsigned int offset129(int) {
return offset = 129;
}
virtual unsigned int offset130(int) {
return offset = 130;
}
virtual unsigned int offset131(int) {
return offset = 131;
}
virtual unsigned int offset132(int) {
return offset = 132;
}
virtual unsigned int offset133(int) {
return offset = 133;
}
virtual unsigned int offset134(int) {
return offset = 134;
}
virtual unsigned int offset135(int) {
return offset = 135;
}
virtual unsigned int offset136(int) {
return offset = 136;
}
virtual unsigned int offset137(int) {
return offset = 137;
}
virtual unsigned int offset138(int) {
return offset = 138;
}
virtual unsigned int offset139(int) {
return offset = 139;
}
virtual unsigned int offset140(int) {
return offset = 140;
}
virtual unsigned int offset141(int) {
return offset = 141;
}
virtual unsigned int offset142(int) {
return offset = 142;
}
virtual unsigned int offset143(int) {
return offset = 143;
}
virtual unsigned int offset144(int) {
return offset = 144;
}
virtual unsigned int offset145(int) {
return offset = 145;
}
virtual unsigned int offset146(int) {
return offset = 146;
}
virtual unsigned int offset147(int) {
return offset = 147;
}
virtual unsigned int offset148(int) {
return offset = 148;
}
virtual unsigned int offset149(int) {
return offset = 149;
}
virtual unsigned int offset150(int) {
return offset = 150;
}
virtual unsigned int offset151(int) {
return offset = 151;
}
virtual unsigned int offset152(int) {
return offset = 152;
}
virtual unsigned int offset153(int) {
return offset = 153;
}
virtual unsigned int offset154(int) {
return offset = 154;
}
virtual unsigned int offset155(int) {
return offset = 155;
}
virtual unsigned int offset156(int) {
return offset = 156;
}
virtual unsigned int offset157(int) {
return offset = 157;
}
virtual unsigned int offset158(int) {
return offset = 158;
}
virtual unsigned int offset159(int) {
return offset = 159;
}
virtual unsigned int offset160(int) {
return offset = 160;
}
virtual unsigned int offset161(int) {
return offset = 161;
}
virtual unsigned int offset162(int) {
return offset = 162;
}
virtual unsigned int offset163(int) {
return offset = 163;
}
virtual unsigned int offset164(int) {
return offset = 164;
}
virtual unsigned int offset165(int) {
return offset = 165;
}
virtual unsigned int offset166(int) {
return offset = 166;
}
virtual unsigned int offset167(int) {
return offset = 167;
}
virtual unsigned int offset168(int) {
return offset = 168;
}
virtual unsigned int offset169(int) {
return offset = 169;
}
virtual unsigned int offset170(int) {
return offset = 170;
}
virtual unsigned int offset171(int) {
return offset = 171;
}
virtual unsigned int offset172(int) {
return offset = 172;
}
virtual unsigned int offset173(int) {
return offset = 173;
}
virtual unsigned int offset174(int) {
return offset = 174;
}
virtual unsigned int offset175(int) {
return offset = 175;
}
virtual unsigned int offset176(int) {
return offset = 176;
}
virtual unsigned int offset177(int) {
return offset = 177;
}
virtual unsigned int offset178(int) {
return offset = 178;
}
virtual unsigned int offset179(int) {
return offset = 179;
}
virtual unsigned int offset180(int) {
return offset = 180;
}
virtual unsigned int offset181(int) {
return offset = 181;
}
virtual unsigned int offset182(int) {
return offset = 182;
}
virtual unsigned int offset183(int) {
return offset = 183;
}
virtual unsigned int offset184(int) {
return offset = 184;
}
virtual unsigned int offset185(int) {
return offset = 185;
}
virtual unsigned int offset186(int) {
return offset = 186;
}
virtual unsigned int offset187(int) {
return offset = 187;
}
virtual unsigned int offset188(int) {
return offset = 188;
}
virtual unsigned int offset189(int) {
return offset = 189;
}
virtual unsigned int offset190(int) {
return offset = 190;
}
virtual unsigned int offset191(int) {
return offset = 191;
}
virtual unsigned int offset192(int) {
return offset = 192;
}
virtual unsigned int offset193(int) {
return offset = 193;
}
virtual unsigned int offset194(int) {
return offset = 194;
}
virtual unsigned int offset195(int) {
return offset = 195;
}
virtual unsigned int offset196(int) {
return offset = 196;
}
virtual unsigned int offset197(int) {
return offset = 197;
}
virtual unsigned int offset198(int) {
return offset = 198;
}
virtual unsigned int offset199(int) {
return offset = 199;
}
virtual unsigned int offset200(int) {
return offset = 200;
}
virtual unsigned int offset201(int) {
return offset = 201;
}
virtual unsigned int offset202(int) {
return offset = 202;
}
virtual unsigned int offset203(int) {
return offset = 203;
}
virtual unsigned int offset204(int) {
return offset = 204;
}
virtual unsigned int offset205(int) {
return offset = 205;
}
virtual unsigned int offset206(int) {
return offset = 206;
}
virtual unsigned int offset207(int) {
return offset = 207;
}
virtual unsigned int offset208(int) {
return offset = 208;
}
virtual unsigned int offset209(int) {
return offset = 209;
}
virtual unsigned int offset210(int) {
return offset = 210;
}
virtual unsigned int offset211(int) {
return offset = 211;
}
virtual unsigned int offset212(int) {
return offset = 212;
}
virtual unsigned int offset213(int) {
return offset = 213;
}
virtual unsigned int offset214(int) {
return offset = 214;
}
virtual unsigned int offset215(int) {
return offset = 215;
}
virtual unsigned int offset216(int) {
return offset = 216;
}
virtual unsigned int offset217(int) {
return offset = 217;
}
virtual unsigned int offset218(int) {
return offset = 218;
}
virtual unsigned int offset219(int) {
return offset = 219;
}
virtual unsigned int offset220(int) {
return offset = 220;
}
virtual unsigned int offset221(int) {
return offset = 221;
}
virtual unsigned int offset222(int) {
return offset = 222;
}
virtual unsigned int offset223(int) {
return offset = 223;
}
virtual unsigned int offset224(int) {
return offset = 224;
}
virtual unsigned int offset225(int) {
return offset = 225;
}
virtual unsigned int offset226(int) {
return offset = 226;
}
virtual unsigned int offset227(int) {
return offset = 227;
}
virtual unsigned int offset228(int) {
return offset = 228;
}
virtual unsigned int offset229(int) {
return offset = 229;
}
virtual unsigned int offset230(int) {
return offset = 230;
}
virtual unsigned int offset231(int) {
return offset = 231;
}
virtual unsigned int offset232(int) {
return offset = 232;
}
virtual unsigned int offset233(int) {
return offset = 233;
}
virtual unsigned int offset234(int) {
return offset = 234;
}
virtual unsigned int offset235(int) {
return offset = 235;
}
virtual unsigned int offset236(int) {
return offset = 236;
}
virtual unsigned int offset237(int) {
return offset = 237;
}
virtual unsigned int offset238(int) {
return offset = 238;
}
virtual unsigned int offset239(int) {
return offset = 239;
}
virtual unsigned int offset240(int) {
return offset = 240;
}
virtual unsigned int offset241(int) {
return offset = 241;
}
virtual unsigned int offset242(int) {
return offset = 242;
}
virtual unsigned int offset243(int) {
return offset = 243;
}
virtual unsigned int offset244(int) {
return offset = 244;
}
virtual unsigned int offset245(int) {
return offset = 245;
}
virtual unsigned int offset246(int) {
return offset = 246;
}
virtual unsigned int offset247(int) {
return offset = 247;
}
virtual unsigned int offset248(int) {
return offset = 248;
}
virtual unsigned int offset249(int) {
return offset = 249;
}
virtual unsigned int offset250(int) {
return offset = 250;
}
virtual unsigned int offset251(int) {
return offset = 251;
}
virtual unsigned int offset252(int) {
return offset = 252;
}
virtual unsigned int offset253(int) {
return offset = 253;
}
virtual unsigned int offset254(int) {
return offset = 254;
}
virtual unsigned int offset255(int) {
return offset = 255;
}
virtual unsigned int offset256(int) {
return offset = 256;
}
virtual unsigned int offset257(int) {
return offset = 257;
}
virtual unsigned int offset258(int) {
return offset = 258;
}
virtual unsigned int offset259(int) {
return offset = 259;
}
virtual unsigned int offset260(int) {
return offset = 260;
}
virtual unsigned int offset261(int) {
return offset = 261;
}
virtual unsigned int offset262(int) {
return offset = 262;
}
virtual unsigned int offset263(int) {
return offset = 263;
}
virtual unsigned int offset264(int) {
return offset = 264;
}
virtual unsigned int offset265(int) {
return offset = 265;
}
virtual unsigned int offset266(int) {
return offset = 266;
}
virtual unsigned int offset267(int) {
return offset = 267;
}
virtual unsigned int offset268(int) {
return offset = 268;
}
virtual unsigned int offset269(int) {
return offset = 269;
}
virtual unsigned int offset270(int) {
return offset = 270;
}
virtual unsigned int offset271(int) {
return offset = 271;
}
virtual unsigned int offset272(int) {
return offset = 272;
}
virtual unsigned int offset273(int) {
return offset = 273;
}
virtual unsigned int offset274(int) {
return offset = 274;
}
virtual unsigned int offset275(int) {
return offset = 275;
}
virtual unsigned int offset276(int) {
return offset = 276;
}
virtual unsigned int offset277(int) {
return offset = 277;
}
virtual unsigned int offset278(int) {
return offset = 278;
}
virtual unsigned int offset279(int) {
return offset = 279;
}
virtual unsigned int offset280(int) {
return offset = 280;
}
virtual unsigned int offset281(int) {
return offset = 281;
}
virtual unsigned int offset282(int) {
return offset = 282;
}
virtual unsigned int offset283(int) {
return offset = 283;
}
virtual unsigned int offset284(int) {
return offset = 284;
}
virtual unsigned int offset285(int) {
return offset = 285;
}
virtual unsigned int offset286(int) {
return offset = 286;
}
virtual unsigned int offset287(int) {
return offset = 287;
}
virtual unsigned int offset288(int) {
return offset = 288;
}
virtual unsigned int offset289(int) {
return offset = 289;
}
virtual unsigned int offset290(int) {
return offset = 290;
}
virtual unsigned int offset291(int) {
return offset = 291;
}
virtual unsigned int offset292(int) {
return offset = 292;
}
virtual unsigned int offset293(int) {
return offset = 293;
}
virtual unsigned int offset294(int) {
return offset = 294;
}
virtual unsigned int offset295(int) {
return offset = 295;
}
virtual unsigned int offset296(int) {
return offset = 296;
}
virtual unsigned int offset297(int) {
return offset = 297;
}
virtual unsigned int offset298(int) {
return offset = 298;
}
virtual unsigned int offset299(int) {
return offset = 299;
}
virtual unsigned int offset300(int) {
return offset = 300;
}
virtual unsigned int offset301(int) {
return offset = 301;
}
virtual unsigned int offset302(int) {
return offset = 302;
}
virtual unsigned int offset303(int) {
return offset = 303;
}
virtual unsigned int offset304(int) {
return offset = 304;
}
virtual unsigned int offset305(int) {
return offset = 305;
}
virtual unsigned int offset306(int) {
return offset = 306;
}
virtual unsigned int offset307(int) {
return offset = 307;
}
virtual unsigned int offset308(int) {
return offset = 308;
}
virtual unsigned int offset309(int) {
return offset = 309;
}
virtual unsigned int offset310(int) {
return offset = 310;
}
virtual unsigned int offset311(int) {
return offset = 311;
}
virtual unsigned int offset312(int) {
return offset = 312;
}
virtual unsigned int offset313(int) {
return offset = 313;
}
virtual unsigned int offset314(int) {
return offset = 314;
}
virtual unsigned int offset315(int) {
return offset = 315;
}
virtual unsigned int offset316(int) {
return offset = 316;
}
virtual unsigned int offset317(int) {
return offset = 317;
}
virtual unsigned int offset318(int) {
return offset = 318;
}
virtual unsigned int offset319(int) {
return offset = 319;
}
virtual unsigned int offset320(int) {
return offset = 320;
}
virtual unsigned int offset321(int) {
return offset = 321;
}
virtual unsigned int offset322(int) {
return offset = 322;
}
virtual unsigned int offset323(int) {
return offset = 323;
}
virtual unsigned int offset324(int) {
return offset = 324;
}
virtual unsigned int offset325(int) {
return offset = 325;
}
virtual unsigned int offset326(int) {
return offset = 326;
}
virtual unsigned int offset327(int) {
return offset = 327;
}
virtual unsigned int offset328(int) {
return offset = 328;
}
virtual unsigned int offset329(int) {
return offset = 329;
}
virtual unsigned int offset330(int) {
return offset = 330;
}
virtual unsigned int offset331(int) {
return offset = 331;
}
virtual unsigned int offset332(int) {
return offset = 332;
}
virtual unsigned int offset333(int) {
return offset = 333;
}
virtual unsigned int offset334(int) {
return offset = 334;
}
virtual unsigned int offset335(int) {
return offset = 335;
}
virtual unsigned int offset336(int) {
return offset = 336;
}
virtual unsigned int offset337(int) {
return offset = 337;
}
virtual unsigned int offset338(int) {
return offset = 338;
}
virtual unsigned int offset339(int) {
return offset = 339;
}
virtual unsigned int offset340(int) {
return offset = 340;
}
virtual unsigned int offset341(int) {
return offset = 341;
}
virtual unsigned int offset342(int) {
return offset = 342;
}
virtual unsigned int offset343(int) {
return offset = 343;
}
virtual unsigned int offset344(int) {
return offset = 344;
}
virtual unsigned int offset345(int) {
return offset = 345;
}
virtual unsigned int offset346(int) {
return offset = 346;
}
virtual unsigned int offset347(int) {
return offset = 347;
}
virtual unsigned int offset348(int) {
return offset = 348;
}
virtual unsigned int offset349(int) {
return offset = 349;
}
virtual unsigned int offset350(int) {
return offset = 350;
}
virtual unsigned int offset351(int) {
return offset = 351;
}
virtual unsigned int offset352(int) {
return offset = 352;
}
virtual unsigned int offset353(int) {
return offset = 353;
}
virtual unsigned int offset354(int) {
return offset = 354;
}
virtual unsigned int offset355(int) {
return offset = 355;
}
virtual unsigned int offset356(int) {
return offset = 356;
}
virtual unsigned int offset357(int) {
return offset = 357;
}
virtual unsigned int offset358(int) {
return offset = 358;
}
virtual unsigned int offset359(int) {
return offset = 359;
}
virtual unsigned int offset360(int) {
return offset = 360;
}
virtual unsigned int offset361(int) {
return offset = 361;
}
virtual unsigned int offset362(int) {
return offset = 362;
}
virtual unsigned int offset363(int) {
return offset = 363;
}
virtual unsigned int offset364(int) {
return offset = 364;
}
virtual unsigned int offset365(int) {
return offset = 365;
}
virtual unsigned int offset366(int) {
return offset = 366;
}
virtual unsigned int offset367(int) {
return offset = 367;
}
virtual unsigned int offset368(int) {
return offset = 368;
}
virtual unsigned int offset369(int) {
return offset = 369;
}
virtual unsigned int offset370(int) {
return offset = 370;
}
virtual unsigned int offset371(int) {
return offset = 371;
}
virtual unsigned int offset372(int) {
return offset = 372;
}
virtual unsigned int offset373(int) {
return offset = 373;
}
virtual unsigned int offset374(int) {
return offset = 374;
}
virtual unsigned int offset375(int) {
return offset = 375;
}
virtual unsigned int offset376(int) {
return offset = 376;
}
virtual unsigned int offset377(int) {
return offset = 377;
}
virtual unsigned int offset378(int) {
return offset = 378;
}
virtual unsigned int offset379(int) {
return offset = 379;
}
virtual unsigned int offset380(int) {
return offset = 380;
}
virtual unsigned int offset381(int) {
return offset = 381;
}
virtual unsigned int offset382(int) {
return offset = 382;
}
virtual unsigned int offset383(int) {
return offset = 383;
}
virtual unsigned int offset384(int) {
return offset = 384;
}
virtual unsigned int offset385(int) {
return offset = 385;
}
virtual unsigned int offset386(int) {
return offset = 386;
}
virtual unsigned int offset387(int) {
return offset = 387;
}
virtual unsigned int offset388(int) {
return offset = 388;
}
virtual unsigned int offset389(int) {
return offset = 389;
}
virtual unsigned int offset390(int) {
return offset = 390;
}
virtual unsigned int offset391(int) {
return offset = 391;
}
virtual unsigned int offset392(int) {
return offset = 392;
}
virtual unsigned int offset393(int) {
return offset = 393;
}
virtual unsigned int offset394(int) {
return offset = 394;
}
virtual unsigned int offset395(int) {
return offset = 395;
}
virtual unsigned int offset396(int) {
return offset = 396;
}
virtual unsigned int offset397(int) {
return offset = 397;
}
virtual unsigned int offset398(int) {
return offset = 398;
}
virtual unsigned int offset399(int) {
return offset = 399;
}
virtual unsigned int offset400(int) {
return offset = 400;
}
virtual unsigned int offset401(int) {
return offset = 401;
}
virtual unsigned int offset402(int) {
return offset = 402;
}
virtual unsigned int offset403(int) {
return offset = 403;
}
virtual unsigned int offset404(int) {
return offset = 404;
}
virtual unsigned int offset405(int) {
return offset = 405;
}
virtual unsigned int offset406(int) {
return offset = 406;
}
virtual unsigned int offset407(int) {
return offset = 407;
}
virtual unsigned int offset408(int) {
return offset = 408;
}
virtual unsigned int offset409(int) {
return offset = 409;
}
virtual unsigned int offset410(int) {
return offset = 410;
}
virtual unsigned int offset411(int) {
return offset = 411;
}
virtual unsigned int offset412(int) {
return offset = 412;
}
virtual unsigned int offset413(int) {
return offset = 413;
}
virtual unsigned int offset414(int) {
return offset = 414;
}
virtual unsigned int offset415(int) {
return offset = 415;
}
virtual unsigned int offset416(int) {
return offset = 416;
}
virtual unsigned int offset417(int) {
return offset = 417;
}
virtual unsigned int offset418(int) {
return offset = 418;
}
virtual unsigned int offset419(int) {
return offset = 419;
}
virtual unsigned int offset420(int) {
return offset = 420;
}
virtual unsigned int offset421(int) {
return offset = 421;
}
virtual unsigned int offset422(int) {
return offset = 422;
}
virtual unsigned int offset423(int) {
return offset = 423;
}
virtual unsigned int offset424(int) {
return offset = 424;
}
virtual unsigned int offset425(int) {
return offset = 425;
}
virtual unsigned int offset426(int) {
return offset = 426;
}
virtual unsigned int offset427(int) {
return offset = 427;
}
virtual unsigned int offset428(int) {
return offset = 428;
}
virtual unsigned int offset429(int) {
return offset = 429;
}
virtual unsigned int offset430(int) {
return offset = 430;
}
virtual unsigned int offset431(int) {
return offset = 431;
}
virtual unsigned int offset432(int) {
return offset = 432;
}
virtual unsigned int offset433(int) {
return offset = 433;
}
virtual unsigned int offset434(int) {
return offset = 434;
}
virtual unsigned int offset435(int) {
return offset = 435;
}
virtual unsigned int offset436(int) {
return offset = 436;
}
virtual unsigned int offset437(int) {
return offset = 437;
}
virtual unsigned int offset438(int) {
return offset = 438;
}
virtual unsigned int offset439(int) {
return offset = 439;
}
virtual unsigned int offset440(int) {
return offset = 440;
}
virtual unsigned int offset441(int) {
return offset = 441;
}
virtual unsigned int offset442(int) {
return offset = 442;
}
virtual unsigned int offset443(int) {
return offset = 443;
}
virtual unsigned int offset444(int) {
return offset = 444;
}
virtual unsigned int offset445(int) {
return offset = 445;
}
virtual unsigned int offset446(int) {
return offset = 446;
}
virtual unsigned int offset447(int) {
return offset = 447;
}
virtual unsigned int offset448(int) {
return offset = 448;
}
virtual unsigned int offset449(int) {
return offset = 449;
}
virtual unsigned int offset450(int) {
return offset = 450;
}
virtual unsigned int offset451(int) {
return offset = 451;
}
virtual unsigned int offset452(int) {
return offset = 452;
}
virtual unsigned int offset453(int) {
return offset = 453;
}
virtual unsigned int offset454(int) {
return offset = 454;
}
virtual unsigned int offset455(int) {
return offset = 455;
}
virtual unsigned int offset456(int) {
return offset = 456;
}
virtual unsigned int offset457(int) {
return offset = 457;
}
virtual unsigned int offset458(int) {
return offset = 458;
}
virtual unsigned int offset459(int) {
return offset = 459;
}
virtual unsigned int offset460(int) {
return offset = 460;
}
virtual unsigned int offset461(int) {
return offset = 461;
}
virtual unsigned int offset462(int) {
return offset = 462;
}
virtual unsigned int offset463(int) {
return offset = 463;
}
virtual unsigned int offset464(int) {
return offset = 464;
}
virtual unsigned int offset465(int) {
return offset = 465;
}
virtual unsigned int offset466(int) {
return offset = 466;
}
virtual unsigned int offset467(int) {
return offset = 467;
}
virtual unsigned int offset468(int) {
return offset = 468;
}
virtual unsigned int offset469(int) {
return offset = 469;
}
virtual unsigned int offset470(int) {
return offset = 470;
}
virtual unsigned int offset471(int) {
return offset = 471;
}
virtual unsigned int offset472(int) {
return offset = 472;
}
virtual unsigned int offset473(int) {
return offset = 473;
}
virtual unsigned int offset474(int) {
return offset = 474;
}
virtual unsigned int offset475(int) {
return offset = 475;
}
virtual unsigned int offset476(int) {
return offset = 476;
}
virtual unsigned int offset477(int) {
return offset = 477;
}
virtual unsigned int offset478(int) {
return offset = 478;
}
virtual unsigned int offset479(int) {
return offset = 479;
}
virtual unsigned int offset480(int) {
return offset = 480;
}
virtual unsigned int offset481(int) {
return offset = 481;
}
virtual unsigned int offset482(int) {
return offset = 482;
}
virtual unsigned int offset483(int) {
return offset = 483;
}
virtual unsigned int offset484(int) {
return offset = 484;
}
virtual unsigned int offset485(int) {
return offset = 485;
}
virtual unsigned int offset486(int) {
return offset = 486;
}
virtual unsigned int offset487(int) {
return offset = 487;
}
virtual unsigned int offset488(int) {
return offset = 488;
}
virtual unsigned int offset489(int) {
return offset = 489;
}
virtual unsigned int offset490(int) {
return offset = 490;
}
virtual unsigned int offset491(int) {
return offset = 491;
}
virtual unsigned int offset492(int) {
return offset = 492;
}
virtual unsigned int offset493(int) {
return offset = 493;
}
virtual unsigned int offset494(int) {
return offset = 494;
}
virtual unsigned int offset495(int) {
return offset = 495;
}
virtual unsigned int offset496(int) {
return offset = 496;
}
virtual unsigned int offset497(int) {
return offset = 497;
}
virtual unsigned int offset498(int) {
return offset = 498;
}
virtual unsigned int offset499(int) {
return offset = 499;
}
virtual unsigned int offset500(int) {
return offset = 500;
}
virtual unsigned int offset501(int) {
return offset = 501;
}
virtual unsigned int offset502(int) {
return offset = 502;
}
virtual unsigned int offset503(int) {
return offset = 503;
}
virtual unsigned int offset504(int) {
return offset = 504;
}
virtual unsigned int offset505(int) {
return offset = 505;
}
virtual unsigned int offset506(int) {
return offset = 506;
}
virtual unsigned int offset507(int) {
return offset = 507;
}
virtual unsigned int offset508(int) {
return offset = 508;
}
virtual unsigned int offset509(int) {
return offset = 509;
}
virtual unsigned int offset510(int) {
return offset = 510;
}
virtual unsigned int offset511(int) {
return offset = 511;
}
virtual unsigned int offset512(int) {
return offset = 512;
}
virtual unsigned int offset513(int) {
return offset = 513;
}
virtual unsigned int offset514(int) {
return offset = 514;
}
virtual unsigned int offset515(int) {
return offset = 515;
}
virtual unsigned int offset516(int) {
return offset = 516;
}
virtual unsigned int offset517(int) {
return offset = 517;
}
virtual unsigned int offset518(int) {
return offset = 518;
}
virtual unsigned int offset519(int) {
return offset = 519;
}
virtual unsigned int offset520(int) {
return offset = 520;
}
virtual unsigned int offset521(int) {
return offset = 521;
}
virtual unsigned int offset522(int) {
return offset = 522;
}
virtual unsigned int offset523(int) {
return offset = 523;
}
virtual unsigned int offset524(int) {
return offset = 524;
}
virtual unsigned int offset525(int) {
return offset = 525;
}
virtual unsigned int offset526(int) {
return offset = 526;
}
virtual unsigned int offset527(int) {
return offset = 527;
}
virtual unsigned int offset528(int) {
return offset = 528;
}
virtual unsigned int offset529(int) {
return offset = 529;
}
virtual unsigned int offset530(int) {
return offset = 530;
}
virtual unsigned int offset531(int) {
return offset = 531;
}
virtual unsigned int offset532(int) {
return offset = 532;
}
virtual unsigned int offset533(int) {
return offset = 533;
}
virtual unsigned int offset534(int) {
return offset = 534;
}
virtual unsigned int offset535(int) {
return offset = 535;
}
virtual unsigned int offset536(int) {
return offset = 536;
}
virtual unsigned int offset537(int) {
return offset = 537;
}
virtual unsigned int offset538(int) {
return offset = 538;
}
virtual unsigned int offset539(int) {
return offset = 539;
}
virtual unsigned int offset540(int) {
return offset = 540;
}
virtual unsigned int offset541(int) {
return offset = 541;
}
virtual unsigned int offset542(int) {
return offset = 542;
}
virtual unsigned int offset543(int) {
return offset = 543;
}
virtual unsigned int offset544(int) {
return offset = 544;
}
virtual unsigned int offset545(int) {
return offset = 545;
}
virtual unsigned int offset546(int) {
return offset = 546;
}
virtual unsigned int offset547(int) {
return offset = 547;
}
virtual unsigned int offset548(int) {
return offset = 548;
}
virtual unsigned int offset549(int) {
return offset = 549;
}
virtual unsigned int offset550(int) {
return offset = 550;
}
virtual unsigned int offset551(int) {
return offset = 551;
}
virtual unsigned int offset552(int) {
return offset = 552;
}
virtual unsigned int offset553(int) {
return offset = 553;
}
virtual unsigned int offset554(int) {
return offset = 554;
}
virtual unsigned int offset555(int) {
return offset = 555;
}
virtual unsigned int offset556(int) {
return offset = 556;
}
virtual unsigned int offset557(int) {
return offset = 557;
}
virtual unsigned int offset558(int) {
return offset = 558;
}
virtual unsigned int offset559(int) {
return offset = 559;
}
virtual unsigned int offset560(int) {
return offset = 560;
}
virtual unsigned int offset561(int) {
return offset = 561;
}
virtual unsigned int offset562(int) {
return offset = 562;
}
virtual unsigned int offset563(int) {
return offset = 563;
}
virtual unsigned int offset564(int) {
return offset = 564;
}
virtual unsigned int offset565(int) {
return offset = 565;
}
virtual unsigned int offset566(int) {
return offset = 566;
}
virtual unsigned int offset567(int) {
return offset = 567;
}
virtual unsigned int offset568(int) {
return offset = 568;
}
virtual unsigned int offset569(int) {
return offset = 569;
}
virtual unsigned int offset570(int) {
return offset = 570;
}
virtual unsigned int offset571(int) {
return offset = 571;
}
virtual unsigned int offset572(int) {
return offset = 572;
}
virtual unsigned int offset573(int) {
return offset = 573;
}
virtual unsigned int offset574(int) {
return offset = 574;
}
virtual unsigned int offset575(int) {
return offset = 575;
}
virtual unsigned int offset576(int) {
return offset = 576;
}
virtual unsigned int offset577(int) {
return offset = 577;
}
virtual unsigned int offset578(int) {
return offset = 578;
}
virtual unsigned int offset579(int) {
return offset = 579;
}
virtual unsigned int offset580(int) {
return offset = 580;
}
virtual unsigned int offset581(int) {
return offset = 581;
}
virtual unsigned int offset582(int) {
return offset = 582;
}
virtual unsigned int offset583(int) {
return offset = 583;
}
virtual unsigned int offset584(int) {
return offset = 584;
}
virtual unsigned int offset585(int) {
return offset = 585;
}
virtual unsigned int offset586(int) {
return offset = 586;
}
virtual unsigned int offset587(int) {
return offset = 587;
}
virtual unsigned int offset588(int) {
return offset = 588;
}
virtual unsigned int offset589(int) {
return offset = 589;
}
virtual unsigned int offset590(int) {
return offset = 590;
}
virtual unsigned int offset591(int) {
return offset = 591;
}
virtual unsigned int offset592(int) {
return offset = 592;
}
virtual unsigned int offset593(int) {
return offset = 593;
}
virtual unsigned int offset594(int) {
return offset = 594;
}
virtual unsigned int offset595(int) {
return offset = 595;
}
virtual unsigned int offset596(int) {
return offset = 596;
}
virtual unsigned int offset597(int) {
return offset = 597;
}
virtual unsigned int offset598(int) {
return offset = 598;
}
virtual unsigned int offset599(int) {
return offset = 599;
}
virtual unsigned int offset600(int) {
return offset = 600;
}
virtual unsigned int offset601(int) {
return offset = 601;
}
virtual unsigned int offset602(int) {
return offset = 602;
}
virtual unsigned int offset603(int) {
return offset = 603;
}
virtual unsigned int offset604(int) {
return offset = 604;
}
virtual unsigned int offset605(int) {
return offset = 605;
}
virtual unsigned int offset606(int) {
return offset = 606;
}
virtual unsigned int offset607(int) {
return offset = 607;
}
virtual unsigned int offset608(int) {
return offset = 608;
}
virtual unsigned int offset609(int) {
return offset = 609;
}
virtual unsigned int offset610(int) {
return offset = 610;
}
virtual unsigned int offset611(int) {
return offset = 611;
}
virtual unsigned int offset612(int) {
return offset = 612;
}
virtual unsigned int offset613(int) {
return offset = 613;
}
virtual unsigned int offset614(int) {
return offset = 614;
}
virtual unsigned int offset615(int) {
return offset = 615;
}
virtual unsigned int offset616(int) {
return offset = 616;
}
virtual unsigned int offset617(int) {
return offset = 617;
}
virtual unsigned int offset618(int) {
return offset = 618;
}
virtual unsigned int offset619(int) {
return offset = 619;
}
virtual unsigned int offset620(int) {
return offset = 620;
}
virtual unsigned int offset621(int) {
return offset = 621;
}
virtual unsigned int offset622(int) {
return offset = 622;
}
virtual unsigned int offset623(int) {
return offset = 623;
}
virtual unsigned int offset624(int) {
return offset = 624;
}
virtual unsigned int offset625(int) {
return offset = 625;
}
virtual unsigned int offset626(int) {
return offset = 626;
}
virtual unsigned int offset627(int) {
return offset = 627;
}
virtual unsigned int offset628(int) {
return offset = 628;
}
virtual unsigned int offset629(int) {
return offset = 629;
}
virtual unsigned int offset630(int) {
return offset = 630;
}
virtual unsigned int offset631(int) {
return offset = 631;
}
virtual unsigned int offset632(int) {
return offset = 632;
}
virtual unsigned int offset633(int) {
return offset = 633;
}
virtual unsigned int offset634(int) {
return offset = 634;
}
virtual unsigned int offset635(int) {
return offset = 635;
}
virtual unsigned int offset636(int) {
return offset = 636;
}
virtual unsigned int offset637(int) {
return offset = 637;
}
virtual unsigned int offset638(int) {
return offset = 638;
}
virtual unsigned int offset639(int) {
return offset = 639;
}
virtual unsigned int offset640(int) {
return offset = 640;
}
virtual unsigned int offset641(int) {
return offset = 641;
}
virtual unsigned int offset642(int) {
return offset = 642;
}
virtual unsigned int offset643(int) {
return offset = 643;
}
virtual unsigned int offset644(int) {
return offset = 644;
}
virtual unsigned int offset645(int) {
return offset = 645;
}
virtual unsigned int offset646(int) {
return offset = 646;
}
virtual unsigned int offset647(int) {
return offset = 647;
}
virtual unsigned int offset648(int) {
return offset = 648;
}
virtual unsigned int offset649(int) {
return offset = 649;
}
virtual unsigned int offset650(int) {
return offset = 650;
}
virtual unsigned int offset651(int) {
return offset = 651;
}
virtual unsigned int offset652(int) {
return offset = 652;
}
virtual unsigned int offset653(int) {
return offset = 653;
}
virtual unsigned int offset654(int) {
return offset = 654;
}
virtual unsigned int offset655(int) {
return offset = 655;
}
virtual unsigned int offset656(int) {
return offset = 656;
}
virtual unsigned int offset657(int) {
return offset = 657;
}
virtual unsigned int offset658(int) {
return offset = 658;
}
virtual unsigned int offset659(int) {
return offset = 659;
}
virtual unsigned int offset660(int) {
return offset = 660;
}
virtual unsigned int offset661(int) {
return offset = 661;
}
virtual unsigned int offset662(int) {
return offset = 662;
}
virtual unsigned int offset663(int) {
return offset = 663;
}
virtual unsigned int offset664(int) {
return offset = 664;
}
virtual unsigned int offset665(int) {
return offset = 665;
}
virtual unsigned int offset666(int) {
return offset = 666;
}
virtual unsigned int offset667(int) {
return offset = 667;
}
virtual unsigned int offset668(int) {
return offset = 668;
}
virtual unsigned int offset669(int) {
return offset = 669;
}
virtual unsigned int offset670(int) {
return offset = 670;
}
virtual unsigned int offset671(int) {
return offset = 671;
}
virtual unsigned int offset672(int) {
return offset = 672;
}
virtual unsigned int offset673(int) {
return offset = 673;
}
virtual unsigned int offset674(int) {
return offset = 674;
}
virtual unsigned int offset675(int) {
return offset = 675;
}
virtual unsigned int offset676(int) {
return offset = 676;
}
virtual unsigned int offset677(int) {
return offset = 677;
}
virtual unsigned int offset678(int) {
return offset = 678;
}
virtual unsigned int offset679(int) {
return offset = 679;
}
virtual unsigned int offset680(int) {
return offset = 680;
}
virtual unsigned int offset681(int) {
return offset = 681;
}
virtual unsigned int offset682(int) {
return offset = 682;
}
virtual unsigned int offset683(int) {
return offset = 683;
}
virtual unsigned int offset684(int) {
return offset = 684;
}
virtual unsigned int offset685(int) {
return offset = 685;
}
virtual unsigned int offset686(int) {
return offset = 686;
}
virtual unsigned int offset687(int) {
return offset = 687;
}
virtual unsigned int offset688(int) {
return offset = 688;
}
virtual unsigned int offset689(int) {
return offset = 689;
}
virtual unsigned int offset690(int) {
return offset = 690;
}
virtual unsigned int offset691(int) {
return offset = 691;
}
virtual unsigned int offset692(int) {
return offset = 692;
}
virtual unsigned int offset693(int) {
return offset = 693;
}
virtual unsigned int offset694(int) {
return offset = 694;
}
virtual unsigned int offset695(int) {
return offset = 695;
}
virtual unsigned int offset696(int) {
return offset = 696;
}
virtual unsigned int offset697(int) {
return offset = 697;
}
virtual unsigned int offset698(int) {
return offset = 698;
}
virtual unsigned int offset699(int) {
return offset = 699;
}
virtual unsigned int offset700(int) {
return offset = 700;
}
virtual unsigned int offset701(int) {
return offset = 701;
}
virtual unsigned int offset702(int) {
return offset = 702;
}
virtual unsigned int offset703(int) {
return offset = 703;
}
virtual unsigned int offset704(int) {
return offset = 704;
}
virtual unsigned int offset705(int) {
return offset = 705;
}
virtual unsigned int offset706(int) {
return offset = 706;
}
virtual unsigned int offset707(int) {
return offset = 707;
}
virtual unsigned int offset708(int) {
return offset = 708;
}
virtual unsigned int offset709(int) {
return offset = 709;
}
virtual unsigned int offset710(int) {
return offset = 710;
}
virtual unsigned int offset711(int) {
return offset = 711;
}
virtual unsigned int offset712(int) {
return offset = 712;
}
virtual unsigned int offset713(int) {
return offset = 713;
}
virtual unsigned int offset714(int) {
return offset = 714;
}
virtual unsigned int offset715(int) {
return offset = 715;
}
virtual unsigned int offset716(int) {
return offset = 716;
}
virtual unsigned int offset717(int) {
return offset = 717;
}
virtual unsigned int offset718(int) {
return offset = 718;
}
virtual unsigned int offset719(int) {
return offset = 719;
}
virtual unsigned int offset720(int) {
return offset = 720;
}
virtual unsigned int offset721(int) {
return offset = 721;
}
virtual unsigned int offset722(int) {
return offset = 722;
}
virtual unsigned int offset723(int) {
return offset = 723;
}
virtual unsigned int offset724(int) {
return offset = 724;
}
virtual unsigned int offset725(int) {
return offset = 725;
}
virtual unsigned int offset726(int) {
return offset = 726;
}
virtual unsigned int offset727(int) {
return offset = 727;
}
virtual unsigned int offset728(int) {
return offset = 728;
}
virtual unsigned int offset729(int) {
return offset = 729;
}
virtual unsigned int offset730(int) {
return offset = 730;
}
virtual unsigned int offset731(int) {
return offset = 731;
}
virtual unsigned int offset732(int) {
return offset = 732;
}
virtual unsigned int offset733(int) {
return offset = 733;
}
virtual unsigned int offset734(int) {
return offset = 734;
}
virtual unsigned int offset735(int) {
return offset = 735;
}
virtual unsigned int offset736(int) {
return offset = 736;
}
virtual unsigned int offset737(int) {
return offset = 737;
}
virtual unsigned int offset738(int) {
return offset = 738;
}
virtual unsigned int offset739(int) {
return offset = 739;
}
virtual unsigned int offset740(int) {
return offset = 740;
}
virtual unsigned int offset741(int) {
return offset = 741;
}
virtual unsigned int offset742(int) {
return offset = 742;
}
virtual unsigned int offset743(int) {
return offset = 743;
}
virtual unsigned int offset744(int) {
return offset = 744;
}
virtual unsigned int offset745(int) {
return offset = 745;
}
virtual unsigned int offset746(int) {
return offset = 746;
}
virtual unsigned int offset747(int) {
return offset = 747;
}
virtual unsigned int offset748(int) {
return offset = 748;
}
virtual unsigned int offset749(int) {
return offset = 749;
}
virtual unsigned int offset750(int) {
return offset = 750;
}
virtual unsigned int offset751(int) {
return offset = 751;
}
virtual unsigned int offset752(int) {
return offset = 752;
}
virtual unsigned int offset753(int) {
return offset = 753;
}
virtual unsigned int offset754(int) {
return offset = 754;
}
virtual unsigned int offset755(int) {
return offset = 755;
}
virtual unsigned int offset756(int) {
return offset = 756;
}
virtual unsigned int offset757(int) {
return offset = 757;
}
virtual unsigned int offset758(int) {
return offset = 758;
}
virtual unsigned int offset759(int) {
return offset = 759;
}
virtual unsigned int offset760(int) {
return offset = 760;
}
virtual unsigned int offset761(int) {
return offset = 761;
}
virtual unsigned int offset762(int) {
return offset = 762;
}
virtual unsigned int offset763(int) {
return offset = 763;
}
virtual unsigned int offset764(int) {
return offset = 764;
}
virtual unsigned int offset765(int) {
return offset = 765;
}
virtual unsigned int offset766(int) {
return offset = 766;
}
virtual unsigned int offset767(int) {
return offset = 767;
}
virtual unsigned int offset768(int) {
return offset = 768;
}
virtual unsigned int offset769(int) {
return offset = 769;
}
virtual unsigned int offset770(int) {
return offset = 770;
}
virtual unsigned int offset771(int) {
return offset = 771;
}
virtual unsigned int offset772(int) {
return offset = 772;
}
virtual unsigned int offset773(int) {
return offset = 773;
}
virtual unsigned int offset774(int) {
return offset = 774;
}
virtual unsigned int offset775(int) {
return offset = 775;
}
virtual unsigned int offset776(int) {
return offset = 776;
}
virtual unsigned int offset777(int) {
return offset = 777;
}
virtual unsigned int offset778(int) {
return offset = 778;
}
virtual unsigned int offset779(int) {
return offset = 779;
}
virtual unsigned int offset780(int) {
return offset = 780;
}
virtual unsigned int offset781(int) {
return offset = 781;
}
virtual unsigned int offset782(int) {
return offset = 782;
}
virtual unsigned int offset783(int) {
return offset = 783;
}
virtual unsigned int offset784(int) {
return offset = 784;
}
virtual unsigned int offset785(int) {
return offset = 785;
}
virtual unsigned int offset786(int) {
return offset = 786;
}
virtual unsigned int offset787(int) {
return offset = 787;
}
virtual unsigned int offset788(int) {
return offset = 788;
}
virtual unsigned int offset789(int) {
return offset = 789;
}
virtual unsigned int offset790(int) {
return offset = 790;
}
virtual unsigned int offset791(int) {
return offset = 791;
}
virtual unsigned int offset792(int) {
return offset = 792;
}
virtual unsigned int offset793(int) {
return offset = 793;
}
virtual unsigned int offset794(int) {
return offset = 794;
}
virtual unsigned int offset795(int) {
return offset = 795;
}
virtual unsigned int offset796(int) {
return offset = 796;
}
virtual unsigned int offset797(int) {
return offset = 797;
}
virtual unsigned int offset798(int) {
return offset = 798;
}
virtual unsigned int offset799(int) {
return offset = 799;
}
virtual unsigned int offset800(int) {
return offset = 800;
}
virtual unsigned int offset801(int) {
return offset = 801;
}
virtual unsigned int offset802(int) {
return offset = 802;
}
virtual unsigned int offset803(int) {
return offset = 803;
}
virtual unsigned int offset804(int) {
return offset = 804;
}
virtual unsigned int offset805(int) {
return offset = 805;
}
virtual unsigned int offset806(int) {
return offset = 806;
}
virtual unsigned int offset807(int) {
return offset = 807;
}
virtual unsigned int offset808(int) {
return offset = 808;
}
virtual unsigned int offset809(int) {
return offset = 809;
}
virtual unsigned int offset810(int) {
return offset = 810;
}
virtual unsigned int offset811(int) {
return offset = 811;
}
virtual unsigned int offset812(int) {
return offset = 812;
}
virtual unsigned int offset813(int) {
return offset = 813;
}
virtual unsigned int offset814(int) {
return offset = 814;
}
virtual unsigned int offset815(int) {
return offset = 815;
}
virtual unsigned int offset816(int) {
return offset = 816;
}
virtual unsigned int offset817(int) {
return offset = 817;
}
virtual unsigned int offset818(int) {
return offset = 818;
}
virtual unsigned int offset819(int) {
return offset = 819;
}
virtual unsigned int offset820(int) {
return offset = 820;
}
virtual unsigned int offset821(int) {
return offset = 821;
}
virtual unsigned int offset822(int) {
return offset = 822;
}
virtual unsigned int offset823(int) {
return offset = 823;
}
virtual unsigned int offset824(int) {
return offset = 824;
}
virtual unsigned int offset825(int) {
return offset = 825;
}
virtual unsigned int offset826(int) {
return offset = 826;
}
virtual unsigned int offset827(int) {
return offset = 827;
}
virtual unsigned int offset828(int) {
return offset = 828;
}
virtual unsigned int offset829(int) {
return offset = 829;
}
virtual unsigned int offset830(int) {
return offset = 830;
}
virtual unsigned int offset831(int) {
return offset = 831;
}
virtual unsigned int offset832(int) {
return offset = 832;
}
virtual unsigned int offset833(int) {
return offset = 833;
}
virtual unsigned int offset834(int) {
return offset = 834;
}
virtual unsigned int offset835(int) {
return offset = 835;
}
virtual unsigned int offset836(int) {
return offset = 836;
}
virtual unsigned int offset837(int) {
return offset = 837;
}
virtual unsigned int offset838(int) {
return offset = 838;
}
virtual unsigned int offset839(int) {
return offset = 839;
}
virtual unsigned int offset840(int) {
return offset = 840;
}
virtual unsigned int offset841(int) {
return offset = 841;
}
virtual unsigned int offset842(int) {
return offset = 842;
}
virtual unsigned int offset843(int) {
return offset = 843;
}
virtual unsigned int offset844(int) {
return offset = 844;
}
virtual unsigned int offset845(int) {
return offset = 845;
}
virtual unsigned int offset846(int) {
return offset = 846;
}
virtual unsigned int offset847(int) {
return offset = 847;
}
virtual unsigned int offset848(int) {
return offset = 848;
}
virtual unsigned int offset849(int) {
return offset = 849;
}
virtual unsigned int offset850(int) {
return offset = 850;
}
virtual unsigned int offset851(int) {
return offset = 851;
}
virtual unsigned int offset852(int) {
return offset = 852;
}
virtual unsigned int offset853(int) {
return offset = 853;
}
virtual unsigned int offset854(int) {
return offset = 854;
}
virtual unsigned int offset855(int) {
return offset = 855;
}
virtual unsigned int offset856(int) {
return offset = 856;
}
virtual unsigned int offset857(int) {
return offset = 857;
}
virtual unsigned int offset858(int) {
return offset = 858;
}
virtual unsigned int offset859(int) {
return offset = 859;
}
virtual unsigned int offset860(int) {
return offset = 860;
}
virtual unsigned int offset861(int) {
return offset = 861;
}
virtual unsigned int offset862(int) {
return offset = 862;
}
virtual unsigned int offset863(int) {
return offset = 863;
}
virtual unsigned int offset864(int) {
return offset = 864;
}
virtual unsigned int offset865(int) {
return offset = 865;
}
virtual unsigned int offset866(int) {
return offset = 866;
}
virtual unsigned int offset867(int) {
return offset = 867;
}
virtual unsigned int offset868(int) {
return offset = 868;
}
virtual unsigned int offset869(int) {
return offset = 869;
}
virtual unsigned int offset870(int) {
return offset = 870;
}
virtual unsigned int offset871(int) {
return offset = 871;
}
virtual unsigned int offset872(int) {
return offset = 872;
}
virtual unsigned int offset873(int) {
return offset = 873;
}
virtual unsigned int offset874(int) {
return offset = 874;
}
virtual unsigned int offset875(int) {
return offset = 875;
}
virtual unsigned int offset876(int) {
return offset = 876;
}
virtual unsigned int offset877(int) {
return offset = 877;
}
virtual unsigned int offset878(int) {
return offset = 878;
}
virtual unsigned int offset879(int) {
return offset = 879;
}
virtual unsigned int offset880(int) {
return offset = 880;
}
virtual unsigned int offset881(int) {
return offset = 881;
}
virtual unsigned int offset882(int) {
return offset = 882;
}
virtual unsigned int offset883(int) {
return offset = 883;
}
virtual unsigned int offset884(int) {
return offset = 884;
}
virtual unsigned int offset885(int) {
return offset = 885;
}
virtual unsigned int offset886(int) {
return offset = 886;
}
virtual unsigned int offset887(int) {
return offset = 887;
}
virtual unsigned int offset888(int) {
return offset = 888;
}
virtual unsigned int offset889(int) {
return offset = 889;
}
virtual unsigned int offset890(int) {
return offset = 890;
}
virtual unsigned int offset891(int) {
return offset = 891;
}
virtual unsigned int offset892(int) {
return offset = 892;
}
virtual unsigned int offset893(int) {
return offset = 893;
}
virtual unsigned int offset894(int) {
return offset = 894;
}
virtual unsigned int offset895(int) {
return offset = 895;
}
virtual unsigned int offset896(int) {
return offset = 896;
}
virtual unsigned int offset897(int) {
return offset = 897;
}
virtual unsigned int offset898(int) {
return offset = 898;
}
virtual unsigned int offset899(int) {
return offset = 899;
}
virtual unsigned int offset900(int) {
return offset = 900;
}
virtual unsigned int offset901(int) {
return offset = 901;
}
virtual unsigned int offset902(int) {
return offset = 902;
}
virtual unsigned int offset903(int) {
return offset = 903;
}
virtual unsigned int offset904(int) {
return offset = 904;
}
virtual unsigned int offset905(int) {
return offset = 905;
}
virtual unsigned int offset906(int) {
return offset = 906;
}
virtual unsigned int offset907(int) {
return offset = 907;
}
virtual unsigned int offset908(int) {
return offset = 908;
}
virtual unsigned int offset909(int) {
return offset = 909;
}
virtual unsigned int offset910(int) {
return offset = 910;
}
virtual unsigned int offset911(int) {
return offset = 911;
}
virtual unsigned int offset912(int) {
return offset = 912;
}
virtual unsigned int offset913(int) {
return offset = 913;
}
virtual unsigned int offset914(int) {
return offset = 914;
}
virtual unsigned int offset915(int) {
return offset = 915;
}
virtual unsigned int offset916(int) {
return offset = 916;
}
virtual unsigned int offset917(int) {
return offset = 917;
}
virtual unsigned int offset918(int) {
return offset = 918;
}
virtual unsigned int offset919(int) {
return offset = 919;
}
virtual unsigned int offset920(int) {
return offset = 920;
}
virtual unsigned int offset921(int) {
return offset = 921;
}
virtual unsigned int offset922(int) {
return offset = 922;
}
virtual unsigned int offset923(int) {
return offset = 923;
}
virtual unsigned int offset924(int) {
return offset = 924;
}
virtual unsigned int offset925(int) {
return offset = 925;
}
virtual unsigned int offset926(int) {
return offset = 926;
}
virtual unsigned int offset927(int) {
return offset = 927;
}
virtual unsigned int offset928(int) {
return offset = 928;
}
virtual unsigned int offset929(int) {
return offset = 929;
}
virtual unsigned int offset930(int) {
return offset = 930;
}
virtual unsigned int offset931(int) {
return offset = 931;
}
virtual unsigned int offset932(int) {
return offset = 932;
}
virtual unsigned int offset933(int) {
return offset = 933;
}
virtual unsigned int offset934(int) {
return offset = 934;
}
virtual unsigned int offset935(int) {
return offset = 935;
}
virtual unsigned int offset936(int) {
return offset = 936;
}
virtual unsigned int offset937(int) {
return offset = 937;
}
virtual unsigned int offset938(int) {
return offset = 938;
}
virtual unsigned int offset939(int) {
return offset = 939;
}
virtual unsigned int offset940(int) {
return offset = 940;
}
virtual unsigned int offset941(int) {
return offset = 941;
}
virtual unsigned int offset942(int) {
return offset = 942;
}
virtual unsigned int offset943(int) {
return offset = 943;
}
virtual unsigned int offset944(int) {
return offset = 944;
}
virtual unsigned int offset945(int) {
return offset = 945;
}
virtual unsigned int offset946(int) {
return offset = 946;
}
virtual unsigned int offset947(int) {
return offset = 947;
}
virtual unsigned int offset948(int) {
return offset = 948;
}
virtual unsigned int offset949(int) {
return offset = 949;
}
virtual unsigned int offset950(int) {
return offset = 950;
}
virtual unsigned int offset951(int) {
return offset = 951;
}
virtual unsigned int offset952(int) {
return offset = 952;
}
virtual unsigned int offset953(int) {
return offset = 953;
}
virtual unsigned int offset954(int) {
return offset = 954;
}
virtual unsigned int offset955(int) {
return offset = 955;
}
virtual unsigned int offset956(int) {
return offset = 956;
}
virtual unsigned int offset957(int) {
return offset = 957;
}
virtual unsigned int offset958(int) {
return offset = 958;
}
virtual unsigned int offset959(int) {
return offset = 959;
}
virtual unsigned int offset960(int) {
return offset = 960;
}
virtual unsigned int offset961(int) {
return offset = 961;
}
virtual unsigned int offset962(int) {
return offset = 962;
}
virtual unsigned int offset963(int) {
return offset = 963;
}
virtual unsigned int offset964(int) {
return offset = 964;
}
virtual unsigned int offset965(int) {
return offset = 965;
}
virtual unsigned int offset966(int) {
return offset = 966;
}
virtual unsigned int offset967(int) {
return offset = 967;
}
virtual unsigned int offset968(int) {
return offset = 968;
}
virtual unsigned int offset969(int) {
return offset = 969;
}
virtual unsigned int offset970(int) {
return offset = 970;
}
virtual unsigned int offset971(int) {
return offset = 971;
}
virtual unsigned int offset972(int) {
return offset = 972;
}
virtual unsigned int offset973(int) {
return offset = 973;
}
virtual unsigned int offset974(int) {
return offset = 974;
}
virtual unsigned int offset975(int) {
return offset = 975;
}
virtual unsigned int offset976(int) {
return offset = 976;
}
virtual unsigned int offset977(int) {
return offset = 977;
}
virtual unsigned int offset978(int) {
return offset = 978;
}
virtual unsigned int offset979(int) {
return offset = 979;
}
virtual unsigned int offset980(int) {
return offset = 980;
}
virtual unsigned int offset981(int) {
return offset = 981;
}
virtual unsigned int offset982(int) {
return offset = 982;
}
virtual unsigned int offset983(int) {
return offset = 983;
}
virtual unsigned int offset984(int) {
return offset = 984;
}
virtual unsigned int offset985(int) {
return offset = 985;
}
virtual unsigned int offset986(int) {
return offset = 986;
}
virtual unsigned int offset987(int) {
return offset = 987;
}
virtual unsigned int offset988(int) {
return offset = 988;
}
virtual unsigned int offset989(int) {
return offset = 989;
}
virtual unsigned int offset990(int) {
return offset = 990;
}
virtual unsigned int offset991(int) {
return offset = 991;
}
virtual unsigned int offset992(int) {
return offset = 992;
}
virtual unsigned int offset993(int) {
return offset = 993;
}
virtual unsigned int offset994(int) {
return offset = 994;
}
virtual unsigned int offset995(int) {
return offset = 995;
}
virtual unsigned int offset996(int) {
return offset = 996;
}
virtual unsigned int offset997(int) {
return offset = 997;
}
virtual unsigned int offset998(int) {
return offset = 998;
}
virtual unsigned int offset999(int) {
return offset = 999;
}
virtual unsigned int offset1000(int) {
return offset = 1000;
}
};
}
namespace fakeit {
template<typename TARGET, typename SOURCE>
TARGET union_cast(SOURCE source) {
union {
SOURCE source;
TARGET target;
} u;
u.source = source;
return u.target;
}
}
namespace fakeit {
class NoVirtualDtor {
};
class VTUtils {
public:
template<typename C, typename R, typename ... arglist>
static unsigned int getOffset(R (C::*vMethod)(arglist...)) {
auto sMethod = reinterpret_cast<unsigned int (VirtualOffsetSelector::*)(int)>(vMethod);
VirtualOffsetSelector offsetSelctor;
return (offsetSelctor.*sMethod)(0);
}
template<typename C>
static typename std::enable_if<std::has_virtual_destructor<C>::value, unsigned int>::type
getDestructorOffset() {
VirtualOffsetSelector offsetSelctor;
union_cast<C *>(&offsetSelctor)->~C();
return offsetSelctor.offset;
}
template<typename C>
static typename std::enable_if<!std::has_virtual_destructor<C>::value, unsigned int>::type
getDestructorOffset() {
throw NoVirtualDtor();
}
template<typename C>
static unsigned int getVTSize() {
struct Derrived : public C {
virtual void endOfVt() {
}
};
unsigned int vtSize = getOffset(&Derrived::endOfVt);
return vtSize;
}
};
}
#ifdef _MSC_VER
namespace fakeit {
typedef unsigned long DWORD;
struct TypeDescriptor {
TypeDescriptor() :
ptrToVTable(0), spare(0) {
int **tiVFTPtr = (int **) (&typeid(void));
int *i = (int *) tiVFTPtr[0];
char *type_info_vft_ptr = (char *) i;
ptrToVTable = type_info_vft_ptr;
}
char *ptrToVTable;
DWORD spare;
char name[8];
};
struct PMD {
int mdisp;
int pdisp;
int vdisp;
PMD() :
mdisp(0), pdisp(-1), vdisp(0) {
}
};
struct RTTIBaseClassDescriptor {
RTTIBaseClassDescriptor() :
pTypeDescriptor(nullptr), numContainedBases(0), attributes(0) {
}
const std::type_info *pTypeDescriptor;
DWORD numContainedBases;
struct PMD where;
DWORD attributes;
};
template<typename C, typename... baseclasses>
struct RTTIClassHierarchyDescriptor {
RTTIClassHierarchyDescriptor() :
signature(0),
attributes(0),
numBaseClasses(0),
pBaseClassArray(nullptr) {
pBaseClassArray = new RTTIBaseClassDescriptor *[1 + sizeof...(baseclasses)];
addBaseClass < C, baseclasses...>();
}
~RTTIClassHierarchyDescriptor() {
for (int i = 0; i < 1 + sizeof...(baseclasses); i++) {
RTTIBaseClassDescriptor *desc = pBaseClassArray[i];
delete desc;
}
delete[] pBaseClassArray;
}
DWORD signature;
DWORD attributes;
DWORD numBaseClasses;
RTTIBaseClassDescriptor **pBaseClassArray;
template<typename BaseType>
void addBaseClass() {
static_assert(std::is_base_of<BaseType, C>::value, "C must be a derived class of BaseType");
RTTIBaseClassDescriptor *desc = new RTTIBaseClassDescriptor();
desc->pTypeDescriptor = &typeid(BaseType);
pBaseClassArray[numBaseClasses] = desc;
for (unsigned int i = 0; i < numBaseClasses; i++) {
pBaseClassArray[i]->numContainedBases++;
}
numBaseClasses++;
}
template<typename head, typename B1, typename... tail>
void addBaseClass() {
static_assert(std::is_base_of<B1, head>::value, "invalid inheritance list");
addBaseClass<head>();
addBaseClass<B1, tail...>();
}
};
template<typename C, typename... baseclasses>
struct RTTICompleteObjectLocator {
#ifdef _WIN64
RTTICompleteObjectLocator(const std::type_info &unused) :
signature(0), offset(0), cdOffset(0),
typeDescriptorOffset(0), classDescriptorOffset(0)
{
}
DWORD signature;
DWORD offset;
DWORD cdOffset;
DWORD typeDescriptorOffset;
DWORD classDescriptorOffset;
#else
RTTICompleteObjectLocator(const std::type_info &info) :
signature(0), offset(0), cdOffset(0),
pTypeDescriptor(&info),
pClassDescriptor(new RTTIClassHierarchyDescriptor<C, baseclasses...>()) {
}
~RTTICompleteObjectLocator() {
delete pClassDescriptor;
}
DWORD signature;
DWORD offset;
DWORD cdOffset;
const std::type_info *pTypeDescriptor;
struct RTTIClassHierarchyDescriptor<C, baseclasses...> *pClassDescriptor;
#endif
};
struct VirtualTableBase {
static VirtualTableBase &getVTable(void *instance) {
fakeit::VirtualTableBase *vt = (fakeit::VirtualTableBase *) (instance);
return *vt;
}
VirtualTableBase(void **firstMethod) : _firstMethod(firstMethod) { }
void *getCookie(int index) {
return _firstMethod[-2 - index];
}
void setCookie(int index, void *value) {
_firstMethod[-2 - index] = value;
}
void *getMethod(unsigned int index) const {
return _firstMethod[index];
}
void setMethod(unsigned int index, void *method) {
_firstMethod[index] = method;
}
protected:
void **_firstMethod;
};
template<class C, class... baseclasses>
struct VirtualTable : public VirtualTableBase {
class Handle {
friend struct VirtualTable<C, baseclasses...>;
void **firstMethod;
Handle(void **method) : firstMethod(method) { }
public:
VirtualTable<C, baseclasses...> &restore() {
VirtualTable<C, baseclasses...> *vt = (VirtualTable<C, baseclasses...> *) this;
return *vt;
}
};
static VirtualTable<C, baseclasses...> &getVTable(C &instance) {
fakeit::VirtualTable<C, baseclasses...> *vt = (fakeit::VirtualTable<C, baseclasses...> *) (&instance);
return *vt;
}
void copyFrom(VirtualTable<C, baseclasses...> &from) {
unsigned int size = VTUtils::getVTSize<C>();
for (unsigned int i = 0; i < size; i++) {
_firstMethod[i] = from.getMethod(i);
}
}
VirtualTable() : VirtualTable(buildVTArray()) {
}
~VirtualTable() {
}
void dispose() {
_firstMethod--;
RTTICompleteObjectLocator<C, baseclasses...> *locator = (RTTICompleteObjectLocator<C, baseclasses...> *) _firstMethod[0];
delete locator;
_firstMethod -= numOfCookies;
delete[] _firstMethod;
}
unsigned int dtor(int) {
C *c = (C *) this;
C &cRef = *c;
auto vt = VirtualTable<C, baseclasses...>::getVTable(cRef);
void *dtorPtr = vt.getCookie(numOfCookies - 1);
void(*method)(C *) = reinterpret_cast<void (*)(C *)>(dtorPtr);
method(c);
return 0;
}
void setDtor(void *method) {
void *dtorPtr = union_cast<void *>(&VirtualTable<C, baseclasses...>::dtor);
unsigned int index = VTUtils::getDestructorOffset<C>();
_firstMethod[index] = dtorPtr;
setCookie(numOfCookies - 1, method);
}
unsigned int getSize() {
return VTUtils::getVTSize<C>();
}
void initAll(void *value) {
auto size = getSize();
for (unsigned int i = 0; i < size; i++) {
setMethod(i, value);
}
}
Handle createHandle() {
Handle h(_firstMethod);
return h;
}
private:
class SimpleType {
};
static_assert(sizeof(unsigned int (SimpleType::*)()) == sizeof(unsigned int (C::*)()),
"Can't mock a type with multiple inheritance or with non-polymorphic base class");
static const unsigned int numOfCookies = 3;
static void **buildVTArray() {
int vtSize = VTUtils::getVTSize<C>();
auto array = new void *[vtSize + numOfCookies + 1]{};
RTTICompleteObjectLocator<C, baseclasses...> *objectLocator = new RTTICompleteObjectLocator<C, baseclasses...>(
typeid(C));
array += numOfCookies;
array[0] = objectLocator;
array++;
return array;
}
VirtualTable(void **firstMethod) : VirtualTableBase(firstMethod) {
}
};
}
#else
#ifndef __clang__
#include <type_traits>
#include <tr2/type_traits>
namespace fakeit {
template<typename ... T1>
class has_one_base {
};
template<typename T1, typename T2, typename ... types>
class has_one_base<std::tr2::__reflection_typelist<T1, T2, types...>> : public std::false_type {
};
template<typename T1>
class has_one_base<std::tr2::__reflection_typelist<T1>>
: public has_one_base<typename std::tr2::direct_bases<T1>::type> {
};
template<>
class has_one_base<std::tr2::__reflection_typelist<>> : public std::true_type {
};
template<typename T>
class is_simple_inheritance_layout : public has_one_base<typename std::tr2::direct_bases<T>::type> {
};
}
#endif
namespace fakeit {
struct VirtualTableBase {
static VirtualTableBase &getVTable(void *instance) {
fakeit::VirtualTableBase *vt = (fakeit::VirtualTableBase *) (instance);
return *vt;
}
VirtualTableBase(void **firstMethod) : _firstMethod(firstMethod) { }
void *getCookie(int index) {
return _firstMethod[-3 - index];
}
void setCookie(int index, void *value) {
_firstMethod[-3 - index] = value;
}
void *getMethod(unsigned int index) const {
return _firstMethod[index];
}
void setMethod(unsigned int index, void *method) {
_firstMethod[index] = method;
}
protected:
void **_firstMethod;
};
template<class C, class ... baseclasses>
struct VirtualTable : public VirtualTableBase {
#ifndef __clang__
static_assert(is_simple_inheritance_layout<C>::value, "Can't mock a type with multiple inheritance");
#endif
class Handle {
friend struct VirtualTable<C, baseclasses...>;
void **firstMethod;
Handle(void **method) :
firstMethod(method) {
}
public:
VirtualTable<C, baseclasses...> &restore() {
VirtualTable<C, baseclasses...> *vt = (VirtualTable<C, baseclasses...> *) this;
return *vt;
}
};
static VirtualTable<C, baseclasses...> &getVTable(C &instance) {
fakeit::VirtualTable<C, baseclasses...> *vt = (fakeit::VirtualTable<C, baseclasses...> *) (&instance);
return *vt;
}
void copyFrom(VirtualTable<C, baseclasses...> &from) {
unsigned int size = VTUtils::getVTSize<C>();
for (size_t i = 0; i < size; ++i) {
_firstMethod[i] = from.getMethod(i);
}
}
VirtualTable() :
VirtualTable(buildVTArray()) {
}
void dispose() {
_firstMethod--;
_firstMethod--;
_firstMethod -= numOfCookies;
delete[] _firstMethod;
}
unsigned int dtor(int) {
C *c = (C *) this;
C &cRef = *c;
auto vt = VirtualTable<C, baseclasses...>::getVTable(cRef);
unsigned int index = VTUtils::getDestructorOffset<C>();
void *dtorPtr = vt.getMethod(index);
void(*method)(C *) = union_cast<void (*)(C *)>(dtorPtr);
method(c);
return 0;
}
void setDtor(void *method) {
unsigned int index = VTUtils::getDestructorOffset<C>();
void *dtorPtr = union_cast<void *>(&VirtualTable<C, baseclasses...>::dtor);
_firstMethod[index] = method;
_firstMethod[index + 1] = dtorPtr;
}
unsigned int getSize() {
return VTUtils::getVTSize<C>();
}
void initAll(void *value) {
unsigned int size = getSize();
for (unsigned int i = 0; i < size; i++) {
setMethod(i, value);
}
}
const std::type_info *getTypeId() {
return (const std::type_info *) (_firstMethod[-1]);
}
Handle createHandle() {
Handle h(_firstMethod);
return h;
}
private:
static const unsigned int numOfCookies = 2;
static void **buildVTArray() {
int size = VTUtils::getVTSize<C>();
auto array = new void *[size + 2 + numOfCookies]{};
array += numOfCookies;
array++;
array[0] = const_cast<std::type_info *>(&typeid(C));
array++;
return array;
}
VirtualTable(void **firstMethod) : VirtualTableBase(firstMethod) {
}
};
}
#endif
namespace fakeit {
struct NoMoreRecordedActionException {
};
template<typename R, typename ... arglist>
struct MethodInvocationHandler : Destructible {
virtual R handleMethodInvocation(const typename fakeit::production_arg<arglist>::type... args) = 0;
};
}
#include <new>
namespace fakeit {
#ifdef __GNUG__
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
#endif
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable : 4200 )
#endif
template<typename C, typename ... baseclasses>
class FakeObject {
VirtualTable<C, baseclasses...> vtable;
static const size_t SIZE = sizeof(C) - sizeof(VirtualTable<C, baseclasses...>);
char instanceArea[SIZE ? SIZE : 0];
FakeObject(FakeObject const &) = delete;
FakeObject &operator=(FakeObject const &) = delete;
public:
FakeObject() : vtable() {
initializeDataMembersArea();
}
~FakeObject() {
vtable.dispose();
}
void initializeDataMembersArea() {
for (size_t i = 0; i < SIZE; ++i) instanceArea[i] = (char) 0;
}
void setMethod(unsigned int index, void *method) {
vtable.setMethod(index, method);
}
VirtualTable<C, baseclasses...> &getVirtualTable() {
return vtable;
}
void setVirtualTable(VirtualTable<C, baseclasses...> &t) {
vtable = t;
}
void setDtor(void *dtor) {
vtable.setDtor(dtor);
}
};
#ifdef _MSC_VER
#pragma warning( pop )
#endif
#ifdef __GNUG__
#ifndef __clang__
#pragma GCC diagnostic pop
#endif
#endif
}
namespace fakeit {
struct MethodProxy {
MethodProxy(unsigned int id, unsigned int offset, void *vMethod) :
_id(id),
_offset(offset),
_vMethod(vMethod) {
}
unsigned int getOffset() const {
return _offset;
}
unsigned int getId() const {
return _id;
}
void *getProxy() const {
return union_cast<void *>(_vMethod);
}
private:
unsigned int _id;
unsigned int _offset;
void *_vMethod;
};
}
#include <utility>
namespace fakeit {
struct InvocationHandlerCollection {
static const unsigned int VT_COOKIE_INDEX = 0;
virtual Destructible *getInvocatoinHandlerPtrById(unsigned int index) = 0;
static InvocationHandlerCollection *getInvocationHandlerCollection(void *instance) {
VirtualTableBase &vt = VirtualTableBase::getVTable(instance);
InvocationHandlerCollection *invocationHandlerCollection = (InvocationHandlerCollection *) vt.getCookie(
InvocationHandlerCollection::VT_COOKIE_INDEX);
return invocationHandlerCollection;
}
};
template<typename R, typename ... arglist>
class MethodProxyCreator {
public:
template<unsigned int id>
MethodProxy createMethodProxy(unsigned int offset) {
return MethodProxy(id, offset, union_cast<void *>(&MethodProxyCreator::methodProxyX < id > ));
}
protected:
R methodProxy(unsigned int id, const typename fakeit::production_arg<arglist>::type... args) {
InvocationHandlerCollection *invocationHandlerCollection = InvocationHandlerCollection::getInvocationHandlerCollection(
this);
MethodInvocationHandler<R, arglist...> *invocationHandler =
(MethodInvocationHandler<R, arglist...> *) invocationHandlerCollection->getInvocatoinHandlerPtrById(
id);
return invocationHandler->handleMethodInvocation(std::forward<const typename fakeit::production_arg<arglist>::type>(args)...);
}
template<int id>
R methodProxyX(arglist ... args) {
return methodProxy(id, std::forward<const typename fakeit::production_arg<arglist>::type>(args)...);
}
};
}
namespace fakeit {
class InvocationHandlers : public InvocationHandlerCollection {
std::vector<std::shared_ptr<Destructible>> &_methodMocks;
std::vector<unsigned int> &_offsets;
unsigned int getOffset(unsigned int id) {
unsigned int offset = 0;
for (; offset < _offsets.size(); offset++) {
if (_offsets[offset] == id) {
break;
}
}
return offset;
}
public:
InvocationHandlers(
std::vector<std::shared_ptr<Destructible>> &methodMocks,
std::vector<unsigned int> &offsets) :
_methodMocks(methodMocks), _offsets(offsets) {
}
Destructible *getInvocatoinHandlerPtrById(unsigned int id) override {
unsigned int offset = getOffset(id);
std::shared_ptr<Destructible> ptr = _methodMocks[offset];
return ptr.get();
}
};
template<typename C, typename ... baseclasses>
struct DynamicProxy {
static_assert(std::is_polymorphic<C>::value, "DynamicProxy requires a polymorphic type");
DynamicProxy(C &inst) :
instance(inst),
originalVtHandle(VirtualTable<C, baseclasses...>::getVTable(instance).createHandle()),
_methodMocks(VTUtils::getVTSize<C>()),
_offsets(VTUtils::getVTSize<C>()),
_invocationHandlers(_methodMocks, _offsets) {
_cloneVt.copyFrom(originalVtHandle.restore());
_cloneVt.setCookie(InvocationHandlerCollection::VT_COOKIE_INDEX, &_invocationHandlers);
getFake().setVirtualTable(_cloneVt);
}
void detach() {
getFake().setVirtualTable(originalVtHandle.restore());
}
~DynamicProxy() {
_cloneVt.dispose();
}
C &get() {
return instance;
}
void Reset() {
_methodMocks = {{}};
_methodMocks.resize(VTUtils::getVTSize<C>());
_members = {};
_offsets = {};
_offsets.resize(VTUtils::getVTSize<C>());
_cloneVt.copyFrom(originalVtHandle.restore());
}
template<int id, typename R, typename ... arglist>
void stubMethod(R(C::*vMethod)(arglist...), MethodInvocationHandler<R, arglist...> *methodInvocationHandler) {
auto offset = VTUtils::getOffset(vMethod);
MethodProxyCreator<R, arglist...> creator;
bind(creator.template createMethodProxy<id + 1>(offset), methodInvocationHandler);
}
void stubDtor(MethodInvocationHandler<void> *methodInvocationHandler) {
auto offset = VTUtils::getDestructorOffset<C>();
MethodProxyCreator<void> creator;
bindDtor(creator.createMethodProxy<0>(offset), methodInvocationHandler);
}
template<typename R, typename ... arglist>
bool isMethodStubbed(R(C::*vMethod)(arglist...)) {
unsigned int offset = VTUtils::getOffset(vMethod);
return isBinded(offset);
}
bool isDtorStubbed() {
unsigned int offset = VTUtils::getDestructorOffset<C>();
return isBinded(offset);
}
template<typename R, typename ... arglist>
Destructible *getMethodMock(R(C::*vMethod)(arglist...)) {
auto offset = VTUtils::getOffset(vMethod);
std::shared_ptr<Destructible> ptr = _methodMocks[offset];
return ptr.get();
}
Destructible *getDtorMock() {
auto offset = VTUtils::getDestructorOffset<C>();
std::shared_ptr<Destructible> ptr = _methodMocks[offset];
return ptr.get();
}
template<typename DATA_TYPE, typename ... arglist>
void stubDataMember(DATA_TYPE C::*member, const arglist &... initargs) {
DATA_TYPE C::*theMember = (DATA_TYPE C::*) member;
C &mock = get();
DATA_TYPE *memberPtr = &(mock.*theMember);
_members.push_back(
std::shared_ptr<DataMemeberWrapper < DATA_TYPE, arglist...> >
{new DataMemeberWrapper < DATA_TYPE, arglist...>(memberPtr,
initargs...)});
}
template<typename DATA_TYPE>
void getMethodMocks(std::vector<DATA_TYPE> &into) const {
for (std::shared_ptr<Destructible> ptr : _methodMocks) {
DATA_TYPE p = dynamic_cast<DATA_TYPE>(ptr.get());
if (p) {
into.push_back(p);
}
}
}
VirtualTable<C, baseclasses...> &getOriginalVT() {
VirtualTable<C, baseclasses...> &vt = originalVtHandle.restore();
return vt;
}
private:
template<typename DATA_TYPE, typename ... arglist>
class DataMemeberWrapper : public Destructible {
private:
DATA_TYPE *dataMember;
public:
DataMemeberWrapper(DATA_TYPE *dataMem, const arglist &... initargs) :
dataMember(dataMem) {
new(dataMember) DATA_TYPE{initargs ...};
}
~DataMemeberWrapper() override
{
dataMember->~DATA_TYPE();
}
};
static_assert(sizeof(C) == sizeof(FakeObject<C, baseclasses...>), "This is a problem");
C &instance;
typename VirtualTable<C, baseclasses...>::Handle originalVtHandle;
VirtualTable<C, baseclasses...> _cloneVt;
std::vector<std::shared_ptr<Destructible>> _methodMocks;
std::vector<std::shared_ptr<Destructible>> _members;
std::vector<unsigned int> _offsets;
InvocationHandlers _invocationHandlers;
FakeObject<C, baseclasses...> &getFake() {
return reinterpret_cast<FakeObject<C, baseclasses...> &>(instance);
}
void bind(const MethodProxy &methodProxy, Destructible *invocationHandler) {
getFake().setMethod(methodProxy.getOffset(), methodProxy.getProxy());
_methodMocks[methodProxy.getOffset()].reset(invocationHandler);
_offsets[methodProxy.getOffset()] = methodProxy.getId();
}
void bindDtor(const MethodProxy &methodProxy, Destructible *invocationHandler) {
getFake().setDtor(methodProxy.getProxy());
_methodMocks[methodProxy.getOffset()].reset(invocationHandler);
_offsets[methodProxy.getOffset()] = methodProxy.getId();
}
template<typename DATA_TYPE>
DATA_TYPE getMethodMock(unsigned int offset) {
std::shared_ptr<Destructible> ptr = _methodMocks[offset];
return dynamic_cast<DATA_TYPE>(ptr.get());
}
template<typename BaseClass>
void checkMultipleInheritance() {
C *ptr = (C *) (unsigned int) 1;
BaseClass *basePtr = ptr;
int delta = (unsigned long) basePtr - (unsigned long) ptr;
if (delta > 0) {
throw std::invalid_argument(std::string("multiple inheritance is not supported"));
}
}
bool isBinded(unsigned int offset) {
std::shared_ptr<Destructible> ptr = _methodMocks[offset];
return ptr.get() != nullptr;
}
};
}
#include <functional>
#include <type_traits>
#include <memory>
#include <iosfwd>
#include <vector>
#include <functional>
#include <tuple>
#include <tuple>
namespace fakeit {
template<int N>
struct apply_func {
template<typename R, typename ... ArgsF, typename ... ArgsT, typename ... Args>
static R applyTuple(std::function<R(ArgsF &...)> f, std::tuple<ArgsT...> &t, Args &... args) {
return apply_func<N - 1>::template applyTuple(f, t, std::get<N - 1>(t), args...);
}
};
template<>
struct apply_func < 0 > {
template<typename R, typename ... ArgsF, typename ... ArgsT, typename ... Args>
static R applyTuple(std::function<R(ArgsF &...)> f, std::tuple<ArgsT...> & , Args &... args) {
return f(args...);
}
};
struct TupleDispatcher {
template<typename R, typename ... ArgsF, typename ... ArgsT>
static R applyTuple(std::function<R(ArgsF &...)> f, std::tuple<ArgsT...> &t) {
return apply_func<sizeof...(ArgsT)>::template applyTuple(f, t);
}
template<typename R, typename ...arglist>
static R invoke(std::function<R(arglist &...)> func, const std::tuple<arglist...> &arguments) {
std::tuple<arglist...> &args = const_cast<std::tuple<arglist...> &>(arguments);
return applyTuple(func, args);
}
template<typename TupleType, typename FunctionType>
static void for_each(TupleType &&, FunctionType &,
std::integral_constant<size_t, std::tuple_size<typename std::remove_reference<TupleType>::type>::value>) {
}
template<std::size_t I, typename TupleType, typename FunctionType, typename = typename std::enable_if<
I != std::tuple_size<typename std::remove_reference<TupleType>::type>::value>::type>
static void for_each(TupleType &&t, FunctionType &f, std::integral_constant<size_t, I>) {
f(I, std::get < I >(t));
for_each(std::forward < TupleType >(t), f, std::integral_constant<size_t, I + 1>());
}
template<typename TupleType, typename FunctionType>
static void for_each(TupleType &&t, FunctionType &f) {
for_each(std::forward < TupleType >(t), f, std::integral_constant<size_t, 0>());
}
template<typename TupleType1, typename TupleType2, typename FunctionType>
static void for_each(TupleType1 &&, TupleType2 &&, FunctionType &,
std::integral_constant<size_t, std::tuple_size<typename std::remove_reference<TupleType1>::type>::value>) {
}
template<std::size_t I, typename TupleType1, typename TupleType2, typename FunctionType, typename = typename std::enable_if<
I != std::tuple_size<typename std::remove_reference<TupleType1>::type>::value>::type>
static void for_each(TupleType1 &&t, TupleType2 &&t2, FunctionType &f, std::integral_constant<size_t, I>) {
f(I, std::get < I >(t), std::get < I >(t2));
for_each(std::forward < TupleType1 >(t), std::forward < TupleType2 >(t2), f, std::integral_constant<size_t, I + 1>());
}
template<typename TupleType1, typename TupleType2, typename FunctionType>
static void for_each(TupleType1 &&t, TupleType2 &&t2, FunctionType &f) {
for_each(std::forward < TupleType1 >(t), std::forward < TupleType2 >(t2), f, std::integral_constant<size_t, 0>());
}
};
}
namespace fakeit {
template<typename R, typename ... arglist>
struct ActualInvocationHandler : Destructible {
virtual R handleMethodInvocation(ArgumentsTuple<arglist...> & args) = 0;
};
}
#include <functional>
#include <tuple>
#include <string>
#include <iosfwd>
#include <type_traits>
#include <typeinfo>
namespace fakeit {
struct DefaultValueInstatiationException {
virtual ~DefaultValueInstatiationException() = default;
virtual std::string what() const = 0;
};
template<class C>
struct is_constructible_type {
static const bool value =
std::is_default_constructible<typename naked_type<C>::type>::value
&& !std::is_abstract<typename naked_type<C>::type>::value;
};
template<class C, class Enable = void>
struct DefaultValue;
template<class C>
struct DefaultValue<C, typename std::enable_if<!is_constructible_type<C>::value>::type> {
static C &value() {
if (std::is_reference<C>::value) {
typename naked_type<C>::type *ptr = nullptr;
return *ptr;
}
class Exception : public DefaultValueInstatiationException {
virtual std::string what() const
override {
return (std::string("Type ") + std::string(typeid(C).name())
+ std::string(
" is not default constructible. Could not instantiate a default return value")).c_str();
}
};
throw Exception();
}
};
template<class C>
struct DefaultValue<C, typename std::enable_if<is_constructible_type<C>::value>::type> {
static C &value() {
static typename naked_type<C>::type val{};
return val;
}
};
template<>
struct DefaultValue<void> {
static void value() {
return;
}
};
template<>
struct DefaultValue<bool> {
static bool &value() {
static bool value{false};
return value;
}
};
template<>
struct DefaultValue<char> {
static char &value() {
static char value{0};
return value;
}
};
template<>
struct DefaultValue<char16_t> {
static char16_t &value() {
static char16_t value{0};
return value;
}
};
template<>
struct DefaultValue<char32_t> {
static char32_t &value() {
static char32_t value{0};
return value;
}
};
template<>
struct DefaultValue<wchar_t> {
static wchar_t &value() {
static wchar_t value{0};
return value;
}
};
template<>
struct DefaultValue<short> {
static short &value() {
static short value{0};
return value;
}
};
template<>
struct DefaultValue<int> {
static int &value() {
static int value{0};
return value;
}
};
template<>
struct DefaultValue<long> {
static long &value() {
static long value{0};
return value;
}
};
template<>
struct DefaultValue<long long> {
static long long &value() {
static long long value{0};
return value;
}
};
template<>
struct DefaultValue<std::string> {
static std::string &value() {
static std::string value{};
return value;
}
};
}
namespace fakeit {
struct IMatcher : Destructible {
~IMatcher() = default;
virtual std::string format() const = 0;
};
template<typename T>
struct TypedMatcher : IMatcher {
virtual bool matches(const T &actual) const = 0;
};
template<typename T>
struct TypedMatcherCreator {
virtual ~TypedMatcherCreator() = default;
virtual TypedMatcher<T> *createMatcher() const = 0;
};
template<typename T>
struct ComparisonMatcherCreator : public TypedMatcherCreator<T> {
virtual ~ComparisonMatcherCreator() = default;
ComparisonMatcherCreator(const T &arg)
: _expected(arg) {
}
struct Matcher : public TypedMatcher<T> {
Matcher(const T &expected)
: _expected(expected) {
}
const T _expected;
};
const T &_expected;
};
namespace internal {
template<typename T>
struct TypedAnyMatcher : public TypedMatcherCreator<T> {
virtual ~TypedAnyMatcher() = default;
TypedAnyMatcher() {
}
struct Matcher : public TypedMatcher<T> {
virtual bool matches(const T &) const {
return true;
}
virtual std::string format() const override {
return "Any";
}
};
virtual TypedMatcher<T> *createMatcher() const override {
return new Matcher();
}
};
template<typename T>
struct EqMatcherCreator : public ComparisonMatcherCreator<T> {
virtual ~EqMatcherCreator() = default;
EqMatcherCreator(const T &expected)
: ComparisonMatcherCreator<T>(expected) {
}
struct Matcher : public ComparisonMatcherCreator<T>::Matcher {
Matcher(const T &expected)
: ComparisonMatcherCreator<T>::Matcher(expected) {
}
virtual std::string format() const override {
return TypeFormatter<T>::format(this->_expected);
}
virtual bool matches(const T &actual) const override {
return actual == this->_expected;
}
};
virtual TypedMatcher<T> *createMatcher() const {
return new Matcher(this->_expected);
}
};
template<typename T>
struct GtMatcherCreator : public ComparisonMatcherCreator<T> {
virtual ~GtMatcherCreator() = default;
GtMatcherCreator(const T &expected)
: ComparisonMatcherCreator<T>(expected) {
}
struct Matcher : public ComparisonMatcherCreator<T>::Matcher {
Matcher(const T &expected)
: ComparisonMatcherCreator<T>::Matcher(expected) {
}
virtual bool matches(const T &actual) const override {
return actual > this->_expected;
}
virtual std::string format() const override {
return std::string(">") + TypeFormatter<T>::format(this->_expected);
}
};
virtual TypedMatcher<T> *createMatcher() const override {
return new Matcher(this->_expected);
}
};
template<typename T>
struct GeMatcherCreator : public ComparisonMatcherCreator<T> {
virtual ~GeMatcherCreator() = default;
GeMatcherCreator(const T &expected)
: ComparisonMatcherCreator<T>(expected) {
}
struct Matcher : public ComparisonMatcherCreator<T>::Matcher {
Matcher(const T &expected)
: ComparisonMatcherCreator<T>::Matcher(expected) {
}
virtual bool matches(const T &actual) const override {
return actual >= this->_expected;
}
virtual std::string format() const override {
return std::string(">=") + TypeFormatter<T>::format(this->_expected);
}
};
virtual TypedMatcher<T> *createMatcher() const override {
return new Matcher(this->_expected);
}
};
template<typename T>
struct LtMatcherCreator : public ComparisonMatcherCreator<T> {
virtual ~LtMatcherCreator() = default;
LtMatcherCreator(const T &expected)
: ComparisonMatcherCreator<T>(expected) {
}
struct Matcher : public ComparisonMatcherCreator<T>::Matcher {
Matcher(const T &expected)
: ComparisonMatcherCreator<T>::Matcher(expected) {
}
virtual bool matches(const T &actual) const override {
return actual < this->_expected;
}
virtual std::string format() const override {
return std::string("<") + TypeFormatter<T>::format(this->_expected);
}
};
virtual TypedMatcher<T> *createMatcher() const override {
return new Matcher(this->_expected);
}
};
template<typename T>
struct LeMatcherCreator : public ComparisonMatcherCreator<T> {
virtual ~LeMatcherCreator() = default;
LeMatcherCreator(const T &expected)
: ComparisonMatcherCreator<T>(expected) {
}
struct Matcher : public ComparisonMatcherCreator<T>::Matcher {
Matcher(const T &expected)
: ComparisonMatcherCreator<T>::Matcher(expected) {
}
virtual bool matches(const T &actual) const override {
return actual <= this->_expected;
}
virtual std::string format() const override {
return std::string("<=") + TypeFormatter<T>::format(this->_expected);
}
};
virtual TypedMatcher<T> *createMatcher() const override {
return new Matcher(this->_expected);
}
};
template<typename T>
struct NeMatcherCreator : public ComparisonMatcherCreator<T> {
virtual ~NeMatcherCreator() = default;
NeMatcherCreator(const T &expected)
: ComparisonMatcherCreator<T>(expected) {
}
struct Matcher : public ComparisonMatcherCreator<T>::Matcher {
Matcher(const T &expected)
: ComparisonMatcherCreator<T>::Matcher(expected) {
}
virtual bool matches(const T &actual) const override {
return actual != this->_expected;
}
virtual std::string format() const override {
return std::string("!=") + TypeFormatter<T>::format(this->_expected);
}
};
virtual TypedMatcher<T> *createMatcher() const override {
return new Matcher(this->_expected);
}
};
}
struct AnyMatcher {
} static _;
template<typename T>
internal::TypedAnyMatcher<T> Any() {
internal::TypedAnyMatcher<T> rv;
return rv;
}
template<typename T>
internal::EqMatcherCreator<T> Eq(const T &arg) {
internal::EqMatcherCreator<T> rv(arg);
return rv;
}
template<typename T>
internal::GtMatcherCreator<T> Gt(const T &arg) {
internal::GtMatcherCreator<T> rv(arg);
return rv;
}
template<typename T>
internal::GeMatcherCreator<T> Ge(const T &arg) {
internal::GeMatcherCreator<T> rv(arg);
return rv;
}
template<typename T>
internal::LtMatcherCreator<T> Lt(const T &arg) {
internal::LtMatcherCreator<T> rv(arg);
return rv;
}
template<typename T>
internal::LeMatcherCreator<T> Le(const T &arg) {
internal::LeMatcherCreator<T> rv(arg);
return rv;
}
template<typename T>
internal::NeMatcherCreator<T> Ne(const T &arg) {
internal::NeMatcherCreator<T> rv(arg);
return rv;
}
}
namespace fakeit {
template<typename ... arglist>
struct ArgumentsMatcherInvocationMatcher : public ActualInvocation<arglist...>::Matcher {
virtual ~ArgumentsMatcherInvocationMatcher() {
for (unsigned int i = 0; i < _matchers.size(); i++)
delete _matchers[i];
}
ArgumentsMatcherInvocationMatcher(const std::vector<Destructible *> &args)
: _matchers(args) {
}
virtual bool matches(ActualInvocation<arglist...> &invocation) override {
if (invocation.getActualMatcher() == this)
return true;
return matches(invocation.getActualArguments());
}
virtual std::string format() const override {
std::ostringstream out;
out << "(";
for (unsigned int i = 0; i < _matchers.size(); i++) {
if (i > 0) out << ", ";
IMatcher *m = dynamic_cast<IMatcher *>(_matchers[i]);
out << m->format();
}
out << ")";
return out.str();
}
private:
struct MatchingLambda {
MatchingLambda(const std::vector<Destructible *> &matchers)
: _matchers(matchers) {
}
template<typename A>
void operator()(int index, A &actualArg) {
TypedMatcher<typename naked_type<A>::type> *matcher =
dynamic_cast<TypedMatcher<typename naked_type<A>::type> *>(_matchers[index]);
if (_matching)
_matching = matcher->matches(actualArg);
}
bool isMatching() {
return _matching;
}
private:
bool _matching = true;
const std::vector<Destructible *> &_matchers;
};
virtual bool matches(ArgumentsTuple<arglist...>& actualArguments) {
MatchingLambda l(_matchers);
fakeit::TupleDispatcher::for_each(actualArguments, l);
return l.isMatching();
}
const std::vector<Destructible *> _matchers;
};
template<typename ... arglist>
struct UserDefinedInvocationMatcher : ActualInvocation<arglist...>::Matcher {
virtual ~UserDefinedInvocationMatcher() = default;
UserDefinedInvocationMatcher(std::function<bool(arglist &...)> match)
: matcher{match} {
}
virtual bool matches(ActualInvocation<arglist...> &invocation) override {
if (invocation.getActualMatcher() == this)
return true;
return matches(invocation.getActualArguments());
}
virtual std::string format() const override {
return {"( user defined matcher )"};
}
private:
virtual bool matches(ArgumentsTuple<arglist...>& actualArguments) {
return TupleDispatcher::invoke<bool, typename tuple_arg<arglist>::type...>(matcher, actualArguments);
}
const std::function<bool(arglist &...)> matcher;
};
template<typename ... arglist>
struct DefaultInvocationMatcher : public ActualInvocation<arglist...>::Matcher {
virtual ~DefaultInvocationMatcher() = default;
DefaultInvocationMatcher() {
}
virtual bool matches(ActualInvocation<arglist...> &invocation) override {
return matches(invocation.getActualArguments());
}
virtual std::string format() const override {
return {"( Any arguments )"};
}
private:
virtual bool matches(const ArgumentsTuple<arglist...>&) {
return true;
}
};
}
namespace fakeit {
template<typename R, typename ... arglist>
class RecordedMethodBody : public MethodInvocationHandler<R, arglist...>, public ActualInvocationsSource {
struct MatchedInvocationHandler : ActualInvocationHandler<R, arglist...> {
virtual ~MatchedInvocationHandler() = default;
MatchedInvocationHandler(typename ActualInvocation<arglist...>::Matcher *matcher,
ActualInvocationHandler<R, arglist...> *invocationHandler) :
_matcher{matcher}, _invocationHandler{invocationHandler} {
}
virtual R handleMethodInvocation(ArgumentsTuple<arglist...> & args) override
{
Destructible &destructable = *_invocationHandler;
ActualInvocationHandler<R, arglist...> &invocationHandler = dynamic_cast<ActualInvocationHandler<R, arglist...> &>(destructable);
return invocationHandler.handleMethodInvocation(args);
}
typename ActualInvocation<arglist...>::Matcher &getMatcher() const {
Destructible &destructable = *_matcher;
typename ActualInvocation<arglist...>::Matcher &matcher = dynamic_cast<typename ActualInvocation<arglist...>::Matcher &>(destructable);
return matcher;
}
private:
std::shared_ptr<Destructible> _matcher;
std::shared_ptr<Destructible> _invocationHandler;
};
FakeitContext &_fakeit;
MethodInfo _method;
std::vector<std::shared_ptr<Destructible>> _invocationHandlers;
std::vector<std::shared_ptr<Destructible>> _actualInvocations;
MatchedInvocationHandler *buildMatchedInvocationHandler(
typename ActualInvocation<arglist...>::Matcher *invocationMatcher,
ActualInvocationHandler<R, arglist...> *invocationHandler) {
return new MatchedInvocationHandler(invocationMatcher, invocationHandler);
}
MatchedInvocationHandler *getInvocationHandlerForActualArgs(ActualInvocation<arglist...> &invocation) {
for (auto i = _invocationHandlers.rbegin(); i != _invocationHandlers.rend(); ++i) {
std::shared_ptr<Destructible> curr = *i;
Destructible &destructable = *curr;
MatchedInvocationHandler &im = asMatchedInvocationHandler(destructable);
if (im.getMatcher().matches(invocation)) {
return &im;
}
}
return nullptr;
}
MatchedInvocationHandler &asMatchedInvocationHandler(Destructible &destructable) {
MatchedInvocationHandler &im = dynamic_cast<MatchedInvocationHandler &>(destructable);
return im;
}
ActualInvocation<arglist...> &asActualInvocation(Destructible &destructable) const {
ActualInvocation<arglist...> &invocation = dynamic_cast<ActualInvocation<arglist...> &>(destructable);
return invocation;
}
public:
RecordedMethodBody(FakeitContext &fakeit, std::string name) :
_fakeit(fakeit), _method{MethodInfo::nextMethodOrdinal(), name} { }
virtual ~RecordedMethodBody() NO_THROWS {
}
MethodInfo &getMethod() {
return _method;
}
bool isOfMethod(MethodInfo &method) {
return method.id() == _method.id();
}
void addMethodInvocationHandler(typename ActualInvocation<arglist...>::Matcher *matcher,
ActualInvocationHandler<R, arglist...> *invocationHandler) {
ActualInvocationHandler<R, arglist...> *mock = buildMatchedInvocationHandler(matcher, invocationHandler);
std::shared_ptr<Destructible> destructable{mock};
_invocationHandlers.push_back(destructable);
}
void clear() {
_invocationHandlers.clear();
_actualInvocations.clear();
}
R handleMethodInvocation(const typename fakeit::production_arg<arglist>::type... args) override {
unsigned int ordinal = Invocation::nextInvocationOrdinal();
MethodInfo &method = this->getMethod();
auto actualInvocation = new ActualInvocation<arglist...>(ordinal, method, std::forward<const typename fakeit::production_arg<arglist>::type>(args)...);
std::shared_ptr<Destructible> actualInvocationDtor{actualInvocation};
auto invocationHandler = getInvocationHandlerForActualArgs(*actualInvocation);
if (invocationHandler) {
auto &matcher = invocationHandler->getMatcher();
actualInvocation->setActualMatcher(&matcher);
_actualInvocations.push_back(actualInvocationDtor);
try {
return invocationHandler->handleMethodInvocation(actualInvocation->getActualArguments());
} catch (NoMoreRecordedActionException &) {
}
}
UnexpectedMethodCallEvent event(UnexpectedType::Unmatched, *actualInvocation);
_fakeit.handle(event);
std::string format{_fakeit.format(event)};
UnexpectedMethodCallException e(format);
throw e;
}
void scanActualInvocations(const std::function<void(ActualInvocation<arglist...> &)> &scanner) {
for (auto destructablePtr : _actualInvocations) {
ActualInvocation<arglist...> &invocation = asActualInvocation(*destructablePtr);
scanner(invocation);
}
}
void getActualInvocations(std::unordered_set<Invocation *> &into) const override {
for (auto destructablePtr : _actualInvocations) {
Invocation &invocation = asActualInvocation(*destructablePtr);
into.insert(&invocation);
}
}
void setMethodDetails(const std::string &mockName, const std::string &methodName) {
const std::string fullName{mockName + "." + methodName};
_method.setName(fullName);
}
};
}
#include <functional>
#include <type_traits>
#include <stdexcept>
#include <utility>
#include <functional>
#include <type_traits>
namespace fakeit {
struct Quantity {
Quantity(const int q) :
quantity(q) {
}
const int quantity;
} static Once(1);
template<typename R>
struct Quantifier : public Quantity {
Quantifier(const int q, const R &val) :
Quantity(q), value(val) {
}
const R &value;
};
template<>
struct Quantifier<void> : public Quantity {
explicit Quantifier(const int q) :
Quantity(q) {
}
};
struct QuantifierFunctor : public Quantifier<void> {
QuantifierFunctor(const int q) :
Quantifier<void>(q) {
}
template<typename R>
Quantifier<R> operator()(const R &value) {
return Quantifier<R>(quantity, value);
}
};
template<int q>
struct Times : public Quantity {
Times<q>() : Quantity(q) { }
template<typename R>
static Quantifier<R> of(const R &value) {
return Quantifier<R>(q, value);
}
static Quantifier<void> Void() {
return Quantifier<void>(q);
}
};
#if defined (__GNUG__) || (_MSC_VER >= 1900)
inline QuantifierFunctor operator
""
_Times(unsigned long long n) {
return QuantifierFunctor((int) n);
}
inline QuantifierFunctor operator
""
_Time(unsigned long long n) {
if (n != 1)
throw std::invalid_argument("Only 1_Time is supported. Use X_Times (with s) if X is bigger than 1");
return QuantifierFunctor((int) n);
}
#endif
}
#include <functional>
#include <atomic>
#include <tuple>
#include <type_traits>
namespace fakeit {
template<typename R, typename ... arglist>
struct Action : Destructible {
virtual R invoke(const ArgumentsTuple<arglist...> &) = 0;
virtual bool isDone() = 0;
};
template<typename R, typename ... arglist>
struct Repeat : Action<R, arglist...> {
virtual ~Repeat() = default;
Repeat(std::function<R(typename fakeit::test_arg<arglist>::type...)> func) :
f(func), times(1) {
}
Repeat(std::function<R(typename fakeit::test_arg<arglist>::type...)> func, long t) :
f(func), times(t) {
}
virtual R invoke(const ArgumentsTuple<arglist...> & args) override {
times--;
return TupleDispatcher::invoke<R, arglist...>(f, args);
}
virtual bool isDone() override {
return times == 0;
}
private:
std::function<R(typename fakeit::test_arg<arglist>::type...)> f;
long times;
};
template<typename R, typename ... arglist>
struct RepeatForever : public Action<R, arglist...> {
virtual ~RepeatForever() = default;
RepeatForever(std::function<R(typename fakeit::test_arg<arglist>::type...)> func) :
f(func) {
}
virtual R invoke(const ArgumentsTuple<arglist...> & args) override {
return TupleDispatcher::invoke<R, arglist...>(f, args);
}
virtual bool isDone() override {
return false;
}
private:
std::function<R(typename fakeit::test_arg<arglist>::type...)> f;
};
template<typename R, typename ... arglist>
struct ReturnDefaultValue : public Action<R, arglist...> {
virtual ~ReturnDefaultValue() = default;
virtual R invoke(const ArgumentsTuple<arglist...> &) override {
return DefaultValue<R>::value();
}
virtual bool isDone() override {
return false;
}
};
template<typename R, typename ... arglist>
struct ReturnDelegateValue : public Action<R, arglist...> {
ReturnDelegateValue(std::function<R(const typename fakeit::test_arg<arglist>::type...)> delegate) : _delegate(delegate) { }
virtual ~ReturnDelegateValue() = default;
virtual R invoke(const ArgumentsTuple<arglist...> & args) override {
return TupleDispatcher::invoke<R, arglist...>(_delegate, args);
}
virtual bool isDone() override {
return false;
}
private:
std::function<R(const typename fakeit::test_arg<arglist>::type...)> _delegate;
};
}
namespace fakeit {
template<typename R, typename ... arglist>
struct MethodStubbingProgress {
virtual ~MethodStubbingProgress() THROWS {
}
template<typename U = R>
typename std::enable_if<!std::is_reference<U>::value, MethodStubbingProgress<R, arglist...> &>::type
Return(const R &r) {
return Do([r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; });
}
template<typename U = R>
typename std::enable_if<std::is_reference<U>::value, MethodStubbingProgress<R, arglist...> &>::type
Return(const R &r) {
return Do([&r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; });
}
MethodStubbingProgress<R, arglist...> &
Return(const Quantifier<R> &q) {
const R &value = q.value;
auto method = [value](const arglist &...) -> R { return value; };
return DoImpl(new Repeat<R, arglist...>(method, q.quantity));
}
template<typename first, typename second, typename ... tail>
MethodStubbingProgress<R, arglist...> &
Return(const first &f, const second &s, const tail &... t) {
Return(f);
return Return(s, t...);
}
template<typename U = R>
typename std::enable_if<!std::is_reference<U>::value, void>::type
AlwaysReturn(const R &r) {
return AlwaysDo([r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; });
}
template<typename U = R>
typename std::enable_if<std::is_reference<U>::value, void>::type
AlwaysReturn(const R &r) {
return AlwaysDo([&r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; });
}
MethodStubbingProgress<R, arglist...> &
Return() {
return Do([](const typename fakeit::test_arg<arglist>::type...) -> R { return DefaultValue<R>::value(); });
}
void AlwaysReturn() {
return AlwaysDo([](const typename fakeit::test_arg<arglist>::type...) -> R { return DefaultValue<R>::value(); });
}
template<typename E>
MethodStubbingProgress<R, arglist...> &Throw(const E &e) {
return Do([e](const typename fakeit::test_arg<arglist>::type...) -> R { throw e; });
}
template<typename E>
MethodStubbingProgress<R, arglist...> &
Throw(const Quantifier<E> &q) {
const E &value = q.value;
auto method = [value](const arglist &...) -> R { throw value; };
return DoImpl(new Repeat<R, arglist...>(method, q.quantity));
}
template<typename first, typename second, typename ... tail>
MethodStubbingProgress<R, arglist...> &
Throw(const first &f, const second &s, const tail &... t) {
Throw(f);
return Throw(s, t...);
}
template<typename E>
void AlwaysThrow(const E &e) {
return AlwaysDo([e](const typename fakeit::test_arg<arglist>::type...) -> R { throw e; });
}
virtual MethodStubbingProgress<R, arglist...> &
Do(std::function<R(const typename fakeit::test_arg<arglist>::type...)> method) {
return DoImpl(new Repeat<R, arglist...>(method));
}
template<typename F>
MethodStubbingProgress<R, arglist...> &
Do(const Quantifier<F> &q) {
return DoImpl(new Repeat<R, arglist...>(q.value, q.quantity));
}
template<typename first, typename second, typename ... tail>
MethodStubbingProgress<R, arglist...> &
Do(const first &f, const second &s, const tail &... t) {
Do(f);
return Do(s, t...);
}
virtual void AlwaysDo(std::function<R(const typename fakeit::test_arg<arglist>::type...)> method) {
DoImpl(new RepeatForever<R, arglist...>(method));
}
protected:
virtual MethodStubbingProgress<R, arglist...> &DoImpl(Action<R, arglist...> *action) = 0;
private:
MethodStubbingProgress &operator=(const MethodStubbingProgress &other) = delete;
};
template<typename ... arglist>
struct MethodStubbingProgress<void, arglist...> {
virtual ~MethodStubbingProgress() THROWS {
}
MethodStubbingProgress<void, arglist...> &Return() {
auto lambda = [](const typename fakeit::test_arg<arglist>::type...) -> void {
return DefaultValue<void>::value();
};
return Do(lambda);
}
virtual MethodStubbingProgress<void, arglist...> &Do(
std::function<void(const typename fakeit::test_arg<arglist>::type...)> method) {
return DoImpl(new Repeat<void, arglist...>(method));
}
void AlwaysReturn() {
return AlwaysDo([](const typename fakeit::test_arg<arglist>::type...) -> void { return DefaultValue<void>::value(); });
}
MethodStubbingProgress<void, arglist...> &
Return(const Quantifier<void> &q) {
auto method = [](const arglist &...) -> void { return DefaultValue<void>::value(); };
return DoImpl(new Repeat<void, arglist...>(method, q.quantity));
}
template<typename E>
MethodStubbingProgress<void, arglist...> &Throw(const E &e) {
return Do([e](const typename fakeit::test_arg<arglist>::type...) -> void { throw e; });
}
template<typename E>
MethodStubbingProgress<void, arglist...> &
Throw(const Quantifier<E> &q) {
const E &value = q.value;
auto method = [value](const typename fakeit::test_arg<arglist>::type...) -> void { throw value; };
return DoImpl(new Repeat<void, arglist...>(method, q.quantity));
}
template<typename first, typename second, typename ... tail>
MethodStubbingProgress<void, arglist...> &
Throw(const first &f, const second &s, const tail &... t) {
Throw(f);
return Throw(s, t...);
}
template<typename E>
void AlwaysThrow(const E e) {
return AlwaysDo([e](const typename fakeit::test_arg<arglist>::type...) -> void { throw e; });
}
template<typename F>
MethodStubbingProgress<void, arglist...> &
Do(const Quantifier<F> &q) {
return DoImpl(new Repeat<void, arglist...>(q.value, q.quantity));
}
template<typename first, typename second, typename ... tail>
MethodStubbingProgress<void, arglist...> &
Do(const first &f, const second &s, const tail &... t) {
Do(f);
return Do(s, t...);
}
virtual void AlwaysDo(std::function<void(const typename fakeit::test_arg<arglist>::type...)> method) {
DoImpl(new RepeatForever<void, arglist...>(method));
}
protected:
virtual MethodStubbingProgress<void, arglist...> &DoImpl(Action<void, arglist...> *action) = 0;
private:
MethodStubbingProgress &operator=(const MethodStubbingProgress &other) = delete;
};
}
#include <vector>
#include <functional>
namespace fakeit {
class Finally {
private:
std::function<void()> _finallyClause;
Finally(const Finally &);
Finally &operator=(const Finally &);
public:
explicit Finally(std::function<void()> f) :
_finallyClause(f) {
}
~Finally() {
_finallyClause();
}
};
}
namespace fakeit {
template<typename R, typename ... arglist>
struct ActionSequence : ActualInvocationHandler<R,arglist...> {
ActionSequence() {
clear();
}
void AppendDo(Action<R, arglist...> *action) {
append(action);
}
virtual R handleMethodInvocation(ArgumentsTuple<arglist...> & args) override
{
std::shared_ptr<Destructible> destructablePtr = _recordedActions.front();
Destructible &destructable = *destructablePtr;
Action<R, arglist...> &action = dynamic_cast<Action<R, arglist...> &>(destructable);
std::function<void()> finallyClause = [&]() -> void {
if (action.isDone())
_recordedActions.erase(_recordedActions.begin());
};
Finally onExit(finallyClause);
return action.invoke(args);
}
private:
struct NoMoreRecordedAction : Action<R, arglist...> {
virtual R invoke(const ArgumentsTuple<arglist...> &) override {
throw NoMoreRecordedActionException();
}
virtual bool isDone() override {
return false;
}
};
void append(Action<R, arglist...> *action) {
std::shared_ptr<Destructible> destructable{action};
_recordedActions.insert(_recordedActions.end() - 1, destructable);
}
void clear() {
_recordedActions.clear();
auto actionPtr = std::shared_ptr<Destructible> {new NoMoreRecordedAction()};
_recordedActions.push_back(actionPtr);
}
std::vector<std::shared_ptr<Destructible>> _recordedActions;
};
}
namespace fakeit {
template<typename C, typename DATA_TYPE>
class DataMemberStubbingRoot {
private:
public:
DataMemberStubbingRoot(const DataMemberStubbingRoot &) = default;
DataMemberStubbingRoot() = default;
void operator=(const DATA_TYPE&) {
}
};
}
#include <functional>
#include <utility>
#include <type_traits>
#include <tuple>
#include <memory>
#include <vector>
#include <unordered_set>
#include <set>
#include <iosfwd>
namespace fakeit {
struct Xaction {
virtual void commit() = 0;
};
}
namespace fakeit {
template<typename R, typename ... arglist>
struct SpyingContext : Xaction {
virtual void appendAction(Action<R, arglist...> *action) = 0;
virtual std::function<R(arglist&...)> getOriginalMethod() = 0;
};
}
namespace fakeit {
template<typename R, typename ... arglist>
struct StubbingContext : public Xaction {
virtual void appendAction(Action<R, arglist...> *action) = 0;
};
}
#include <functional>
#include <type_traits>
#include <tuple>
#include <memory>
#include <vector>
#include <unordered_set>
namespace fakeit {
template<unsigned int index, typename ... arglist>
class MatchersCollector {
std::vector<Destructible *> &_matchers;
public:
template<std::size_t N>
using ArgType = typename std::tuple_element<N, std::tuple<arglist...>>::type;
template<std::size_t N>
using NakedArgType = typename naked_type<ArgType<index>>::type;
template<std::size_t N>
using ArgMatcherCreatorType = decltype(std::declval<TypedMatcherCreator<NakedArgType<N>>>());
MatchersCollector(std::vector<Destructible *> &matchers)
: _matchers(matchers) {
}
void CollectMatchers() {
}
template<typename Head>
typename std::enable_if<
std::is_constructible<NakedArgType<index>, Head>::value, void>
::type CollectMatchers(const Head &value) {
TypedMatcher<NakedArgType<index>> *d = Eq<NakedArgType<index>>(value).createMatcher();
_matchers.push_back(d);
}
template<typename Head, typename ...Tail>
typename std::enable_if<
std::is_constructible<NakedArgType<index>, Head>::value
, void>
::type CollectMatchers(const Head &head, const Tail &... tail) {
CollectMatchers(head);
MatchersCollector<index + 1, arglist...> c(_matchers);
c.CollectMatchers(tail...);
}
template<typename Head>
typename std::enable_if<
std::is_base_of<TypedMatcherCreator<NakedArgType<index>>, Head>::value, void>
::type CollectMatchers(const Head &creator) {
TypedMatcher<NakedArgType<index>> *d = creator.createMatcher();
_matchers.push_back(d);
}
template<typename Head, typename ...Tail>
typename std::enable_if<
std::is_base_of<TypedMatcherCreator<NakedArgType<index>>, Head>::value, void>
::type CollectMatchers(const Head &head, const Tail &... tail) {
CollectMatchers(head);
MatchersCollector<index + 1, arglist...> c(_matchers);
c.CollectMatchers(tail...);
}
template<typename Head>
typename std::enable_if<
std::is_same<AnyMatcher, Head>::value, void>
::type CollectMatchers(const Head &) {
TypedMatcher<NakedArgType<index>> *d = Any<NakedArgType<index>>().createMatcher();
_matchers.push_back(d);
}
template<typename Head, typename ...Tail>
typename std::enable_if<
std::is_same<AnyMatcher, Head>::value, void>
::type CollectMatchers(const Head &head, const Tail &... tail) {
CollectMatchers(head);
MatchersCollector<index + 1, arglist...> c(_matchers);
c.CollectMatchers(tail...);
}
};
}
namespace fakeit {
template<typename R, typename ... arglist>
class MethodMockingContext :
public Sequence,
public ActualInvocationsSource,
public virtual StubbingContext<R, arglist...>,
public virtual SpyingContext<R, arglist...>,
private Invocation::Matcher {
public:
struct Context : Destructible {
virtual typename std::function<R(arglist&...)> getOriginalMethod() = 0;
virtual std::string getMethodName() = 0;
virtual void addMethodInvocationHandler(typename ActualInvocation<arglist...>::Matcher *matcher,
ActualInvocationHandler<R, arglist...> *invocationHandler) = 0;
virtual void scanActualInvocations(const std::function<void(ActualInvocation<arglist...> &)> &scanner) = 0;
virtual void setMethodDetails(std::string mockName, std::string methodName) = 0;
virtual bool isOfMethod(MethodInfo &method) = 0;
virtual ActualInvocationsSource &getInvolvedMock() = 0;
};
private:
class Implementation {
Context *_stubbingContext;
ActionSequence<R, arglist...> *_recordedActionSequence;
typename ActualInvocation<arglist...>::Matcher *_invocationMatcher;
bool _commited;
Context &getStubbingContext() const {
return *_stubbingContext;
}
public:
Implementation(Context *stubbingContext)
: _stubbingContext(stubbingContext),
_recordedActionSequence(new ActionSequence<R, arglist...>()),
_invocationMatcher
{
new DefaultInvocationMatcher<arglist...>()}, _commited(false) {
}
~Implementation() {
delete _stubbingContext;
if (!_commited) {
delete _recordedActionSequence;
delete _invocationMatcher;
}
}
ActionSequence<R, arglist...> &getRecordedActionSequence() {
return *_recordedActionSequence;
}
std::string format() const {
std::string s = getStubbingContext().getMethodName();
s += _invocationMatcher->format();
return s;
}
void getActualInvocations(std::unordered_set<Invocation *> &into) const {
auto scanner = [&](ActualInvocation<arglist...> &a) {
if (_invocationMatcher->matches(a)) {
into.insert(&a);
}
};
getStubbingContext().scanActualInvocations(scanner);
}
bool matches(Invocation &invocation) {
MethodInfo &actualMethod = invocation.getMethod();
if (!getStubbingContext().isOfMethod(actualMethod)) {
return false;
}
ActualInvocation<arglist...> &actualInvocation = dynamic_cast<ActualInvocation<arglist...> &>(invocation);
return _invocationMatcher->matches(actualInvocation);
}
void commit() {
getStubbingContext().addMethodInvocationHandler(_invocationMatcher, _recordedActionSequence);
_commited = true;
}
void appendAction(Action<R, arglist...> *action) {
getRecordedActionSequence().AppendDo(action);
}
void setMethodBodyByAssignment(std::function<R(const typename fakeit::test_arg<arglist>::type...)> method) {
appendAction(new RepeatForever<R, arglist...>(method));
commit();
}
void setMethodDetails(std::string mockName, std::string methodName) {
getStubbingContext().setMethodDetails(mockName, methodName);
}
void getInvolvedMocks(std::vector<ActualInvocationsSource *> &into) const {
into.push_back(&getStubbingContext().getInvolvedMock());
}
typename std::function<R(arglist &...)> getOriginalMethod() {
return getStubbingContext().getOriginalMethod();
}
void setInvocationMatcher(typename ActualInvocation<arglist...>::Matcher *matcher) {
delete _invocationMatcher;
_invocationMatcher = matcher;
}
};
protected:
MethodMockingContext(Context *stubbingContext)
: _impl{new Implementation(stubbingContext)} {
}
MethodMockingContext(MethodMockingContext &) = default;
MethodMockingContext(MethodMockingContext &&other)
: _impl(std::move(other._impl)) {
}
virtual ~MethodMockingContext() NO_THROWS { }
std::string format() const override {
return _impl->format();
}
unsigned int size() const override {
return 1;
}
void getInvolvedMocks(std::vector<ActualInvocationsSource *> &into) const override {
_impl->getInvolvedMocks(into);
}
void getExpectedSequence(std::vector<Invocation::Matcher *> &into) const override {
const Invocation::Matcher *b = this;
Invocation::Matcher *c = const_cast<Invocation::Matcher *>(b);
into.push_back(c);
}
void getActualInvocations(std::unordered_set<Invocation *> &into) const override {
_impl->getActualInvocations(into);
}
bool matches(Invocation &invocation) override {
return _impl->matches(invocation);
}
void commit() override {
_impl->commit();
}
void setMethodDetails(std::string mockName, std::string methodName) {
_impl->setMethodDetails(mockName, methodName);
}
void setMatchingCriteria(std::function<bool(arglist &...)> predicate) {
typename ActualInvocation<arglist...>::Matcher *matcher{
new UserDefinedInvocationMatcher<arglist...>(predicate)};
_impl->setInvocationMatcher(matcher);
}
void setMatchingCriteria(const std::vector<Destructible *> &matchers) {
typename ActualInvocation<arglist...>::Matcher *matcher{
new ArgumentsMatcherInvocationMatcher<arglist...>(matchers)};
_impl->setInvocationMatcher(matcher);
}
void appendAction(Action<R, arglist...> *action) override {
_impl->appendAction(action);
}
void setMethodBodyByAssignment(std::function<R(const typename fakeit::test_arg<arglist>::type...)> method) {
_impl->setMethodBodyByAssignment(method);
}
template<class ...matcherCreators, class = typename std::enable_if<
sizeof...(matcherCreators) == sizeof...(arglist)>::type>
void setMatchingCriteria(const matcherCreators &... matcherCreator) {
std::vector<Destructible *> matchers;
MatchersCollector<0, arglist...> c(matchers);
c.CollectMatchers(matcherCreator...);
MethodMockingContext<R, arglist...>::setMatchingCriteria(matchers);
}
private:
typename std::function<R(arglist&...)> getOriginalMethod() override {
return _impl->getOriginalMethod();
}
std::shared_ptr<Implementation> _impl;
};
template<typename R, typename ... arglist>
class MockingContext :
public MethodMockingContext<R, arglist...> {
MockingContext &operator=(const MockingContext &) = delete;
public:
MockingContext(typename MethodMockingContext<R, arglist...>::Context *stubbingContext)
: MethodMockingContext<R, arglist...>(stubbingContext) {
}
MockingContext(MockingContext &) = default;
MockingContext(MockingContext &&other)
: MethodMockingContext<R, arglist...>(std::move(other)) {
}
MockingContext<R, arglist...> &setMethodDetails(std::string mockName, std::string methodName) {
MethodMockingContext<R, arglist...>::setMethodDetails(mockName, methodName);
return *this;
}
MockingContext<R, arglist...> &Using(const arglist &... args) {
MethodMockingContext<R, arglist...>::setMatchingCriteria(args...);
return *this;
}
template<class ...arg_matcher>
MockingContext<R, arglist...> &Using(const arg_matcher &... arg_matchers) {
MethodMockingContext<R, arglist...>::setMatchingCriteria(arg_matchers...);
return *this;
}
MockingContext<R, arglist...> &Matching(std::function<bool(arglist &...)> matcher) {
MethodMockingContext<R, arglist...>::setMatchingCriteria(matcher);
return *this;
}
MockingContext<R, arglist...> &operator()(const arglist &... args) {
MethodMockingContext<R, arglist...>::setMatchingCriteria(args...);
return *this;
}
MockingContext<R, arglist...> &operator()(std::function<bool(arglist &...)> matcher) {
MethodMockingContext<R, arglist...>::setMatchingCriteria(matcher);
return *this;
}
void operator=(std::function<R(arglist &...)> method) {
MethodMockingContext<R, arglist...>::setMethodBodyByAssignment(method);
}
template<typename U = R>
typename std::enable_if<!std::is_reference<U>::value, void>::type operator=(const R &r) {
auto method = [r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; };
MethodMockingContext<R, arglist...>::setMethodBodyByAssignment(method);
}
template<typename U = R>
typename std::enable_if<std::is_reference<U>::value, void>::type operator=(const R &r) {
auto method = [&r](const typename fakeit::test_arg<arglist>::type...) -> R { return r; };
MethodMockingContext<R, arglist...>::setMethodBodyByAssignment(method);
}
};
template<typename ... arglist>
class MockingContext<void, arglist...> :
public MethodMockingContext<void, arglist...> {
MockingContext &operator=(const MockingContext &) = delete;
public:
MockingContext(typename MethodMockingContext<void, arglist...>::Context *stubbingContext)
: MethodMockingContext<void, arglist...>(stubbingContext) {
}
MockingContext(MockingContext &) = default;
MockingContext(MockingContext &&other)
: MethodMockingContext<void, arglist...>(std::move(other)) {
}
MockingContext<void, arglist...> &setMethodDetails(std::string mockName, std::string methodName) {
MethodMockingContext<void, arglist...>::setMethodDetails(mockName, methodName);
return *this;
}
MockingContext<void, arglist...> &Using(const arglist &... args) {
MethodMockingContext<void, arglist...>::setMatchingCriteria(args...);
return *this;
}
template<class ...arg_matcher>
MockingContext<void, arglist...> &Using(const arg_matcher &... arg_matchers) {
MethodMockingContext<void, arglist...>::setMatchingCriteria(arg_matchers...);
return *this;
}
MockingContext<void, arglist...> &Matching(std::function<bool(arglist &...)> matcher) {
MethodMockingContext<void, arglist...>::setMatchingCriteria(matcher);
return *this;
}
MockingContext<void, arglist...> &operator()(const arglist &... args) {
MethodMockingContext<void, arglist...>::setMatchingCriteria(args...);
return *this;
}
MockingContext<void, arglist...> &operator()(std::function<bool(arglist &...)> matcher) {
MethodMockingContext<void, arglist...>::setMatchingCriteria(matcher);
return *this;
}
void operator=(std::function<void(arglist &...)> method) {
MethodMockingContext<void, arglist...>::setMethodBodyByAssignment(method);
}
};
class DtorMockingContext : public MethodMockingContext<void> {
public:
DtorMockingContext(MethodMockingContext<void>::Context *stubbingContext)
: MethodMockingContext<void>(stubbingContext) {
}
DtorMockingContext(DtorMockingContext &other) : MethodMockingContext<void>(other) {
}
DtorMockingContext(DtorMockingContext &&other) : MethodMockingContext<void>(std::move(other)) {
}
void operator=(std::function<void()> method) {
MethodMockingContext<void>::setMethodBodyByAssignment(method);
}
DtorMockingContext &setMethodDetails(std::string mockName, std::string methodName) {
MethodMockingContext<void>::setMethodDetails(mockName, methodName);
return *this;
}
};
}
namespace fakeit {
template<typename C, typename ... baseclasses>
class MockImpl : private MockObject<C>, public virtual ActualInvocationsSource {
public:
MockImpl(FakeitContext &fakeit, C &obj)
: MockImpl<C, baseclasses...>(fakeit, obj, true) {
}
MockImpl(FakeitContext &fakeit)
: MockImpl<C, baseclasses...>(fakeit, *(createFakeInstance()), false) {
FakeObject<C, baseclasses...> *fake = reinterpret_cast<FakeObject<C, baseclasses...> *>(_instance);
fake->getVirtualTable().setCookie(1, this);
}
virtual ~MockImpl() NO_THROWS {
_proxy.detach();
if (_isOwner) {
FakeObject<C, baseclasses...> *fake = reinterpret_cast<FakeObject<C, baseclasses...> *>(_instance);
delete fake;
}
}
void detach() {
_isOwner = false;
_proxy.detach();
}
void getActualInvocations(std::unordered_set<Invocation *> &into) const override {
std::vector<ActualInvocationsSource *> vec;
_proxy.getMethodMocks(vec);
for (ActualInvocationsSource *s : vec) {
s->getActualInvocations(into);
}
}
void reset() {
_proxy.Reset();
if (_isOwner) {
FakeObject<C, baseclasses...> *fake = reinterpret_cast<FakeObject<C, baseclasses...> *>(_instance);
fake->initializeDataMembersArea();
}
}
virtual C &get() override {
return _proxy.get();
}
virtual FakeitContext &getFakeIt() override {
return _fakeit;
}
template<class DATA_TYPE, typename T, typename ... arglist, class = typename std::enable_if<std::is_base_of<T, C>::value>::type>
DataMemberStubbingRoot<C, DATA_TYPE> stubDataMember(DATA_TYPE T::*member, const arglist &... ctorargs) {
_proxy.stubDataMember(member, ctorargs...);
return DataMemberStubbingRoot<T, DATA_TYPE>();
}
template<int id, typename R, typename T, typename ... arglist, class = typename std::enable_if<std::is_base_of<T, C>::value>::type>
MockingContext<R, arglist...> stubMethod(R(T::*vMethod)(arglist...)) {
return MockingContext<R, arglist...>(new UniqueMethodMockingContextImpl < id, R, arglist... >
(*this, vMethod));
}
DtorMockingContext stubDtor() {
return DtorMockingContext(new DtorMockingContextImpl(*this));
}
private:
DynamicProxy<C, baseclasses...> _proxy;
C *_instance;
bool _isOwner;
FakeitContext &_fakeit;
template<typename R, typename ... arglist>
class MethodMockingContextBase : public MethodMockingContext<R, arglist...>::Context {
protected:
MockImpl<C, baseclasses...> &_mock;
virtual RecordedMethodBody<R, arglist...> &getRecordedMethodBody() = 0;
public:
MethodMockingContextBase(MockImpl<C, baseclasses...> &mock) : _mock(mock) { }
virtual ~MethodMockingContextBase() = default;
void addMethodInvocationHandler(typename ActualInvocation<arglist...>::Matcher *matcher,
ActualInvocationHandler<R, arglist...> *invocationHandler) {
getRecordedMethodBody().addMethodInvocationHandler(matcher, invocationHandler);
}
void scanActualInvocations(const std::function<void(ActualInvocation<arglist...> &)> &scanner) {
getRecordedMethodBody().scanActualInvocations(scanner);
}
void setMethodDetails(std::string mockName, std::string methodName) {
getRecordedMethodBody().setMethodDetails(mockName, methodName);
}
bool isOfMethod(MethodInfo &method) {
return getRecordedMethodBody().isOfMethod(method);
}
ActualInvocationsSource &getInvolvedMock() {
return _mock;
}
std::string getMethodName() {
return getRecordedMethodBody().getMethod().name();
}
};
template<typename R, typename ... arglist>
class MethodMockingContextImpl : public MethodMockingContextBase<R, arglist...> {
protected:
R (C::*_vMethod)(arglist...);
public:
virtual ~MethodMockingContextImpl() = default;
MethodMockingContextImpl(MockImpl<C, baseclasses...> &mock, R (C::*vMethod)(arglist...))
: MethodMockingContextBase<R, arglist...>(mock), _vMethod(vMethod) {
}
virtual std::function<R(arglist&...)> getOriginalMethod() override {
void *mPtr = MethodMockingContextBase<R, arglist...>::_mock.getOriginalMethod(_vMethod);
C * instance = &(MethodMockingContextBase<R, arglist...>::_mock.get());
return [=](arglist&... args) -> R {
auto m = union_cast<typename VTableMethodType<R,arglist...>::type>(mPtr);
return m(instance, std::forward<arglist>(args)...);
};
}
};
template<int id, typename R, typename ... arglist>
class UniqueMethodMockingContextImpl : public MethodMockingContextImpl<R, arglist...> {
protected:
virtual RecordedMethodBody<R, arglist...> &getRecordedMethodBody() override {
return MethodMockingContextBase<R, arglist...>::_mock.template stubMethodIfNotStubbed<id>(
MethodMockingContextBase<R, arglist...>::_mock._proxy,
MethodMockingContextImpl<R, arglist...>::_vMethod);
}
public:
UniqueMethodMockingContextImpl(MockImpl<C, baseclasses...> &mock, R (C::*vMethod)(arglist...))
: MethodMockingContextImpl<R, arglist...>(mock, vMethod) {
}
};
class DtorMockingContextImpl : public MethodMockingContextBase<void> {
protected:
virtual RecordedMethodBody<void> &getRecordedMethodBody() override {
return MethodMockingContextBase<void>::_mock.stubDtorIfNotStubbed(
MethodMockingContextBase<void>::_mock._proxy);
}
public:
virtual ~DtorMockingContextImpl() = default;
DtorMockingContextImpl(MockImpl<C, baseclasses...> &mock)
: MethodMockingContextBase<void>(mock) {
}
virtual std::function<void()> getOriginalMethod() override {
C &instance = MethodMockingContextBase<void>::_mock.get();
return [=, &instance]() -> void {
};
}
};
static MockImpl<C, baseclasses...> *getMockImpl(void *instance) {
FakeObject<C, baseclasses...> *fake = reinterpret_cast<FakeObject<C, baseclasses...> *>(instance);
MockImpl<C, baseclasses...> *mock = reinterpret_cast<MockImpl<C, baseclasses...> *>(fake->getVirtualTable().getCookie(
1));
return mock;
}
void unmocked() {
ActualInvocation<> invocation(Invocation::nextInvocationOrdinal(), UnknownMethod::instance());
UnexpectedMethodCallEvent event(UnexpectedType::Unmocked, invocation);
auto &fakeit = getMockImpl(this)->_fakeit;
fakeit.handle(event);
std::string format = fakeit.format(event);
UnexpectedMethodCallException e(format);
throw e;
}
static C *createFakeInstance() {
FakeObject<C, baseclasses...> *fake = new FakeObject<C, baseclasses...>();
void *unmockedMethodStubPtr = union_cast<void *>(&MockImpl<C, baseclasses...>::unmocked);
fake->getVirtualTable().initAll(unmockedMethodStubPtr);
return reinterpret_cast<C *>(fake);
}
template<typename R, typename ... arglist>
void *getOriginalMethod(R (C::*vMethod)(arglist...)) {
auto vt = _proxy.getOriginalVT();
auto offset = VTUtils::getOffset(vMethod);
void *origMethodPtr = vt.getMethod(offset);
return origMethodPtr;
}
void *getOriginalDtor() {
auto vt = _proxy.getOriginalVT();
auto offset = VTUtils::getDestructorOffset<C>();
void *origMethodPtr = vt.getMethod(offset);
return origMethodPtr;
}
template<unsigned int id, typename R, typename ... arglist>
RecordedMethodBody<R, arglist...> &stubMethodIfNotStubbed(DynamicProxy<C, baseclasses...> &proxy,
R (C::*vMethod)(arglist...)) {
if (!proxy.isMethodStubbed(vMethod)) {
proxy.template stubMethod<id>(vMethod, createRecordedMethodBody < R, arglist... > (*this, vMethod));
}
Destructible *d = proxy.getMethodMock(vMethod);
RecordedMethodBody<R, arglist...> *methodMock = dynamic_cast<RecordedMethodBody<R, arglist...> *>(d);
return *methodMock;
}
RecordedMethodBody<void> &stubDtorIfNotStubbed(DynamicProxy<C, baseclasses...> &proxy) {
if (!proxy.isDtorStubbed()) {
proxy.stubDtor(createRecordedDtorBody(*this));
}
Destructible *d = proxy.getDtorMock();
RecordedMethodBody<void> *dtorMock = dynamic_cast<RecordedMethodBody<void> *>(d);
return *dtorMock;
}
MockImpl(FakeitContext &fakeit, C &obj, bool isSpy)
: _proxy{obj}, _instance(&obj), _isOwner(!isSpy), _fakeit(fakeit) {
}
template<typename R, typename ... arglist>
static RecordedMethodBody<R, arglist...> *createRecordedMethodBody(MockObject<C> &mock,
R(C::*vMethod)(arglist...)) {
return new RecordedMethodBody<R, arglist...>(mock.getFakeIt(), typeid(vMethod).name());
}
static RecordedMethodBody<void> *createRecordedDtorBody(MockObject<C> &mock) {
return new RecordedMethodBody<void>(mock.getFakeIt(), "dtor");
}
};
}
namespace fakeit {
template<typename R, typename... Args>
struct Prototype;
template<typename R, typename... Args>
struct Prototype<R(Args...)> {
typedef R Type(Args...);
typedef R ConstType(Args...) const;
template<class C>
struct MemberType {
typedef Type(C::*type);
typedef ConstType(C::*cosntType);
static type get(type t) {
return t;
}
static cosntType getconst(cosntType t) {
return t;
}
};
};
template<int X, typename R, typename C, typename... arglist>
struct UniqueMethod {
R (C::*method)(arglist...);
UniqueMethod(R (C::*vMethod)(arglist...)) : method(vMethod) { }
int uniqueId() {
return X;
}
};
}
namespace fakeit {
namespace internal {
}
using namespace fakeit;
using namespace fakeit::internal;
template<typename C, typename ... baseclasses>
class Mock : public ActualInvocationsSource {
MockImpl<C, baseclasses...> impl;
public:
virtual ~Mock() = default;
static_assert(std::is_polymorphic<C>::value, "Can only mock a polymorphic type");
Mock() : impl(Fakeit) {
}
explicit Mock(C &obj) : impl(Fakeit, obj) {
}
virtual C &get() {
return impl.get();
}
C &operator()() {
return get();
}
void Reset() {
impl.reset();
}
template<class DATA_TYPE, typename ... arglist,
class = typename std::enable_if<std::is_member_object_pointer<DATA_TYPE C::*>::value>::type>
DataMemberStubbingRoot<C, DATA_TYPE> Stub(DATA_TYPE C::* member, const arglist &... ctorargs) {
return impl.stubDataMember(member, ctorargs...);
}
template<int id, typename R, typename T, typename ... arglist, class = typename std::enable_if<
!std::is_void<R>::value && std::is_base_of<T, C>::value>::type>
MockingContext<R, arglist...> stub(R (T::*vMethod)(arglist...) const) {
auto methodWithoutConstVolatile = reinterpret_cast<R (T::*)(arglist...)>(vMethod);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
}
template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if<
!std::is_void<R>::value && std::is_base_of<T, C>::value>::type>
MockingContext<R, arglist...> stub(R(T::*vMethod)(arglist...) volatile) {
auto methodWithoutConstVolatile = reinterpret_cast<R(T::*)(arglist...)>(vMethod);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
}
template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if<
!std::is_void<R>::value && std::is_base_of<T, C>::value>::type>
MockingContext<R, arglist...> stub(R(T::*vMethod)(arglist...) const volatile) {
auto methodWithoutConstVolatile = reinterpret_cast<R(T::*)(arglist...)>(vMethod);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
}
template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if<
!std::is_void<R>::value && std::is_base_of<T, C>::value>::type>
MockingContext<R, arglist...> stub(R(T::*vMethod)(arglist...)) {
return impl.template stubMethod<id>(vMethod);
}
template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_void<R>::value && std::is_base_of<T, C>::value>::type>
MockingContext<void, arglist...> stub(R(T::*vMethod)(arglist...) const) {
auto methodWithoutConstVolatile = reinterpret_cast<void (T::*)(arglist...)>(vMethod);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
}
template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_void<R>::value && std::is_base_of<T, C>::value>::type>
MockingContext<void, arglist...> stub(R(T::*vMethod)(arglist...) volatile) {
auto methodWithoutConstVolatile = reinterpret_cast<void (T::*)(arglist...)>(vMethod);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
}
template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_void<R>::value && std::is_base_of<T, C>::value>::type>
MockingContext<void, arglist...> stub(R(T::*vMethod)(arglist...) const volatile) {
auto methodWithoutConstVolatile = reinterpret_cast<void (T::*)(arglist...)>(vMethod);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
}
template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_void<R>::value && std::is_base_of<T, C>::value>::type>
MockingContext<void, arglist...> stub(R(T::*vMethod)(arglist...)) {
auto methodWithoutConstVolatile = reinterpret_cast<void (T::*)(arglist...)>(vMethod);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
}
DtorMockingContext dtor() {
return impl.stubDtor();
}
void getActualInvocations(std::unordered_set<Invocation *> &into) const override {
impl.getActualInvocations(into);
}
};
}
#include <exception>
namespace fakeit {
class RefCount {
private:
int count;
public:
void AddRef() {
count++;
}
int Release() {
return --count;
}
};
template<typename T>
class smart_ptr {
private:
T *pData;
RefCount *reference;
public:
smart_ptr() : pData(0), reference(0) {
reference = new RefCount();
reference->AddRef();
}
smart_ptr(T *pValue) : pData(pValue), reference(0) {
reference = new RefCount();
reference->AddRef();
}
smart_ptr(const smart_ptr<T> &sp) : pData(sp.pData), reference(sp.reference) {
reference->AddRef();
}
~smart_ptr() THROWS {
if (reference->Release() == 0) {
delete reference;
delete pData;
}
}
T &operator*() {
return *pData;
}
T *operator->() {
return pData;
}
smart_ptr<T> &operator=(const smart_ptr<T> &sp) {
if (this != &sp) {
if (reference->Release() == 0) {
delete reference;
delete pData;
}
pData = sp.pData;
reference = sp.reference;
reference->AddRef();
}
return *this;
}
};
}
namespace fakeit {
class WhenFunctor {
struct StubbingChange {
friend class WhenFunctor;
virtual ~StubbingChange() THROWS {
if (std::uncaught_exception()) {
return;
}
_xaction.commit();
}
StubbingChange(StubbingChange &other) :
_xaction(other._xaction) {
}
private:
StubbingChange(Xaction &xaction)
: _xaction(xaction) {
}
Xaction &_xaction;
};
public:
template<typename R, typename ... arglist>
struct MethodProgress : MethodStubbingProgress<R, arglist...> {
friend class WhenFunctor;
virtual ~MethodProgress() override = default;
MethodProgress(MethodProgress &other) :
_progress(other._progress), _context(other._context) {
}
MethodProgress(StubbingContext<R, arglist...> &xaction) :
_progress(new StubbingChange(xaction)), _context(xaction) {
}
protected:
virtual MethodStubbingProgress<R, arglist...> &DoImpl(Action<R, arglist...> *action) override {
_context.appendAction(action);
return *this;
}
private:
smart_ptr<StubbingChange> _progress;
StubbingContext<R, arglist...> &_context;
};
WhenFunctor() {
}
template<typename R, typename ... arglist>
MethodProgress<R, arglist...> operator()(const StubbingContext<R, arglist...> &stubbingContext) {
StubbingContext<R, arglist...> &rootWithoutConst = const_cast<StubbingContext<R, arglist...> &>(stubbingContext);
MethodProgress<R, arglist...> progress(rootWithoutConst);
return progress;
}
};
}
namespace fakeit {
class FakeFunctor {
private:
template<typename R, typename ... arglist>
void fake(const StubbingContext<R, arglist...> &root) {
StubbingContext<R, arglist...> &rootWithoutConst = const_cast<StubbingContext<R, arglist...> &>(root);
rootWithoutConst.appendAction(new ReturnDefaultValue<R, arglist...>());
rootWithoutConst.commit();
}
void operator()() {
}
public:
template<typename H, typename ... M>
void operator()(const H &head, const M &... tail) {
fake(head);
this->operator()(tail...);
}
};
}
#include <set>
#include <set>
namespace fakeit {
struct InvocationUtils {
static void sortByInvocationOrder(std::unordered_set<Invocation *> &ivocations,
std::vector<Invocation *> &result) {
auto comparator = [](Invocation *a, Invocation *b) -> bool {
return a->getOrdinal() < b->getOrdinal();
};
std::set<Invocation *, bool (*)(Invocation *a, Invocation *b)> sortedIvocations(comparator);
for (auto i : ivocations)
sortedIvocations.insert(i);
for (auto i : sortedIvocations)
result.push_back(i);
}
static void collectActualInvocations(std::unordered_set<Invocation *> &actualInvocations,
std::vector<ActualInvocationsSource *> &invocationSources) {
for (auto source : invocationSources) {
source->getActualInvocations(actualInvocations);
}
}
static void selectNonVerifiedInvocations(std::unordered_set<Invocation *> &actualInvocations,
std::unordered_set<Invocation *> &into) {
for (auto invocation : actualInvocations) {
if (!invocation->isVerified()) {
into.insert(invocation);
}
}
}
static void collectInvocationSources(std::vector<ActualInvocationsSource *> &) {
}
template<typename ... list>
static void collectInvocationSources(std::vector<ActualInvocationsSource *> &into,
const ActualInvocationsSource &mock,
const list &... tail) {
into.push_back(const_cast<ActualInvocationsSource *>(&mock));
collectInvocationSources(into, tail...);
}
static void collectSequences(std::vector<Sequence *> &) {
}
template<typename ... list>
static void collectSequences(std::vector<Sequence *> &vec, const Sequence &sequence, const list &... tail) {
vec.push_back(&const_cast<Sequence &>(sequence));
collectSequences(vec, tail...);
}
static void collectInvolvedMocks(std::vector<Sequence *> &allSequences,
std::vector<ActualInvocationsSource *> &involvedMocks) {
for (auto sequence : allSequences) {
sequence->getInvolvedMocks(involvedMocks);
}
}
template<class T>
static T &remove_const(const T &s) {
return const_cast<T &>(s);
}
};
}
#include <memory>
#include <vector>
#include <unordered_set>
namespace fakeit {
struct MatchAnalysis {
std::vector<Invocation *> actualSequence;
std::vector<Invocation *> matchedInvocations;
int count;
void run(InvocationsSourceProxy &involvedInvocationSources, std::vector<Sequence *> &expectedPattern) {
getActualInvocationSequence(involvedInvocationSources, actualSequence);
count = countMatches(expectedPattern, actualSequence, matchedInvocations);
}
private:
static void getActualInvocationSequence(InvocationsSourceProxy &involvedMocks,
std::vector<Invocation *> &actualSequence) {
std::unordered_set<Invocation *> actualInvocations;
collectActualInvocations(involvedMocks, actualInvocations);
InvocationUtils::sortByInvocationOrder(actualInvocations, actualSequence);
}
static int countMatches(std::vector<Sequence *> &pattern, std::vector<Invocation *> &actualSequence,
std::vector<Invocation *> &matchedInvocations) {
int end = -1;
int count = 0;
int startSearchIndex = 0;
while (findNextMatch(pattern, actualSequence, startSearchIndex, end, matchedInvocations)) {
count++;
startSearchIndex = end;
}
return count;
}
static void collectActualInvocations(InvocationsSourceProxy &involvedMocks,
std::unordered_set<Invocation *> &actualInvocations) {
involvedMocks.getActualInvocations(actualInvocations);
}
static bool findNextMatch(std::vector<Sequence *> &pattern, std::vector<Invocation *> &actualSequence,
int startSearchIndex, int &end,
std::vector<Invocation *> &matchedInvocations) {
for (auto sequence : pattern) {
int index = findNextMatch(sequence, actualSequence, startSearchIndex);
if (index == -1) {
return false;
}
collectMatchedInvocations(actualSequence, matchedInvocations, index, sequence->size());
startSearchIndex = index + sequence->size();
}
end = startSearchIndex;
return true;
}
static void collectMatchedInvocations(std::vector<Invocation *> &actualSequence,
std::vector<Invocation *> &matchedInvocations, int start,
int length) {
int indexAfterMatchedPattern = start + length;
for (; start < indexAfterMatchedPattern; start++) {
matchedInvocations.push_back(actualSequence[start]);
}
}
static bool isMatch(std::vector<Invocation *> &actualSequence,
std::vector<Invocation::Matcher *> &expectedSequence, int start) {
bool found = true;
for (unsigned int j = 0; found && j < expectedSequence.size(); j++) {
Invocation *actual = actualSequence[start + j];
Invocation::Matcher *expected = expectedSequence[j];
found = found && expected->matches(*actual);
}
return found;
}
static int findNextMatch(Sequence *&pattern, std::vector<Invocation *> &actualSequence, int startSearchIndex) {
std::vector<Invocation::Matcher *> expectedSequence;
pattern->getExpectedSequence(expectedSequence);
for (int i = startSearchIndex; i < ((int) actualSequence.size() - (int) expectedSequence.size() + 1); i++) {
if (isMatch(actualSequence, expectedSequence, i)) {
return i;
}
}
return -1;
}
};
}
namespace fakeit {
struct SequenceVerificationExpectation {
friend class SequenceVerificationProgress;
~SequenceVerificationExpectation() THROWS {
if (std::uncaught_exception()) {
return;
}
VerifyExpectation(_fakeit);
}
void setExpectedPattern(std::vector<Sequence *> expectedPattern) {
_expectedPattern = expectedPattern;
}
void setExpectedCount(const int count) {
_expectedCount = count;
}
void setFileInfo(std::string file, int line, std::string callingMethod) {
_file = file;
_line = line;
_testMethod = callingMethod;
}
private:
VerificationEventHandler &_fakeit;
InvocationsSourceProxy _involvedInvocationSources;
std::vector<Sequence *> _expectedPattern;
int _expectedCount;
std::string _file;
int _line;
std::string _testMethod;
bool _isVerified;
SequenceVerificationExpectation(
VerificationEventHandler &fakeit,
InvocationsSourceProxy mocks,
std::vector<Sequence *> &expectedPattern) :
_fakeit(fakeit),
_involvedInvocationSources(mocks),
_expectedPattern(expectedPattern),
_expectedCount(-1),
_line(0),
_isVerified(false) {
}
void VerifyExpectation(VerificationEventHandler &verificationErrorHandler) {
if (_isVerified)
return;
_isVerified = true;
MatchAnalysis ma;
ma.run(_involvedInvocationSources, _expectedPattern);
if (isAtLeastVerification() && atLeastLimitNotReached(ma.count)) {
return handleAtLeastVerificationEvent(verificationErrorHandler, ma.actualSequence, ma.count);
}
if (isExactVerification() && exactLimitNotMatched(ma.count)) {
return handleExactVerificationEvent(verificationErrorHandler, ma.actualSequence, ma.count);
}
markAsVerified(ma.matchedInvocations);
}
std::vector<Sequence *> &collectSequences(std::vector<Sequence *> &vec) {
return vec;
}
template<typename ... list>
std::vector<Sequence *> &collectSequences(std::vector<Sequence *> &vec, const Sequence &sequence,
const list &... tail) {
vec.push_back(&const_cast<Sequence &>(sequence));
return collectSequences(vec, tail...);
}
static void markAsVerified(std::vector<Invocation *> &matchedInvocations) {
for (auto i : matchedInvocations) {
i->markAsVerified();
}
}
bool isAtLeastVerification() {
return _expectedCount < 0;
}
bool isExactVerification() {
return !isAtLeastVerification();
}
bool atLeastLimitNotReached(int count) {
return count < -_expectedCount;
}
bool exactLimitNotMatched(int count) {
return count != _expectedCount;
}
void handleExactVerificationEvent(VerificationEventHandler &verificationErrorHandler,
std::vector<Invocation *> actualSequence, int count) {
SequenceVerificationEvent evt(VerificationType::Exact, _expectedPattern, actualSequence, _expectedCount,
count);
evt.setFileInfo(_file, _line, _testMethod);
return verificationErrorHandler.handle(evt);
}
void handleAtLeastVerificationEvent(VerificationEventHandler &verificationErrorHandler,
std::vector<Invocation *> actualSequence, int count) {
SequenceVerificationEvent evt(VerificationType::AtLeast, _expectedPattern, actualSequence, -_expectedCount,
count);
evt.setFileInfo(_file, _line, _testMethod);
return verificationErrorHandler.handle(evt);
}
};
}
namespace fakeit {
class ThrowFalseEventHandler : public VerificationEventHandler {
void handle(const SequenceVerificationEvent &) override {
throw false;
}
void handle(const NoMoreInvocationsVerificationEvent &) override {
throw false;
}
};
}
#include <string>
#include <sstream>
#include <iomanip>
namespace fakeit {
template<typename T>
static std::string to_string(const T &n) {
std::ostringstream stm;
stm << n;
return stm.str();
}
}
namespace fakeit {
struct FakeitContext;
class SequenceVerificationProgress {
friend class UsingFunctor;
friend class VerifyFunctor;
friend class UsingProgress;
smart_ptr<SequenceVerificationExpectation> _expectationPtr;
SequenceVerificationProgress(SequenceVerificationExpectation *ptr) : _expectationPtr(ptr) {
}
SequenceVerificationProgress(
FakeitContext &fakeit,
InvocationsSourceProxy sources,
std::vector<Sequence *> &allSequences) :
SequenceVerificationProgress(new SequenceVerificationExpectation(fakeit, sources, allSequences)) {
}
virtual void verifyInvocations(const int times) {
_expectationPtr->setExpectedCount(times);
}
class Terminator {
smart_ptr<SequenceVerificationExpectation> _expectationPtr;
bool toBool() {
try {
ThrowFalseEventHandler eh;
_expectationPtr->VerifyExpectation(eh);
return true;
}
catch (bool e) {
return e;
}
}
public:
Terminator(smart_ptr<SequenceVerificationExpectation> expectationPtr) : _expectationPtr(expectationPtr) { };
operator bool() {
return toBool();
}
bool operator!() const { return !const_cast<Terminator *>(this)->toBool(); }
};
public:
~SequenceVerificationProgress() THROWS { };
operator bool() {
return Terminator(_expectationPtr);
}
bool operator!() const { return !Terminator(_expectationPtr); }
Terminator Never() {
Exactly(0);
return Terminator(_expectationPtr);
}
Terminator Once() {
Exactly(1);
return Terminator(_expectationPtr);
}
Terminator Twice() {
Exactly(2);
return Terminator(_expectationPtr);
}
Terminator AtLeastOnce() {
verifyInvocations(-1);
return Terminator(_expectationPtr);
}
Terminator Exactly(const int times) {
if (times < 0) {
throw std::invalid_argument(std::string("bad argument times:").append(fakeit::to_string(times)));
}
verifyInvocations(times);
return Terminator(_expectationPtr);
}
Terminator Exactly(const Quantity &q) {
Exactly(q.quantity);
return Terminator(_expectationPtr);
}
Terminator AtLeast(const int times) {
if (times < 0) {
throw std::invalid_argument(std::string("bad argument times:").append(fakeit::to_string(times)));
}
verifyInvocations(-times);
return Terminator(_expectationPtr);
}
Terminator AtLeast(const Quantity &q) {
AtLeast(q.quantity);
return Terminator(_expectationPtr);
}
SequenceVerificationProgress setFileInfo(std::string file, int line, std::string callingMethod) {
_expectationPtr->setFileInfo(file, line, callingMethod);
return *this;
}
};
}
namespace fakeit {
class UsingProgress {
fakeit::FakeitContext &_fakeit;
InvocationsSourceProxy _sources;
void collectSequences(std::vector<fakeit::Sequence *> &) {
}
template<typename ... list>
void collectSequences(std::vector<fakeit::Sequence *> &vec, const fakeit::Sequence &sequence,
const list &... tail) {
vec.push_back(&const_cast<fakeit::Sequence &>(sequence));
collectSequences(vec, tail...);
}
public:
UsingProgress(fakeit::FakeitContext &fakeit, InvocationsSourceProxy source) :
_fakeit(fakeit),
_sources(source) {
}
template<typename ... list>
SequenceVerificationProgress Verify(const fakeit::Sequence &sequence, const list &... tail) {
std::vector<fakeit::Sequence *> allSequences;
collectSequences(allSequences, sequence, tail...);
SequenceVerificationProgress progress(_fakeit, _sources, allSequences);
return progress;
}
};
}
namespace fakeit {
class UsingFunctor {
friend class VerifyFunctor;
FakeitContext &_fakeit;
public:
UsingFunctor(FakeitContext &fakeit) : _fakeit(fakeit) {
}
template<typename ... list>
UsingProgress operator()(const ActualInvocationsSource &head, const list &... tail) {
std::vector<ActualInvocationsSource *> allMocks{&InvocationUtils::remove_const(head),
&InvocationUtils::remove_const(tail)...};
InvocationsSourceProxy aggregateInvocationsSource{new AggregateInvocationsSource(allMocks)};
UsingProgress progress(_fakeit, aggregateInvocationsSource);
return progress;
}
};
}
#include <set>
namespace fakeit {
class VerifyFunctor {
FakeitContext &_fakeit;
public:
VerifyFunctor(FakeitContext &fakeit) : _fakeit(fakeit) {
}
template<typename ... list>
SequenceVerificationProgress operator()(const Sequence &sequence, const list &... tail) {
std::vector<Sequence *> allSequences{&InvocationUtils::remove_const(sequence),
&InvocationUtils::remove_const(tail)...};
std::vector<ActualInvocationsSource *> involvedSources;
InvocationUtils::collectInvolvedMocks(allSequences, involvedSources);
InvocationsSourceProxy aggregateInvocationsSource{new AggregateInvocationsSource(involvedSources)};
UsingProgress usingProgress(_fakeit, aggregateInvocationsSource);
return usingProgress.Verify(sequence, tail...);
}
};
}
#include <set>
#include <memory>
namespace fakeit {
class VerifyNoOtherInvocationsVerificationProgress {
friend class VerifyNoOtherInvocationsFunctor;
struct VerifyNoOtherInvocationsExpectation {
friend class VerifyNoOtherInvocationsVerificationProgress;
~VerifyNoOtherInvocationsExpectation() THROWS {
if (std::uncaught_exception()) {
return;
}
VerifyExpectation(_fakeit);
}
void setFileInfo(std::string file, int line, std::string callingMethod) {
_file = file;
_line = line;
_callingMethod = callingMethod;
}
private:
VerificationEventHandler &_fakeit;
std::vector<ActualInvocationsSource *> _mocks;
std::string _file;
int _line;
std::string _callingMethod;
bool _isVerified;
VerifyNoOtherInvocationsExpectation(VerificationEventHandler &fakeit,
std::vector<ActualInvocationsSource *> mocks) :
_fakeit(fakeit),
_mocks(mocks),
_line(0),
_isVerified(false) {
}
VerifyNoOtherInvocationsExpectation(VerifyNoOtherInvocationsExpectation &other) = default;
void VerifyExpectation(VerificationEventHandler &verificationErrorHandler) {
if (_isVerified)
return;
_isVerified = true;
std::unordered_set<Invocation *> actualInvocations;
InvocationUtils::collectActualInvocations(actualInvocations, _mocks);
std::unordered_set<Invocation *> nonVerifiedInvocations;
InvocationUtils::selectNonVerifiedInvocations(actualInvocations, nonVerifiedInvocations);
if (nonVerifiedInvocations.size() > 0) {
std::vector<Invocation *> sortedNonVerifiedInvocations;
InvocationUtils::sortByInvocationOrder(nonVerifiedInvocations, sortedNonVerifiedInvocations);
std::vector<Invocation *> sortedActualInvocations;
InvocationUtils::sortByInvocationOrder(actualInvocations, sortedActualInvocations);
NoMoreInvocationsVerificationEvent evt(sortedActualInvocations, sortedNonVerifiedInvocations);
evt.setFileInfo(_file, _line, _callingMethod);
return verificationErrorHandler.handle(evt);
}
}
};
fakeit::smart_ptr<VerifyNoOtherInvocationsExpectation> _ptr;
VerifyNoOtherInvocationsVerificationProgress(VerifyNoOtherInvocationsExpectation *ptr) :
_ptr(ptr) {
}
VerifyNoOtherInvocationsVerificationProgress(FakeitContext &fakeit,
std::vector<ActualInvocationsSource *> &invocationSources)
: VerifyNoOtherInvocationsVerificationProgress(
new VerifyNoOtherInvocationsExpectation(fakeit, invocationSources)
) {
}
bool toBool() {
try {
ThrowFalseEventHandler ev;
_ptr->VerifyExpectation(ev);
return true;
}
catch (bool e) {
return e;
}
}
public:
~VerifyNoOtherInvocationsVerificationProgress() THROWS {
};
VerifyNoOtherInvocationsVerificationProgress setFileInfo(std::string file, int line,
std::string callingMethod) {
_ptr->setFileInfo(file, line, callingMethod);
return *this;
}
operator bool() {
return toBool();
}
bool operator!() const { return !const_cast<VerifyNoOtherInvocationsVerificationProgress *>(this)->toBool(); }
};
}
namespace fakeit {
class VerifyNoOtherInvocationsFunctor {
FakeitContext &_fakeit;
public:
VerifyNoOtherInvocationsFunctor(FakeitContext &fakeit) : _fakeit(fakeit) {
}
void operator()() {
}
template<typename ... list>
VerifyNoOtherInvocationsVerificationProgress operator()(const ActualInvocationsSource &head,
const list &... tail) {
std::vector<ActualInvocationsSource *> invocationSources{&InvocationUtils::remove_const(head),
&InvocationUtils::remove_const(tail)...};
VerifyNoOtherInvocationsVerificationProgress progress{_fakeit, invocationSources};
return progress;
}
};
}
namespace fakeit {
class SpyFunctor {
private:
template<typename R, typename ... arglist>
void spy(const SpyingContext<R, arglist...> &root) {
SpyingContext<R, arglist...> &rootWithoutConst = const_cast<SpyingContext<R, arglist...> &>(root);
auto methodFromOriginalVT = rootWithoutConst.getOriginalMethod();
rootWithoutConst.appendAction(new ReturnDelegateValue<R, arglist...>(methodFromOriginalVT));
rootWithoutConst.commit();
}
void operator()() {
}
public:
template<typename H, typename ... M>
void operator()(const H &head, const M &... tail) {
spy(head);
this->operator()(tail...);
}
};
}
#include <vector>
#include <set>
namespace fakeit {
class VerifyUnverifiedFunctor {
FakeitContext &_fakeit;
public:
VerifyUnverifiedFunctor(FakeitContext &fakeit) : _fakeit(fakeit) {
}
template<typename ... list>
SequenceVerificationProgress operator()(const Sequence &sequence, const list &... tail) {
std::vector<Sequence *> allSequences{&InvocationUtils::remove_const(sequence),
&InvocationUtils::remove_const(tail)...};
std::vector<ActualInvocationsSource *> involvedSources;
InvocationUtils::collectInvolvedMocks(allSequences, involvedSources);
InvocationsSourceProxy aggregateInvocationsSource{new AggregateInvocationsSource(involvedSources)};
InvocationsSourceProxy unverifiedInvocationsSource{
new UnverifiedInvocationsSource(aggregateInvocationsSource)};
UsingProgress usingProgress(_fakeit, unverifiedInvocationsSource);
return usingProgress.Verify(sequence, tail...);
}
};
class UnverifiedFunctor {
public:
UnverifiedFunctor(FakeitContext &fakeit) : Verify(fakeit) {
}
VerifyUnverifiedFunctor Verify;
template<typename ... list>
UnverifiedInvocationsSource operator()(const ActualInvocationsSource &head, const list &... tail) {
std::vector<ActualInvocationsSource *> allMocks{&InvocationUtils::remove_const(head),
&InvocationUtils::remove_const(tail)...};
InvocationsSourceProxy aggregateInvocationsSource{new AggregateInvocationsSource(allMocks)};
UnverifiedInvocationsSource unverifiedInvocationsSource{aggregateInvocationsSource};
return unverifiedInvocationsSource;
}
};
}
namespace fakeit {
static UsingFunctor Using(Fakeit);
static VerifyFunctor Verify(Fakeit);
static VerifyNoOtherInvocationsFunctor VerifyNoOtherInvocations(Fakeit);
static UnverifiedFunctor Unverified(Fakeit);
static SpyFunctor Spy;
static FakeFunctor Fake;
static WhenFunctor When;
template<class T>
class SilenceUnusedVariableWarnings {
void use(void *) {
}
SilenceUnusedVariableWarnings() {
use(&Fake);
use(&When);
use(&Spy);
use(&Using);
use(&Verify);
use(&VerifyNoOtherInvocations);
use(&_);
}
};
}
#ifdef _MSC_VER
#define __func__ __FUNCTION__
#endif
#define MOCK_TYPE(mock) \
std::remove_reference<decltype(mock.get())>::type
#define OVERLOADED_METHOD_PTR(mock, method, prototype) \
fakeit::Prototype<prototype>::MemberType<MOCK_TYPE(mock)>::get(&MOCK_TYPE(mock)::method)
#define CONST_OVERLOADED_METHOD_PTR(mock, method, prototype) \
fakeit::Prototype<prototype>::MemberType<MOCK_TYPE(mock)>::getconst(&MOCK_TYPE(mock)::method)
#define Dtor(mock) \
mock.dtor().setMethodDetails(#mock,"destructor")
#define Method(mock, method) \
mock.template stub<__COUNTER__>(&MOCK_TYPE(mock)::method).setMethodDetails(#mock,#method)
#define OverloadedMethod(mock, method, prototype) \
mock.template stub<__COUNTER__>(OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)
#define ConstOverloadedMethod(mock, method, prototype) \
mock.template stub<__COUNTER__>(CONST_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)
#define Verify(...) \
Verify( __VA_ARGS__ ).setFileInfo(__FILE__, __LINE__, __func__)
#define Using(...) \
Using( __VA_ARGS__ )
#define VerifyNoOtherInvocations(...) \
VerifyNoOtherInvocations( __VA_ARGS__ ).setFileInfo(__FILE__, __LINE__, __func__)
#define Fake(...) \
Fake( __VA_ARGS__ )
#define When(call) \
When(call)
#endif