diff options
author | Manoj Srivastava <srivasta@debian.org> | 2016-01-27 13:11:31 -0800 |
---|---|---|
committer | Manoj Srivastava <srivasta@debian.org> | 2016-01-27 13:11:31 -0800 |
commit | 02819db3483514d49df7ec3f7e372b5aeb831466 (patch) | |
tree | 6a86adac74beac293bc688dafcfa1709a6476901 /vendor/bandit/specs | |
parent | 2a61dffe127e22c1aaf955db6f085ac2eefbebba (diff) | |
parent | 6f6de67c70fd98815088ce49f046f48f88ea35bd (diff) |
Merge branch 'upstream'
Signed-off-by: Manoj Srivastava <srivasta@debian.org>
# Conflicts:
# src/CMakeLists.txt
# src/config.h
# src/lua/llimits.h
Diffstat (limited to 'vendor/bandit/specs')
35 files changed, 3433 insertions, 0 deletions
diff --git a/vendor/bandit/specs/before_each_after_each.spec.cpp b/vendor/bandit/specs/before_each_after_each.spec.cpp new file mode 100644 index 00000000..29d40574 --- /dev/null +++ b/vendor/bandit/specs/before_each_after_each.spec.cpp @@ -0,0 +1,78 @@ +#include <specs/specs.h> + +namespace bf = bandit::fakes; + +go_bandit([](){ + + describe("before_each/after_each", [&](){ + std::unique_ptr<bandit::detail::contextstack_t> context_stack; + std::unique_ptr<bf::fake_context> context; + + before_each([&](){ + context = std::unique_ptr<bf::fake_context>(new bf::fake_context()); + context_stack = std::unique_ptr<bandit::detail::contextstack_t>(new bandit::detail::contextstack_t()); + context_stack->push_back(context.get()); + }); + + describe("before_each", [&](){ + bandit::detail::voidfunc_t before_each_fn; + + before_each([&](){ + before_each_fn = [](){}; + }); + + it("registers itself for the current context in the stack", [&](){ + before_each(before_each_fn, *context_stack); + Assert::That(context->call_log(), Has().Exactly(1).EqualTo("register_before_each")); + }); + + }); + + describe("after_each", [&](){ + bandit::detail::voidfunc_t after_each_fn; + + before_each([&](){ + after_each_fn = [](){}; + }); + + it("registers itself for the current context in the stack", [&](){ + after_each(after_each_fn, *context_stack); + Assert::That(context->call_log(), Has().Exactly(1).EqualTo("register_after_each")); + }); + + }); + }); + + describe("before_each/after_each integration", [&](){ + bandit::specs::logging_fake logger; + + before_each([&](){ + logger.log() << "first before_each called" << std::endl; + }); + + before_each([&](){ + logger.log() << "second before_each called" << std::endl; + }); + + after_each([&](){ + logger.log() << "first after_each called" << std::endl; + }); + + after_each([&](){ + logger.log() << "second after_each called" << std::endl; + }); + + it("should only have called the before_each functions for the first test", [&](){ + Assert::That(logger.call_log(), Has().Exactly(1).EqualTo("first before_each called")); + Assert::That(logger.call_log(), Has().Exactly(1).EqualTo("second before_each called")); + Assert::That(logger.call_log(), Has().None().Containing("after_each")); + }); + + it("should have called 'before_each' function twice, and 'after_each' functions once for the second test", [&](){ + Assert::That(logger.call_log(), Has().Exactly(2).EqualTo("first before_each called")); + Assert::That(logger.call_log(), Has().Exactly(2).EqualTo("second before_each called")); + Assert::That(logger.call_log(), Has().Exactly(1).EqualTo("first after_each called")); + Assert::That(logger.call_log(), Has().Exactly(1).EqualTo("second after_each called")); + }); + }); +}); diff --git a/vendor/bandit/specs/context.spec.cpp b/vendor/bandit/specs/context.spec.cpp new file mode 100644 index 00000000..d517ef80 --- /dev/null +++ b/vendor/bandit/specs/context.spec.cpp @@ -0,0 +1,44 @@ +#include <specs/specs.h> + +go_bandit([](){ + + describe("bandit_context:", [&](){ + + std::unique_ptr<bandit::detail::bandit_context> context; + + before_each([&](){ + bool hard_skip = false; + context = std::unique_ptr<bandit::detail::bandit_context>( + new bandit::detail::bandit_context("context name", hard_skip)); + }); + + it("is ok to register before_each as it is not executing", [&](){ + context->register_before_each([](){}); + }); + + it("is ok to register after_each as it is not executing", [&](){ + context->register_after_each([](){}); + }); + + describe("is executing", [&](){ + + before_each([&](){ + context->execution_is_starting(); + }); + + it("is not ok to register before_each", [&](){ + AssertThrows(bandit::detail::test_run_error, context->register_before_each([](){})); + Assert::That(LastException<bandit::detail::test_run_error>().what(), + Equals("before_each was called after 'describe' or 'it'")); + }); + + it("is not ok to register after_each", [&](){ + AssertThrows(bandit::detail::test_run_error, context->register_after_each([](){})); + Assert::That(LastException<bandit::detail::test_run_error>().what(), + Equals("after_each was called after 'describe' or 'it'")); + }); + }); + + }); + +}); diff --git a/vendor/bandit/specs/describe.spec.cpp b/vendor/bandit/specs/describe.spec.cpp new file mode 100644 index 00000000..d4600a28 --- /dev/null +++ b/vendor/bandit/specs/describe.spec.cpp @@ -0,0 +1,117 @@ +#include <specs/specs.h> + +using namespace bandit::fakes; +namespace bd = bandit::detail; + +SPEC_BEGIN(describe) + + describe("describe:", [](){ + bandit::detail::voidfunc_t describe_fn; + fake_reporter_ptr reporter; + std::unique_ptr<bd::contextstack_t> context_stack; + std::unique_ptr<fake_context> global_context; + + before_each([&](){ + reporter = fake_reporter_ptr(new fake_reporter()); + + context_stack = std::unique_ptr<bd::contextstack_t>(new bd::contextstack_t()); + + global_context = std::unique_ptr<fake_context>(new fake_context()); + context_stack->push_back(global_context.get()); + }); + + + auto call_describe = [&](){ + describe("context name", describe_fn, *reporter, *context_stack); + }; + + describe("with a succeeding 'it'", [&](){ + int context_stack_size_while_running; + + before_each([&](){ + context_stack_size_while_running = 0; + describe_fn = [&](){context_stack_size_while_running = context_stack->size();}; + }); + + it("tells its parent context that execution has started", [&](){ + // This is important as once execution has started, + // before_each and after_each calls cannot be guaranteed to + // be run before any 'it' method. + + call_describe(); + AssertThat(global_context->call_log(), Has().AtLeast(1).EqualTo("execution_is_starting")); + }); + + it("tells reporter it's starting a run", [&](){ + call_describe(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("context_starting: context name")); + }); + + it("tells reporter it's finished a run", [&](){ + call_describe(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("context_ended: context name")); + }); + + it("pushes a new context during execution", [&](){ + call_describe(); + AssertThat(context_stack_size_while_running, Equals(2)); + }); + + it("pops the context from the stack after execution so that only the global context is left", [&](){ + call_describe(); + AssertThat(*context_stack, Is().OfLength(1)); + }); + + }); + + describe("with test run error", [&](){ + // + // This can occur if after_each or before_each are called + // after execution has started for a context. + // + + before_each([&](){ + describe_fn = [&](){ throw bandit::detail::test_run_error("we dun goofed!"); }; + }); + + it("doesn't propagate the error", [&](){ + call_describe(); + }); + + it("tells reporter to report the error", [&](){ + call_describe(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("test_run_error: context name (we dun goofed!)")); + }); + + }); + + describe("skip", [&](){ + bool context_is_hard_skip; + describe_fn = + [&](){ context_is_hard_skip = context_stack->back()->hard_skip(); }; + + before_each([&](){ + context_is_hard_skip = false; + }); + + describe("describe_skip", [&](){ + + it("pushes a context marked as skipped on the stack", [&](){ + describe_skip("context name", describe_fn, *reporter, *context_stack); + AssertThat(context_is_hard_skip, IsTrue()); + }); + + }); + + describe("xdescribe", [&](){ + + it("pushes a context marked as skipped on the stack", [&](){ + xdescribe("context name", describe_fn, *reporter, *context_stack); + AssertThat(context_is_hard_skip, IsTrue()); + }); + + }); + }); + }); + +SPEC_END diff --git a/vendor/bandit/specs/failure_formatters/default_formatter.spec.cpp b/vendor/bandit/specs/failure_formatters/default_formatter.spec.cpp new file mode 100644 index 00000000..6d29b694 --- /dev/null +++ b/vendor/bandit/specs/failure_formatters/default_formatter.spec.cpp @@ -0,0 +1,21 @@ +#include <specs/specs.h> +namespace bd = bandit::detail; + +go_bandit([](){ + + describe("default failure formatter", [&](){ + bd::default_failure_formatter formatter; + + it("formats assertions with file and line number", [&](){ + bd::assertion_exception exception("message", "file", 321); + AssertThat(formatter.format(exception), Equals("file:321: message")); + }); + + it("formats assertions without file and line number", [&](){ + bd::assertion_exception exception("message"); + AssertThat(formatter.format(exception), Equals("message")); + }); + + }); + +}); diff --git a/vendor/bandit/specs/failure_formatters/visual_studio_failure_formatter.spec.cpp b/vendor/bandit/specs/failure_formatters/visual_studio_failure_formatter.spec.cpp new file mode 100644 index 00000000..0d283c8e --- /dev/null +++ b/vendor/bandit/specs/failure_formatters/visual_studio_failure_formatter.spec.cpp @@ -0,0 +1,22 @@ +#include <specs/specs.h> +namespace bd = bandit::detail; + +go_bandit([](){ + + describe("Visual Studio failure formatter:", [&](){ + + bd::visual_studio_failure_formatter formatter; + + it("formats assertions with file and line number", [&](){ + bd::assertion_exception exception("message", "file", 321); + AssertThat(formatter.format(exception), Equals("file(321): message")); + }); + + it("formats assertions without file and line number", [&](){ + bd::assertion_exception exception("message"); + AssertThat(formatter.format(exception), Equals("bandit: message")); + }); + + }); + +}); diff --git a/vendor/bandit/specs/fakes/fake_context.h b/vendor/bandit/specs/fakes/fake_context.h new file mode 100644 index 00000000..e5d1d870 --- /dev/null +++ b/vendor/bandit/specs/fakes/fake_context.h @@ -0,0 +1,69 @@ +#ifndef BANDIT_FAKE_CONTEXT_H +#define BANDIT_FAKE_CONTEXT_H + +namespace bandit { namespace fakes { + + struct fake_context : public bandit::detail::context, public bandit::specs::logging_fake + { + fake_context() : hard_skip_(false), name_("fake_context"), + custom_after_each_([](){}), custom_before_each_([](){}) + {} + + const std::string& name() + { + log() << "name" << std::endl; + return name_; + } + + void execution_is_starting() + { + log() << "execution_is_starting" << std::endl; + } + + void register_before_each(detail::voidfunc_t) + { + log() << "register_before_each" << std::endl; + } + + void register_after_each(detail::voidfunc_t) + { + log() << "register_after_each" << std::endl; + } + + void run_before_eaches() + { + log() << "run_before_eaches" << std::endl; + custom_before_each_(); + } + + void run_after_eaches() + { + log() << "run_after_eaches" << std::endl; + custom_after_each_(); + } + + bool hard_skip() + { + log() << "hard_skip: returning " << hard_skip_ << std::endl; + return hard_skip_; + } + + void with_after_each(detail::voidfunc_t call) + { + custom_after_each_ = call; + } + + void with_before_each(detail::voidfunc_t call) + { + custom_before_each_ = call; + } + + private: + bool hard_skip_; + std::string name_; + detail::voidfunc_t custom_after_each_; + detail::voidfunc_t custom_before_each_; + }; +}} + +#endif diff --git a/vendor/bandit/specs/fakes/fake_reporter.h b/vendor/bandit/specs/fakes/fake_reporter.h new file mode 100644 index 00000000..032ed44d --- /dev/null +++ b/vendor/bandit/specs/fakes/fake_reporter.h @@ -0,0 +1,78 @@ +#ifndef BANDIT_SPECS_FAKE_REPORTER_H +#define BANDIT_SPECS_FAKE_REPORTER_H + +namespace bandit { namespace fakes { + struct fake_reporter : + public bandit::detail::listener, + public bandit::specs::logging_fake + { + fake_reporter() : test_run_status_(true) + {} + + void test_run_starting() + { + log() << "test_run_starting" << std::endl; + } + + void test_run_complete() + { + log() << "test_run_complete" << std::endl; + } + + void context_starting(const char* desc) + { + log() << "context_starting: " << desc << std::endl; + } + + void context_ended(const char* desc) + { + log() << "context_ended: " << desc << std::endl; + } + + void test_run_error(const char* desc, const struct bandit::detail::test_run_error& err) + { + log() << "test_run_error: " << desc << " (" << strip_newline(err.what()) << ")" << std::endl; + } + + void it_starting(const char* desc) + { + log() << "it_starting: " << desc << std::endl; + } + + void it_succeeded(const char* desc) + { + log() << "it_succeeded: " << desc << std::endl; + } + + void it_failed(const char* desc, const bandit::detail::assertion_exception& ex) + { + log() << "it_failed: " << desc << " (" << strip_newline(ex.what()) << ")" << std::endl; + } + + void it_unknown_error(const char* desc) + { + log() << "it_unknown_error: " << desc << std::endl; + } + + void it_skip(const char* desc) + { + log() << "it_skip: " << desc << std::endl; + } + + bool did_we_pass() const + { + return test_run_status_; + } + + void set_test_run_status(bool status) + { + test_run_status_ = status; + } + + private: + bool test_run_status_; + }; + typedef std::unique_ptr<fake_reporter> fake_reporter_ptr; +}} + +#endif diff --git a/vendor/bandit/specs/fakes/fakes.h b/vendor/bandit/specs/fakes/fakes.h new file mode 100644 index 00000000..a48517f6 --- /dev/null +++ b/vendor/bandit/specs/fakes/fakes.h @@ -0,0 +1,8 @@ +#ifndef BANDIT_SPECS_FAKES_H +#define BANDIT_SPECS_FAKES_H + +#include <specs/fakes/logging_fake.h> +#include <specs/fakes/fake_reporter.h> +#include <specs/fakes/fake_context.h> + +#endif diff --git a/vendor/bandit/specs/fakes/logging_fake.h b/vendor/bandit/specs/fakes/logging_fake.h new file mode 100644 index 00000000..ac1d3dd0 --- /dev/null +++ b/vendor/bandit/specs/fakes/logging_fake.h @@ -0,0 +1,32 @@ +#ifndef BANDIT_SPECS_LOGGING_FAKE_H +#define BANDIT_SPECS_LOGGING_FAKE_H +#include <sstream> + +namespace bandit { namespace specs { + + struct logging_fake + { + std::ostream& log() + { + return logstm_; + } + + std::string strip_newline(const char* val) + { + std::string no_newline = val; + std::transform(no_newline.begin(), no_newline.end(), no_newline.begin(), [](const char& c) { + return (c == '\n' || c == '\r') ? ' ' : c; + }); + return no_newline; + } + + std::string call_log() + { + return logstm_.str(); + } + + private: + std::stringstream logstm_; + }; +}} +#endif diff --git a/vendor/bandit/specs/fuzzbox.spec.cpp b/vendor/bandit/specs/fuzzbox.spec.cpp new file mode 100644 index 00000000..6515a554 --- /dev/null +++ b/vendor/bandit/specs/fuzzbox.spec.cpp @@ -0,0 +1,77 @@ +#include <specs/specs.h> + +namespace fuzzbox { + + typedef enum { + clean, + distorted + } sounds; + + struct fuzzbox + { + fuzzbox() : sound_(sounds::clean) + {} + + void flip() + { + sound_ = sounds::distorted; + } + + sounds sound() + { + return sound_; + } + + private: + sounds sound_; + }; + typedef std::unique_ptr<fuzzbox> fuzzbox_ptr; + + struct guitar + { + void add_effect(fuzzbox* effect) + { + effect_ = effect; + } + + sounds sound() + { + return effect_->sound(); + } + + private: + fuzzbox* effect_; + }; + typedef std::unique_ptr<guitar> guitar_ptr; + +go_bandit([](){ + + describe("fuzzbox:", [](){ + guitar_ptr guitar; + fuzzbox_ptr fuzzbox; + + before_each([&](){ + guitar = guitar_ptr(new struct guitar()); + fuzzbox = fuzzbox_ptr(new struct fuzzbox()); + guitar->add_effect(fuzzbox.get()); + }); + + it("starts in clean mode", [&](){ + AssertThat(guitar->sound(), Equals(sounds::clean)); + }); + + describe("in distorted mode", [&](){ + + before_each([&](){ + fuzzbox->flip(); + }); + + it("sounds distorted", [&](){ + AssertThat(guitar->sound(), Equals(sounds::distorted)); + }); + }); + }); + +}); + +} diff --git a/vendor/bandit/specs/it.spec.cpp b/vendor/bandit/specs/it.spec.cpp new file mode 100644 index 00000000..287a1ede --- /dev/null +++ b/vendor/bandit/specs/it.spec.cpp @@ -0,0 +1,355 @@ +#include <specs/specs.h> +using namespace bandit::fakes; +namespace bd = bandit::detail; + +go_bandit([](){ + describe("it:", [&](){ + bd::voidfunc_t it_func; + fake_reporter_ptr reporter; + std::unique_ptr<bd::contextstack_t> contexts; + std::unique_ptr<fake_context> context; + bandit::adapters::snowhouse_adapter assertion_adapter; + bd::run_policy_ptr run_policy; + + before_each([&](){ + reporter = fake_reporter_ptr(new fake_reporter()); + contexts = std::unique_ptr<bd::contextstack_t>(new bd::contextstack_t()); + context = std::unique_ptr<fake_context>(new fake_context()); + contexts->push_back(context.get()); + + run_policy = bd::run_policy_ptr(new bd::always_run_policy()); + }); + + auto call_it = [&]() { + it("my it", it_func, *reporter, *contexts, assertion_adapter, *run_policy); + }; + + it("tells the current context that execution has started", [&](){ + // This is important as once execution has started, + // before_each and after_each calls cannot be guaranteed to + // be run before any 'it' method. + + call_it(); + AssertThat(context->call_log(), Has().AtLeast(1).EqualTo("execution_is_starting")); + }); + + describe("with succeeding test", [&](){ + before_each([&](){ + it_func = [](){}; + }); + + it("tells reporter it's starting", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_starting: my it")); + }); + + it("tells reporter it's succeeded", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_succeeded: my it")); + }); + + it("calls before_each in context", [&](){ + call_it(); + AssertThat(context->call_log(), Has().Exactly(1).EqualTo("run_before_eaches")); + }); + + it("calls after_each in context", [&](){ + call_it(); + AssertThat(context->call_log(), Has().Exactly(1).EqualTo("run_after_eaches")); + }); + + describe("but with a failing after_each", [&](){ + + before_each([&](){ + context->with_after_each([](){ AssertThat(2, Equals(3)); }); + }); + + it("tells reporter it's failed", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_failed: my it (Expected: equal to 3 Actual: 2 )")); + }); + + it("doesn't report a succeeding test", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().None().EqualTo("it_succeeded: my it")); + }); + + it("tells run_policy that we have a failing test", [&](){ + call_it(); + AssertThat(run_policy->has_encountered_failure(), IsTrue()); + }); + }); + + describe("but with a std::exception in after_each", [&](){ + + before_each([&](){ + context->with_after_each([](){ throw std::logic_error("logic is wrong!"); }); + }); + + it("tells reporter it's failed", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_failed: my it (exception: logic is wrong!)")); + }); + + it("doesn't report a succeeding test", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().None().EqualTo("it_succeeded: my it")); + }); + + it("tells run_policy that we have a failing test", [&](){ + call_it(); + AssertThat(run_policy->has_encountered_failure(), IsTrue()); + }); + + }); + + describe("but with an unknown error in after_each", [&](){ + + before_each([&](){ + context->with_after_each([](){ throw 25; }); + }); + + it("tells reporter it's failed", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_unknown_error: my it")); + }); + + it("doesn't report a succeeding test", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().None().EqualTo("it_succeeded: my it")); + }); + + it("tells run_policy that we have a failing test", [&](){ + call_it(); + AssertThat(run_policy->has_encountered_failure(), IsTrue()); + }); + }); + + describe("but with a failing before_each", [&](){ + + before_each([&](){ + context->with_before_each([](){ AssertThat(2, Equals(3)); }); + }); + + it("tells reporter it's failed", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_failed: my it (Expected: equal to 3 Actual: 2 )")); + }); + + it("doesn't report a succeeding test", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().None().EqualTo("it_succeeded: my it")); + }); + + it("tells run_policy that we have a failing test", [&](){ + call_it(); + AssertThat(run_policy->has_encountered_failure(), IsTrue()); + }); + }); + + describe("but with a std::exception in before_each", [&](){ + + before_each([&](){ + context->with_before_each([](){ throw std::logic_error("logic is wrong!"); }); + }); + + it("tells reporter it's failed", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_failed: my it (exception: logic is wrong!)")); + }); + + it("doesn't report a succeeding test", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().None().EqualTo("it_succeeded: my it")); + }); + + it("tells run_policy that we have a failing test", [&](){ + call_it(); + AssertThat(run_policy->has_encountered_failure(), IsTrue()); + }); + }); + + describe("but with an unknown error in before_each", [&](){ + + before_each([&](){ + context->with_before_each([](){ throw 25; }); + }); + + it("tells reporter it's failed", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_unknown_error: my it")); + }); + + it("doesn't report a succeeding test", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().None().EqualTo("it_succeeded: my it")); + }); + + it("tells run_policy that we have a failing test", [&](){ + call_it(); + AssertThat(run_policy->has_encountered_failure(), IsTrue()); + }); + }); + + }); + + describe("with failing test", [&](){ + before_each([&](){ + it_func = [](){ AssertThat(3, Equals(2)); }; + }); + + it("tells reporter it's failed", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_failed: my it (Expected: equal to 2 Actual: 3 )")); + }); + + it("calls before_each in context", [&](){ + call_it(); + AssertThat(context->call_log(), Has().Exactly(1).EqualTo("run_before_eaches")); + }); + + it("calls after_each in context", [&](){ + call_it(); + AssertThat(context->call_log(), Has().Exactly(1).EqualTo("run_after_eaches")); + }); + + it("tells run_policy that we have a failing test", [&](){ + call_it(); + AssertThat(run_policy->has_encountered_failure(), IsTrue()); + }); + }); + + + describe("with crashing test", [&](){ + before_each([&](){ + it_func = [](){ throw 44; }; + }); + + it("tells reporter it's failed", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_unknown_error: my it")); + }); + + it("calls before_each in context", [&](){ + call_it(); + AssertThat(context->call_log(), Has().Exactly(1).EqualTo("run_before_eaches")); + }); + + it("calls after_each in context", [&](){ + call_it(); + AssertThat(context->call_log(), Has().Exactly(1).EqualTo("run_after_eaches")); + }); + + it("tells run_policy that we have a failing test", [&](){ + call_it(); + AssertThat(run_policy->has_encountered_failure(), IsTrue()); + }); + }); + + describe("with test throwing exception based on 'std::exception'", [&](){ + + before_each([&](){ + it_func = [](){ throw std::logic_error("logic error"); }; + }); + + it("tells reporter it's failed", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_failed: my it (exception: logic error)")); + }); + + it("calls before_each in context", [&](){ + call_it(); + AssertThat(context->call_log(), Has().Exactly(1).EqualTo("run_before_eaches")); + }); + + it("calls after_each in context", [&](){ + call_it(); + AssertThat(context->call_log(), Has().Exactly(1).EqualTo("run_after_eaches")); + }); + + it("tells run_policy that we have a failing test", [&](){ + call_it(); + AssertThat(run_policy->has_encountered_failure(), IsTrue()); + }); + + }); + + describe("it_skip", [&](){ + + it("tells reporter it's skipped", [&](){ + it_skip("my it", [](){}, *reporter); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_skip: my it")); + }); + + it("doesn't call function", [&](){ + bool called = false; + it_skip("my it", [&](){ called = true; }, *reporter); + AssertThat(called, IsFalse()); + }); + + }); + + describe("xit", [&](){ + + it("tells reporter it's skipped", [&](){ + xit("my it", [](){}, *reporter); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_skip: my it")); + }); + + it("doesn't call function", [&](){ + bool called = false; + xit("my it", [&](){ called = true; }, *reporter); + AssertThat(called, IsFalse()); + }); + + }); + + describe("with a run policy that says to skip this 'it'", [&](){ + bool it_was_called; + + before_each([&](){ + run_policy = bd::run_policy_ptr(new bd::never_run_policy()); + it_func = [&](){ it_was_called = true; }; + it_was_called = false; + }); + + it("tells reporter it's skipped", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_skip: my it")); + }); + + it("doesn't call function", [&](){ + call_it(); + AssertThat(it_was_called, IsFalse()); + }); + + }); + + describe("skipping", [&](){ + bool it_was_called; + + before_each([&](){ + it_func = [&](){ it_was_called = true; }; + it_was_called = false; + }); + + describe("with a policy that says to skip this it", [&](){ + + before_each([&](){ + run_policy = bd::run_policy_ptr(new bd::never_run_policy()); + }); + + it("tells reporter it's skipped", [&](){ + call_it(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("it_skip: my it")); + }); + + it("doesn't call function", [&](){ + call_it(); + AssertThat(it_was_called, IsFalse()); + }); + + }); + }); + }); +}); diff --git a/vendor/bandit/specs/main.cpp b/vendor/bandit/specs/main.cpp new file mode 100644 index 00000000..dde5de2d --- /dev/null +++ b/vendor/bandit/specs/main.cpp @@ -0,0 +1,6 @@ +#include <specs/specs.h> + +int main(int argc, char* argv[]) +{ + return bandit::run(argc, argv); +} diff --git a/vendor/bandit/specs/matchers/be_close_to.cpp b/vendor/bandit/specs/matchers/be_close_to.cpp new file mode 100644 index 00000000..64309673 --- /dev/null +++ b/vendor/bandit/specs/matchers/be_close_to.cpp @@ -0,0 +1,112 @@ +#include <specs/specs.h> + +using namespace bandit::Matchers; + +SPEC_BEGIN(Matchers::BeCloseTo) + +describe("be_close_to matcher", []{ + describe("when the actual value is declared as a float", [&]{ + float actualValue = 2.0 / 3.0; + + describe("and the expected value is also a float", [&]{ + float expectedValue; + + describe("with an explicit threshold", [&]{ + float threshold = 0.1; + + describe("and the values are within the given threshold", [&]{ + before_each([&]{ + expectedValue = 2.0 / 3.0 + 0.01; + }); + + it("must accept a positive match", [&]{ + actualValue must be_close_to(expectedValue).within(threshold); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not be_close_to(expectedValue).within(threshold); }()); + }); + }); + + describe("and the values are not within the given threshold", [&]{ + before_each([&]{ + expectedValue = 2.0 / 3.0 + 0.2; + }); + + it("must accept a negative match", [&]{ + actualValue must_not be_close_to(expectedValue).within(threshold); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must be_close_to(expectedValue).within(threshold); }()); + }); + }); + }); + + describe("without an explicit threshold", [&]{ + describe("and the values are within the default threshold", [&]{ + before_each([&]{ + expectedValue = 2.0 / 3.0 + 0.000001; + }); + + it("must accept a positive match", [&]{ + actualValue must be_close_to(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not be_close_to(expectedValue); }()); + }); + }); + + describe("and the values are not within the default threshold", [&]{ + before_each([&]{ + expectedValue = 2.0 / 3.0 + 0.1; + }); + + it("must accept a negative match", [&]{ + actualValue must_not be_close_to(expectedValue); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must be_close_to(expectedValue); }()); + }); + }); + }); + }); + + describe("and the expected value is a compatible non-float type", [&]{ + int expectedValue; + float threshold = 1; + + describe("and the values are within the given threshold", [&]{ + before_each([&]{ + expectedValue = 1; + }); + + it("must accept a positive match", [&]{ + actualValue must be_close_to(expectedValue).within(threshold); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not be_close_to(expectedValue).within(threshold); }()); + }); + }); + + describe("and the values are not within the given threshold", [&]{ + before_each([&]{ + expectedValue = 5; + }); + + it("must accept a negative match", [&]{ + actualValue must_not be_close_to(expectedValue).within(threshold); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must be_close_to(expectedValue).within(threshold); }()); + }); + }); + }); + }); +}); + +SPEC_END diff --git a/vendor/bandit/specs/matchers/be_empty.cpp b/vendor/bandit/specs/matchers/be_empty.cpp new file mode 100644 index 00000000..3ed4a6f9 --- /dev/null +++ b/vendor/bandit/specs/matchers/be_empty.cpp @@ -0,0 +1,89 @@ +#include <set> + +#include <specs/specs.h> + +using namespace bandit::Matchers; + +SPEC_BEGIN(Matchers::BeEmpty) + +describe("be_empty matcher", [&]{ + describe("when the value is an STL vector", [&]{ + describe("which is empty", [&]{ + std::vector<int> container; + + it("must pass a positive match", [&]{ + container must be_empty; + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ container must_not be_empty; }()); + }); + }); + + describe("which is not empty", [&]{ + std::vector<int> container {2, 7}; + + it("must pass a negative match", [&]{ + container must_not be_empty; + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ container must be_empty; }()); + }); + }); + }); + + describe("when the value is an STL map", [&]{ + describe("which is empty", [&]{ + std::map<int, int> container; + + it("must pass a positive match", [&]{ + container must be_empty; + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ container must_not be_empty; }()); + }); + }); + + describe("which is not empty", [&]{ + std::map<int, int> container {{5, 6}, {7,10}}; + + it("must pass a negative match", [&]{ + container must_not be_empty; + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ container must be_empty; }()); + }); + }); + }); + + describe("when the value is an STL set", [&]{ + describe("which is empty", [&]{ + std::set<int> container; + + it("must pass a positive match", [&]{ + container must be_empty; + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ container must_not be_empty; }()); + }); + }); + + describe("which is not empty", [&]{ + std::set<int> container {5, 7}; + + it("must pass a negative match", [&]{ + container must_not be_empty; + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ container must be_empty; }()); + }); + }); + }); +}); + +SPEC_END diff --git a/vendor/bandit/specs/matchers/be_falsy.cpp b/vendor/bandit/specs/matchers/be_falsy.cpp new file mode 100644 index 00000000..d8c71c1b --- /dev/null +++ b/vendor/bandit/specs/matchers/be_falsy.cpp @@ -0,0 +1,85 @@ +#include <specs/specs.h> + +using namespace bandit::Matchers; + +SPEC_BEGIN(Matchers::BeFalsy) + +describe("be_falsy matcher", [&]{ + describe("when the value is a built-in type", [&]{ + bool value; + + describe("which evaluates to false", [&]{ + before_each([&]{ + value = false; + }); + + it("must accept a positive match", [&]{ + value must be_falsy; + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ value must_not be_falsy; }()); + }); + }); + + describe("which evaluates to true", [&]{ + before_each([&]{ + value = true; + }); + + it("must accept a negative match", [&]{ + value must_not be_falsy; + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ value must be_falsy; }()); + }); + }); + }); + + describe("when the value is nullptr", [&]{ + auto value = nullptr; + + it("must accept a positive match", [&]{ + value must be_falsy; + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ value must_not be_falsy; }()); + }); + }); + + describe("when the value is a pointer", [&]{ + char* value; + + describe("which evaluates to false", [&]{ + before_each([&]{ + value = NULL; + }); + + it("must accept a positive match", [&]{ + value must be_falsy; + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ value must_not be_falsy; }()); + }); + }); + + describe("which evaluates to true", [&]{ + before_each([&]{ + value = (char*)"cat"; + }); + + it("must accept a negative match", [&]{ + value must_not be_falsy; + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ value must be_falsy; }()); + }); + }); + }); +}); + +SPEC_END diff --git a/vendor/bandit/specs/matchers/be_greater_than.cpp b/vendor/bandit/specs/matchers/be_greater_than.cpp new file mode 100644 index 00000000..17a97fe3 --- /dev/null +++ b/vendor/bandit/specs/matchers/be_greater_than.cpp @@ -0,0 +1,105 @@ +#include <specs/specs.h> + +using namespace bandit::Matchers; + +SPEC_BEGIN(Matchers::BeGreaterThan) + +describe("be_greater_than matcher", []{ + describe("when the actual value is a built-in type", [&]{ + int actualValue = 10; + + describe("and the expected value is the same built-in type", [&]{ + int expectedValue; + + describe("and the actual value is greater than the expected value", [&]{ + before_each([&]{ + expectedValue = 1; + }); + + it("must pass a positive match", [&]{ + actualValue must be_greater_than(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not be_greater_than(expectedValue); }()); + }); + }); + + describe("and the actual value is less than the expected value", [&]{ + before_each([&]{ + expectedValue = 100; + }); + + it("must pass a negative match", [&]{ + actualValue must_not be_greater_than(expectedValue); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must be_greater_than(expectedValue); }()); + }); + }); + + describe("and the actual value equals the expected value", [&]{ + before_each([&]{ + expectedValue = actualValue; + }); + + it("must pass a negative match", [&]{ + actualValue must_not be_greater_than(expectedValue); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must be_greater_than(expectedValue); }()); + }); + }); + }); + + describe("and the expected value is a different, but comparable, built-in type", [&]{ + float expectedValue; + + describe("and the actual value is greater than the expected value", [&]{ + before_each([&]{ + expectedValue = 1.1; + }); + + it("must pass a positive match", [&]{ + actualValue must be_greater_than(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not be_greater_than(expectedValue); }()); + }); + }); + + describe("and the actual value is less than the expected value", [&]{ + before_each([&]{ + expectedValue = 100.1; + }); + + it("must pass a negative match", [&]{ + actualValue must_not be_greater_than(expectedValue); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must be_greater_than(expectedValue); }()); + }); + }); + + describe("and the actual value equals the expected value", [&]{ + before_each([&]{ + expectedValue = actualValue; + }); + + it("must pass a negative match", [&]{ + actualValue must_not be_greater_than(expectedValue); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must be_greater_than(expectedValue); }()); + }); + }); + }); + }); +}); + +SPEC_END diff --git a/vendor/bandit/specs/matchers/be_gte.cpp b/vendor/bandit/specs/matchers/be_gte.cpp new file mode 100644 index 00000000..f0e18313 --- /dev/null +++ b/vendor/bandit/specs/matchers/be_gte.cpp @@ -0,0 +1,120 @@ +#include <specs/specs.h> + +using namespace bandit::Matchers; + + +SPEC_BEGIN(Matchers::BeGTE) + +describe("be_gte matcher", [&]{ + int someInteger = 10; + + describe("when the actual value is a built-in type", [&]{ + int actualValue = someInteger; + + describe("and the expected value is the same built-in type", [&]{ + int expectedValue; + + describe("and the actual value is greater than the expected value", [&]{ + before_each([&]{ + expectedValue = 1; + }); + + it("must pass a positive match", [&]{ + actualValue must be_gte(expectedValue); + actualValue must be_greater_than_or_equal_to(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not be_gte(expectedValue); }()); + AssertThrows(std::exception, [&]{ actualValue must_not be_greater_than_or_equal_to(expectedValue); }()); + }); + }); + + describe("and the actual value is less than the expected value", [&]{ + before_each([&]{ + expectedValue = 100; + }); + + it("must pass a negative match", [&]{ + actualValue must_not be_gte(expectedValue); + actualValue must_not be_greater_than_or_equal_to(expectedValue); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must be_gte(expectedValue); }()); + AssertThrows(std::exception, [&]{ actualValue must be_greater_than_or_equal_to(expectedValue); }()); + }); + }); + + describe("and the actual value equals the expected value", [&]{ + before_each([&]{ + expectedValue = actualValue; + }); + + it("must pass a positive match", [&]{ + actualValue must be_gte(expectedValue); + actualValue must be_greater_than_or_equal_to(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not be_gte(expectedValue); }()); + AssertThrows(std::exception, [&]{ actualValue must_not be_greater_than_or_equal_to(expectedValue); }()); + }); + }); + }); + + describe("and the expected value is a different, but comparable, built-in type", [&]{ + float expectedValue; + + describe("and the actual value is greater than the expected value", [&]{ + before_each([&]{ + expectedValue = 1.1; + }); + + it("must pass a positive match", [&]{ + actualValue must be_gte(expectedValue); + actualValue must be_greater_than_or_equal_to(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not be_gte(expectedValue); }()); + AssertThrows(std::exception, [&]{ actualValue must_not be_greater_than_or_equal_to(expectedValue); }()); + }); + }); + + describe("and the actual value is less than the expected value", [&]{ + before_each([&]{ + expectedValue = 100.1; + }); + + it("must pass a negative match", [&]{ + actualValue must_not be_gte(expectedValue); + actualValue must_not be_greater_than_or_equal_to(expectedValue); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must be_gte(expectedValue); }()); + AssertThrows(std::exception, [&]{ actualValue must be_greater_than_or_equal_to(expectedValue); }()); + }); + }); + + describe("and the actual value equals the expected value", [&]{ + before_each([&]{ + expectedValue = someInteger / 1.0; + }); + + it("must pass a positive match", [&]{ + actualValue must be_gte(expectedValue); + actualValue must be_greater_than_or_equal_to(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not be_gte(expectedValue); }()); + AssertThrows(std::exception, [&]{ actualValue must_not be_greater_than_or_equal_to(expectedValue); }()); + }); + }); + }); + }); +}); + +SPEC_END diff --git a/vendor/bandit/specs/matchers/be_less_than.cpp b/vendor/bandit/specs/matchers/be_less_than.cpp new file mode 100644 index 00000000..30f60c47 --- /dev/null +++ b/vendor/bandit/specs/matchers/be_less_than.cpp @@ -0,0 +1,105 @@ +#include <specs/specs.h> + +using namespace bandit::Matchers; + +SPEC_BEGIN(Matchers::BeLessThan) + +describe("be_less_than matcher", []{ + describe("when the actual value is a built-in type", [&]{ + int actualValue = 10; + + describe("and the expected value is the same built-in type", [&]{ + int expectedValue; + + describe("and the actual value is greater than the expected value", [&]{ + before_each([&]{ + expectedValue = 1; + }); + + it("must pass a negative match", [&]{ + actualValue must_not be_less_than(expectedValue); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must be_less_than(expectedValue); }()); + }); + }); + + describe("and the actual value is less than the expected value", [&]{ + before_each([&]{ + expectedValue = 100; + }); + + it("must pass a positive match", [&]{ + actualValue must be_less_than(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not be_less_than(expectedValue); }()); + }); + }); + + describe("and the actual value equals the expected value", [&]{ + before_each([&]{ + expectedValue = actualValue; + }); + + it("must pass a negative match", [&]{ + actualValue must_not be_less_than(expectedValue); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must be_less_than(expectedValue); }()); + }); + }); + }); + + describe("and the expected value is a different, but comparable, built-in type", [&]{ + float expectedValue; + + describe("and the actual value is greater than the expected value", [&]{ + before_each([&]{ + expectedValue = 1.1; + }); + + it("must pass a negative match", [&]{ + actualValue must_not be_less_than(expectedValue); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must be_less_than(expectedValue); }()); + }); + }); + + describe("and the actual value is less than the expected value", [&]{ + before_each([&]{ + expectedValue = 100.1; + }); + + it("must pass a positive match", [&]{ + actualValue must be_less_than(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not be_less_than(expectedValue); }()); + }); + }); + + describe("and the actual value equals the expected value", [&]{ + before_each([&]{ + expectedValue = actualValue; + }); + + it("must pass a negative match", [&]{ + actualValue must_not be_less_than(expectedValue); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must be_less_than(expectedValue); }()); + }); + }); + }); + }); +}); + +SPEC_END diff --git a/vendor/bandit/specs/matchers/be_lte.cpp b/vendor/bandit/specs/matchers/be_lte.cpp new file mode 100644 index 00000000..443ac1c5 --- /dev/null +++ b/vendor/bandit/specs/matchers/be_lte.cpp @@ -0,0 +1,119 @@ +#include <specs/specs.h> + +using namespace bandit::Matchers; + +SPEC_BEGIN(Matchers::BeLTE) + +describe("be_lte matcher", [&]{ + int someInteger = 10; + + describe("when the actual value is a built-in type", [&]{ + int actualValue = someInteger; + + describe("and the expected value is the same built-in type", [&]{ + int expectedValue; + + describe("and the actual value is greater than the expected value", [&]{ + before_each([&]{ + expectedValue = 1; + }); + + it("must pass a negative match", [&]{ + actualValue must_not be_lte(expectedValue); + actualValue must_not be_less_than_or_equal_to(expectedValue); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must be_lte(expectedValue); }()); + AssertThrows(std::exception, [&]{ actualValue must be_less_than_or_equal_to(expectedValue); }()); + }); + }); + + describe("and the actual value is less than the expected value", [&]{ + before_each([&]{ + expectedValue = 100; + }); + + it("must pass a positive match", [&]{ + actualValue must be_lte(expectedValue); + actualValue must be_less_than_or_equal_to(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not be_lte(expectedValue); }()); + AssertThrows(std::exception, [&]{ actualValue must_not be_less_than_or_equal_to(expectedValue); }()); + }); + }); + + describe("and the actual value equals the expected value", [&]{ + before_each([&]{ + expectedValue = actualValue; + }); + + it("must pass a positive match", [&]{ + actualValue must be_lte(expectedValue); + actualValue must be_less_than_or_equal_to(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not be_lte(expectedValue); }()); + AssertThrows(std::exception, [&]{ actualValue must_not be_less_than_or_equal_to(expectedValue); }()); + }); + }); + }); + + describe("and the expected value is a different, but comparable, built-in type", [&]{ + float expectedValue; + + describe("and the actual value is greater than the expected value", [&]{ + before_each([&]{ + expectedValue = 1.1; + }); + + it("must pass a negative match", [&]{ + actualValue must_not be_lte(expectedValue); + actualValue must_not be_less_than_or_equal_to(expectedValue); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must be_lte(expectedValue); }()); + AssertThrows(std::exception, [&]{ actualValue must be_less_than_or_equal_to(expectedValue); }()); + }); + }); + + describe("and the actual value is less than the expected value", [&]{ + before_each([&]{ + expectedValue = 100.1; + }); + + it("must pass a positive match", [&]{ + actualValue must be_lte(expectedValue); + actualValue must be_less_than_or_equal_to(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not be_lte(expectedValue); }()); + AssertThrows(std::exception, [&]{ actualValue must_not be_less_than_or_equal_to(expectedValue); }()); + }); + }); + + describe("and the actual value equals the expected value", [&]{ + before_each([&]{ + expectedValue = someInteger / 1.0; + }); + + it("must pass a positive match", [&]{ + actualValue must be_lte(expectedValue); + actualValue must be_less_than_or_equal_to(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not be_lte(expectedValue); }()); + AssertThrows(std::exception, [&]{ actualValue must_not be_less_than_or_equal_to(expectedValue); }()); + }); + }); + }); + }); +}); + +SPEC_END diff --git a/vendor/bandit/specs/matchers/be_null.cpp b/vendor/bandit/specs/matchers/be_null.cpp new file mode 100644 index 00000000..ae3cd40d --- /dev/null +++ b/vendor/bandit/specs/matchers/be_null.cpp @@ -0,0 +1,43 @@ +#include <specs/specs.h> + +using namespace bandit::Matchers; + +SPEC_BEGIN(Matchers::BeNull) + +describe("be_null matcher", [&]{ + describe("when the value is a pointer to a built-in type", [&]{ + int* value; + + describe("which is NULL", [&]{ + before_each([&]{ + value = NULL; + }); + + it("must pass a positive match", [&]{ + value must be_null; + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ value must_not be_null; }()); + }); + }); + + describe("which is not NULL", [&]{ + int i = 7; + + before_each([&]{ + value = &i; + }); + + it("must pass a negative match", [&]{ + value must_not be_null; + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ value must be_null; }()); + }); + }); + }); +}); + +SPEC_END diff --git a/vendor/bandit/specs/matchers/be_truthy.cpp b/vendor/bandit/specs/matchers/be_truthy.cpp new file mode 100644 index 00000000..5e583fbf --- /dev/null +++ b/vendor/bandit/specs/matchers/be_truthy.cpp @@ -0,0 +1,85 @@ +#include <specs/specs.h> + +using namespace bandit::Matchers; + +SPEC_BEGIN(Matchers::BeTruthy) + +describe("be_truthy matcher", [&]{ + describe("when the value is a built-in type", [&]{ + bool value; + + describe("which evaluates to false", [&]{ + before_each([&]{ + value = false; + }); + + it("must accept a negative match", [&]{ + value must_not be_truthy; + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ value must be_truthy; }()); + }); + }); + + describe("which evaluates to true", [&]{ + before_each([&]{ + value = true; + }); + + it("must accept a positive match", [&]{ + value must be_truthy; + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ value must_not be_truthy; }()); + }); + }); + }); + + describe("when the value is nullptr", [&]{ + auto value = nullptr; + + it("must accept a negative match", [&]{ + value must_not be_truthy; + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ value must be_truthy; }()); + }); + }); + + describe("when the value is a pointer", [&]{ + char* value; + + describe("which evaluates to false", [&]{ + before_each([&]{ + value = NULL; + }); + + it("must accept a negative match", [&]{ + value must_not be_truthy; + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ value must be_truthy; }()); + }); + }); + + describe("which evaluates to true", [&]{ + before_each([&]{ + value = (char*)"cat"; + }); + + it("must accept a positive match", [&]{ + value must be_truthy; + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ value must_not be_truthy; }()); + }); + }); + }); +}); + +SPEC_END diff --git a/vendor/bandit/specs/matchers/contain.cpp b/vendor/bandit/specs/matchers/contain.cpp new file mode 100644 index 00000000..2c0b4b3b --- /dev/null +++ b/vendor/bandit/specs/matchers/contain.cpp @@ -0,0 +1,156 @@ +#include <set> + +#include <specs/specs.h> + +using namespace bandit::Matchers; + +SPEC_BEGIN(Matchers::Contain) + +describe("contain matcher", [&]{ + std::string element0("element0"); + std::string element1("element1"); + + describe("when the container is an STL vector", [&]{ + describe("which contains the element", [&]{ + std::vector<std::string> container {element0, element1}; + + it("must pass a positive match", [&]{ + container must contain(element1); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ container must_not contain(element1); }()); + }); + }); + + describe("which does not contain the element", [&]{ + std::vector<int> container; + + it("must pass a negative match", [&]{ + container must_not contain(4); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ container must contain(4); }()); + }); + }); + }); + + describe("when the container is an STL map", [&]{ + describe("which contains the expected key", [&]{ + std::map<int, int> container {{5, 6}, {7,10}}; + + it("must pass a positive match", [&]{ + container must contain(5); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ container must_not contain(5); }()); + }); + }); + + describe("which does not contain the expected value", [&]{ + std::map<int, int> container; + + it("must pass a negative match", [&]{ + container must_not contain(6); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ container must contain(6); }()); + }); + }); + }); + + describe("when the container is an STL set", [&]{ + describe("which contains the element", [&]{ + std::set<int> container {5, 7}; + + it("must pass a positive match", [&]{ + container must contain(7); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ container must_not contain(7); }()); + }); + }); + + describe("which does not contain the element", [&]{ + std::set<int> container; + + it("must pass a negative match", [&]{ + container must_not contain(7); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ container must contain(7); }()); + }); + }); + }); + + describe("when the container is a C string", [&]{ + describe("which is null", [&]{ + char* container = NULL; + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ container must contain("foo"); }()); + }); + }); + + describe("which contains the substring", [&]{ + char* container = (char*)"jack and jill"; + char* element = (char*)"jack"; + + it("must pass a positive match", [&]{ + container must contain(element); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ container must_not contain(element); }()); + }); + }); + + describe("which does not contain the substring", [&]{ + char* container = (char*)"batman and robin"; + char* element = (char*)"catwoman"; + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ container must contain(element); }()); + }); + + it("must pass a negative match", [&]{ + container must_not contain(element); + }); + }); + }); + + describe("when the container is a const C string", [&]{ + describe("which contains the substring", [&]{ + const char* container = (char*)"jack and jill"; + const char* element = (char*)"jack"; + + it("must pass a positive match", [&]{ + container must contain(element); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ container must_not contain(element); }()); + }); + }); + + describe("which does not contain the substring", [&]{ + const char* container = (char*)"batman and robin"; + const char* element = (char*)"catwoman"; + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ container must contain(element); }()); + }); + + it("must pass a negative match", [&]{ + container must_not contain(element); + }); + }); + }); +}); + +SPEC_END diff --git a/vendor/bandit/specs/matchers/equal.cpp b/vendor/bandit/specs/matchers/equal.cpp new file mode 100644 index 00000000..f7f31b0b --- /dev/null +++ b/vendor/bandit/specs/matchers/equal.cpp @@ -0,0 +1,214 @@ +#include <specs/specs.h> + +using namespace bandit::Matchers; + +SPEC_BEGIN(Matchers::Equal) + +describe("when the actual value is a built-in type", []{ + int actualValue = 1; + + describe("and the expected value is the same built-in type", [&]{ + int expectedValue; + + describe("and the values are equal", [&]{ + before_each([&]{ + expectedValue = 1; + }); + + it("must accept a positive match", [&]{ + actualValue must equal(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not equal(expectedValue); }()); + }); + }); + + describe("and the values are not equal", [&]{ + before_each([&]{ + expectedValue = 147; + }); + + it("must accept a negative match", [&]{ + actualValue must_not equal(expectedValue); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must equal(expectedValue); }()); + }); + }); + }); + + describe("and the expected value is a different, but comparable, built-in type", [&]{ + long int expectedValue; + + describe("and the values are equal", [&]{ + before_each([&]{ + expectedValue = 1; + }); + + it("must accept a positive match", [&]{ + actualValue must equal(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not equal(expectedValue); }()); + }); + }); + + describe("and the values are not equal", [&]{ + before_each([&]{ + expectedValue = 42; + }); + + it("must accept a negative match", [&]{ + actualValue must_not equal(expectedValue); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must equal(expectedValue); }()); + }); + }); + }); +}); + +describe("when the actual value is declared as a C string", []{ + char* actualValue = (char*)"actualValue"; + + describe("and the expected value is declared as a C string", [&]{ + std::unique_ptr<char> expectedValue; + + before_each([&]{ + expectedValue.reset((char*)calloc(strlen(actualValue) + 1, sizeof(char))); + }); + + describe("and the values are equal", [&]{ + before_each([&]{ + stpcpy(expectedValue.get(), actualValue); + }); + + it("must accept a positive match", [&]{ + actualValue must equal(expectedValue.get()); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not equal(expectedValue.get()); }()); + }); + }); + + describe("and the values are not equal", [&]{ + before_each([&]{ + stpcpy(expectedValue.get(), "expectedVal"); + }); + + it("must accept a negative match", [&]{ + actualValue must_not equal(expectedValue.get()); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must equal(expectedValue.get()); }()); + }); + }); + }); + + describe("and the expected value is declared as a const C string", [&]{ + const char *expectedValue; + + describe("and the values are equal", [&]{ + before_each([&]{ + expectedValue = "actualValue"; + }); + + it("must accept a positive match", [&]{ + actualValue must equal(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not equal(expectedValue); }()); + }); + }); + }); + + describe("when the expected value is a unique_ptr to a C string", [&]{ + std::unique_ptr<char> expectedValue; + + before_each([&]{ + expectedValue.reset((char*)calloc(strlen(actualValue) + 1, sizeof(char))); + }); + + describe("and the values are equal", [&]{ + before_each([&]{ + stpcpy(expectedValue.get(), actualValue); + }); + + it("must accept a positive match", [&]{ + actualValue must equal(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not equal(expectedValue); }()); + }); + }); + }); +}); + +describe("when the actual value is a unique_ptr", []{ + std::unique_ptr<char> actualValue; + auto expectedValue = (char*)"expectedValue"; + + before_each([&]{ + actualValue.reset((char*)calloc(strlen(expectedValue) + 1, sizeof(char))); + }); + + describe("when the strings are equal", [&]{ + before_each([&]{ + stpcpy(actualValue.get(), expectedValue); + }); + + it("must accept a positive match", [&]{ + actualValue must equal(expectedValue); + }); + }); + + describe("when the strings are not equal", [&]{ + before_each([&]{ + stpcpy(actualValue.get(), "hello"); + }); + + it("must accept a negative match", [&]{ + actualValue must_not equal(expectedValue); + }); + }); +}); + +describe("when the actual value is declared as char array", []{ + describe("and the expected value is declared as a C string", []{ + char actualValue[] = "actualValue"; + + describe("and the values are equal", [&]{ + char* expectedValue = (char*)"actualValue"; + + it("must accept a positive match", [&]{ + actualValue must equal(expectedValue); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must_not equal(expectedValue); }()); + }); + }); + + describe("and the values are not equal", [&]{ + char* expectedValue = (char*)"expectedValue"; + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ actualValue must equal(expectedValue); }()); + }); + + it("must accept a negative match", [&]{ + actualValue must_not equal(expectedValue); + }); + }); + }); +}); + +SPEC_END
\ No newline at end of file diff --git a/vendor/bandit/specs/matchers/throw_exception.cpp b/vendor/bandit/specs/matchers/throw_exception.cpp new file mode 100644 index 00000000..c7531d5f --- /dev/null +++ b/vendor/bandit/specs/matchers/throw_exception.cpp @@ -0,0 +1,104 @@ +#include <specs/specs.h> + +using namespace bandit::Matchers; + +SPEC_BEGIN(Matchers::ThrowException) + +describe("throw_exception", []{ + describe("when no exception is specified", [&]{ + std::exception exception; + + std::function<void()> exception_block = [&]{ throw exception; }; + + describe("when the block throws an exception", [&]{ + it("must pass a positive match", [&]{ + exception_block must throw_exception; + }); + + it("must reject a negative match", [&]{ + AssertThrows(MatcherException, [&]{ exception_block must_not throw_exception; }()); + }); + }); + + describe("when the block does not throw an exception", [&]{ + std::function<void()> quiet_block = [&]{}; + + it("must pass a negative match", [&]{ + quiet_block must_not throw_exception; + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ quiet_block must throw_exception; }()); + }); + }); + }); + + describe("with an exception class specified", [&]{ + std::logic_error expected_exception("logic_error"); + + describe("when the block throws the expected exception", [&]{ + std::function<void()> exception_block = [&]{ throw expected_exception; }; + + it("must pass a positive match", [&]{ + exception_block must throw_exception.operator()<decltype(expected_exception)>(); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ exception_block must_not throw_exception.operator()<decltype(expected_exception)>(); }()); + }); + }); + + // TODO: Because C++ lacks reflection, there's no way to implement + // subclass-checking. I'm leaving these tests here for when the + // language has evolved sufficiently. + xdescribe("when the block throws a sublass of the specified exception", [&]{ + std::function<void()> subclass_block = [&]{ throw std::invalid_argument("invalid argument"); }; + + describe("when subclasses are expected", [&]{ + it("must pass a positive match", [&]{ + subclass_block must throw_exception.operator()<std::logic_error>().or_subclass(); + }); + + it("must reject a negative match", [&]{ + AssertThrows(std::exception, [&]{ subclass_block must_not throw_exception.operator()<std::logic_error>().or_subclass(); }()); + }); + }); + + describe("when subclasses are not expected", [&]{ + it("must pass a negative match", [&]{ + subclass_block must_not throw_exception.operator()<std::logic_error>(); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ subclass_block must throw_exception.operator()<std::logic_error>(); }()); + }); + }); + }); + + describe("when the block throws an unrelated exception", [&]{ + std::function<void()> unrelated_block = [&]{ throw std::range_error("range error"); }; + + it("must pass a negative match", [&]{ + unrelated_block must_not throw_exception.operator()<decltype(expected_exception)>(); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ unrelated_block must throw_exception.operator()<decltype(expected_exception)>(); }()); + }); + }); + + describe("when the block does not throw an exception", [&]{ + std::function<void()> quiet_block = [&]{}; + + it("must pass a negative match", [&]{ + quiet_block must_not throw_exception.operator()<decltype(expected_exception)>(); + }); + + it("must reject a positive match", [&]{ + AssertThrows(std::exception, [&]{ quiet_block must throw_exception.operator()<decltype(expected_exception)>(); }()); + }); + }); + }); +}); + +SPEC_END diff --git a/vendor/bandit/specs/options.spec.cpp b/vendor/bandit/specs/options.spec.cpp new file mode 100644 index 00000000..74d057ec --- /dev/null +++ b/vendor/bandit/specs/options.spec.cpp @@ -0,0 +1,121 @@ +#include <specs/specs.h> + +using namespace bandit::specs::util; +namespace bd = bandit::detail; + +go_bandit([](){ + + describe("options:", [&](){ + + it("parses the '--help' option", [&](){ + const char* args[] = {"executable", "--help"}; + argv_helper argv(2, args); + + bd::options opt(argv.argc(), argv.argv()); + + AssertThat(opt.help(), IsTrue()); + }); + + it("parses the '--version' option", [&](){ + const char* args[] = {"executable", "--version"}; + argv_helper argv(2, args); + + bd::options opt(argv.argc(), argv.argv()); + + AssertThat(opt.version(), IsTrue()); + }); + + it("parses the '--no-color' option", [&](){ + const char* args[] = {"executable", "--no-color"}; + argv_helper argv(2, args); + + bd::options opt(argv.argc(), argv.argv()); + + AssertThat(opt.no_color(), IsTrue()); + }); + + it("parser the '--formatter=vs' option", [&](){ + const char* args[] = {"executable", "--formatter=vs"}; + argv_helper argv(2, args); + + bd::options opt(argv.argc(), argv.argv()); + AssertThat(opt.formatter(), Equals(bd::options::formatters::FORMATTER_VS)); + }); + + it("parser the '--formatter=default' option", [&](){ + const char* args[] = {"executable", "--formatter=default"}; + argv_helper argv(2, args); + + bd::options opt(argv.argc(), argv.argv()); + AssertThat(opt.formatter(), Equals(bd::options::formatters::FORMATTER_DEFAULT)); + }); + + it("parses the '--skip=\"substring\"' option", [&](){ + const char* args[] = {"executable", "--skip=substring"}; + argv_helper argv(2, args); + + bd::options opt(argv.argc(), argv.argv()); + AssertThat(opt.skip(), Equals("substring")); + }); + + it("parses skip as empty string if not present", [&](){ + const char* args[] = {"executable"}; + argv_helper argv(1, args); + + bd::options opt(argv.argc(), argv.argv()); + AssertThat(opt.skip(), Equals("")); + }); + + it("parses the '--only=\"substring\"' option", [&](){ + const char* args[] = {"executable", "--only=substring"}; + argv_helper argv(2, args); + + bd::options opt(argv.argc(), argv.argv()); + AssertThat(opt.only(), Equals("substring")); + }); + + it("parses only as empty string if not present", [&](){ + const char* args[] = {"executable"}; + argv_helper argv(1, args); + + bd::options opt(argv.argc(), argv.argv()); + AssertThat(opt.only(), Equals("")); + }); + + it("parses the '--break-on-failure' oprtion", [&](){ + const char* args[] = {"executable", "--break-on-failure"}; + argv_helper argv(2, args); + + bd::options opt(argv.argc(), argv.argv()); + + AssertThat(opt.break_on_failure(), IsTrue()); + }); + + describe("with no arguments", [&](){ + const char* args[] = {"executable"}; + argv_helper argv(1, args); + bd::options opt(argv.argc(), argv.argv()); + + it("cannot find '--help'", [&](){ + AssertThat(opt.help(), IsFalse()); + }); + + it("cannot find '--version'", [&](){ + AssertThat(opt.version(), IsFalse()); + }); + + it("cannot find '--no-color'", [&](){ + AssertThat(opt.no_color(), IsFalse()); + }); + + it("cannot fine '--break-on-failure'", [&](){ + AssertThat(opt.break_on_failure(), IsFalse()) + }); + + it("uses default formatter for '--formatter'", [&](){ + AssertThat(opt.formatter(), Equals(bd::options::formatters::FORMATTER_DEFAULT)); + }); + }); + }); + +}); diff --git a/vendor/bandit/specs/reporters/colorizer.spec.cpp b/vendor/bandit/specs/reporters/colorizer.spec.cpp new file mode 100644 index 00000000..7708ec81 --- /dev/null +++ b/vendor/bandit/specs/reporters/colorizer.spec.cpp @@ -0,0 +1,45 @@ +#ifndef _WIN32 +#include <specs/specs.h> + +go_bandit([](){ + + describe("colorizer: ", [&](){ + + describe("colors enabled", [&](){ + bandit::detail::colorizer colorizer; + + it("can set color to green", [&](){ + AssertThat(colorizer.green(), Equals("\033[1;32m")); + }); + + it("set color to red", [&](){ + AssertThat(colorizer.red(), Equals("\033[1;31m")); + }); + it("resets color", [&](){ + AssertThat(colorizer.reset(), Equals("\033[0m")); + }); + + }); + + describe("colors disabled", [&](){ + + bandit::detail::colorizer colorizer(false); + + it("ignores setting color to green", [&](){ + AssertThat(colorizer.green(), Equals("")); + }); + + it("ignores setting color to red", [&](){ + AssertThat(colorizer.red(), Equals("")); + }); + + it("ignores resetting colors", [&](){ + AssertThat(colorizer.reset(), Equals("")); + }); + + }); + + }); + +}); +#endif
\ No newline at end of file diff --git a/vendor/bandit/specs/reporters/dots_reporter.spec.cpp b/vendor/bandit/specs/reporters/dots_reporter.spec.cpp new file mode 100644 index 00000000..f06c8d77 --- /dev/null +++ b/vendor/bandit/specs/reporters/dots_reporter.spec.cpp @@ -0,0 +1,202 @@ +#include <specs/specs.h> +namespace bd = bandit::detail; + +go_bandit([](){ + + describe("dots_reporter:", [&](){ + std::unique_ptr<std::stringstream> stm; + std::unique_ptr<bd::dots_reporter> reporter; + bd::default_failure_formatter formatter; + bd::colorizer colorizer(false); + + before_each([&](){ + stm = std::unique_ptr<std::stringstream>(new std::stringstream()); + reporter = std::unique_ptr<bd::dots_reporter>( + new bd::dots_reporter(*stm, formatter, colorizer)); + }); + + auto output = [&](){ return stm->str(); }; + + describe("an empty test run", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->test_run_complete(); + }); + + it("reports no tests where run", [&](){ + AssertThat(output(), Equals("\nCould not find any tests.\n")); + }); + + it("is not considered successful", [&](){ + AssertThat(reporter->did_we_pass(), Equals(false)); + }); + + }); + + describe("a successful test run", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->context_starting("my context"); + reporter->it_starting("my test"); + reporter->it_succeeded("my test"); + reporter->context_ended("my context"); + reporter->test_run_complete(); + }); + + it("reports a successful test run", [&](){ + AssertThat(output(), Contains("Success!")); + AssertThat(output(), EndsWith("Test run complete. 1 tests run. 1 succeeded.\n")); + }); + + it("displays a dot for the successful test", [&](){ + AssertThat(output(), StartsWith(".")); + }); + + it("reports a successful test run", [&](){ + AssertThat(reporter->did_we_pass(), Equals(true)); + }); + }); + + describe("a failing test run", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->context_starting("my context"); + reporter->it_starting("my test"); + + bd::assertion_exception exception("assertion failed!", "some_file", 123); + reporter->it_failed("my test", exception); + + reporter->context_ended("my context"); + reporter->test_run_complete(); + }); + + it("reports a failing test run in summary", [&](){ + AssertThat(output(), EndsWith("Test run complete. 1 tests run. 0 succeeded. 1 failed.\n")); + }); + + it("reports the failed assertion", [&](){ + AssertThat(output(), Contains("my context my test:\nsome_file:123: assertion failed!")); + }); + + it("only reports assertion failure once", [&](){ + AssertThat(output(), Has().Exactly(1).EndingWith("assertion failed!")); + }); + + it("reports an 'F' for the failed assertion", [&](){ + AssertThat(output(), StartsWith("F")); + }); + + it("reports a failed test run", [&](){ + AssertThat(reporter->did_we_pass(), Equals(false)); + }); + }); + + describe("a test run with a non assertion_exception thrown", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->context_starting("my context"); + reporter->it_starting("my test"); + + reporter->it_unknown_error("my test"); + + reporter->context_ended("my context"); + reporter->test_run_complete(); + }); + + it("reports an 'E' for the failed test", [&](){ + AssertThat(output(), StartsWith("E")); + }); + + it("reports the failed test", [&](){ + AssertThat(output(), Contains("my context my test:\nUnknown exception")) + }); + + }); + + describe("a failing test run with nested contexts", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->context_starting("my context"); + reporter->context_starting("a nested context"); + reporter->it_starting("my test"); + + bd::assertion_exception exception("assertion failed!", "some_file", 123); + reporter->it_failed("my test", exception); + + reporter->context_ended("a nested context"); + reporter->context_ended("my context"); + reporter->test_run_complete(); + }); + + it("reports a failing test run in summary", [&](){ + AssertThat(output(), EndsWith("Test run complete. 1 tests run. 0 succeeded. 1 failed.\n")); + }); + + it("reports the failed assertion", [&](){ + AssertThat(output(), Contains("my context a nested context my test:\nsome_file:123: assertion failed!")); + }); + + it("reports an 'F' for the failed assertion", [&](){ + AssertThat(output(), StartsWith("F")); + }); + + it("reports a failed test run", [&](){ + AssertThat(reporter->did_we_pass(), Equals(false)); + }); + + }); + + describe("a context with test run errors", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->context_starting("my context"); + + bd::test_run_error error("we dun goofed!"); + reporter->test_run_error("my context", error); + + reporter->context_ended("my context"); + reporter->test_run_complete(); + }); + + it("reports that the context has failed", [&](){ + AssertThat(output(), Contains("Failed to run \"my context\": error \"we dun goofed!\"")); + }); + + it("reports test run errors in summary", [&](){ + AssertThat(output(), EndsWith("Test run complete. 0 tests run. 0 succeeded. 1 test run errors.\n")) + }); + + it("reports a failed test run", [&](){ + AssertThat(reporter->did_we_pass(), Equals(false)); + }); + }); + + describe("a context with a skipped test", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->context_starting("my context"); + + reporter->it_starting("my test"); + reporter->it_succeeded("my test"); + reporter->it_skip("my skipped test"); + + reporter->context_ended("my context"); + reporter->test_run_complete(); + }); + + it("reports that there is one skipped test in the summary", [&](){ + AssertThat(output(), EndsWith("Test run complete. 1 tests run. 1 succeeded. 1 skipped.\n")); + }); + + }); + }); + + +}); diff --git a/vendor/bandit/specs/reporters/single_line_reporter.spec.cpp b/vendor/bandit/specs/reporters/single_line_reporter.spec.cpp new file mode 100644 index 00000000..ef7b5206 --- /dev/null +++ b/vendor/bandit/specs/reporters/single_line_reporter.spec.cpp @@ -0,0 +1,201 @@ +#include <specs/specs.h> +namespace bd = bandit::detail; + +go_bandit([](){ + + describe("single line reporter", [&](){ + std::unique_ptr<std::stringstream> stm; + std::unique_ptr<bd::single_line_reporter> reporter; + bd::default_failure_formatter formatter; + bd::colorizer colorizer(false); + + before_each([&](){ + stm = std::unique_ptr<std::stringstream>(new std::stringstream()); + reporter = std::unique_ptr<bd::single_line_reporter>( + new bd::single_line_reporter(*stm, formatter, colorizer)); + }); + + auto output = [&](){ return stm->str(); }; + + describe("an empty test run", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->test_run_complete(); + }); + + it("reports that no tests were run", [&](){ + AssertThat(output(), Equals("\nCould not find any tests.\n")); + }); + + it("is not considered successful", [&](){ + AssertThat(reporter->did_we_pass(), Equals(false)); + }); + }); + + describe("a successful test run", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->context_starting("my context"); + reporter->it_starting("my test"); + reporter->it_succeeded("my test"); + reporter->context_ended("my context"); + reporter->test_run_complete(); + }); + + it("reports a successful test run", [&](){ + AssertThat(output(), EndsWith("Test run complete. 1 tests run. 1 succeeded.\n")); + }); + + it("displays progress for the test", [&](){ + AssertThat(output(), StartsWith("\rExecuted 0 tests." + "\rExecuted 1 tests.")); + }); + + it("reports a successful test run", [&](){ + AssertThat(reporter->did_we_pass(), Equals(true)); + }); + }); + + describe("a failing test run", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->context_starting("my context"); + reporter->it_starting("my test"); + + bd::assertion_exception exception("assertion failed!", "some_file", 123); + reporter->it_failed("my test", exception); + + reporter->context_ended("my context"); + reporter->test_run_complete(); + }); + + it("reports a failing test run in summary", [&](){ + AssertThat(output(), EndsWith("Test run complete. 1 tests run. 0 succeeded. 1 failed.\n")); + }); + + it("reports the failed assertion", [&](){ + AssertThat(output(), Contains("my context my test:\nsome_file:123: assertion failed!")); + }); + + it("reports failing test in progress", [&](){ + AssertThat(output(), StartsWith("\rExecuted 0 tests." + "\rExecuted 1 tests. 0 succeeded. 1 failed.")); + }); + + it("reports a failed test run", [&](){ + AssertThat(reporter->did_we_pass(), Equals(false)); + }); + }); + + describe("a test run with a non assertion_exception thrown", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->context_starting("my context"); + reporter->it_starting("my test"); + + reporter->it_unknown_error("my test"); + + reporter->context_ended("my context"); + reporter->test_run_complete(); + }); + + it("reports failing test in progress", [&](){ + AssertThat(output(), StartsWith("\rExecuted 0 tests." + "\rExecuted 1 tests. 0 succeeded. 1 failed.")); + }); + + it("reports the failed test", [&](){ + AssertThat(output(), Contains("my context my test:\nUnknown exception")) + }); + + }); + + describe("a failing test run with nested contexts", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->context_starting("my context"); + reporter->context_starting("a nested context"); + reporter->it_starting("my test"); + + bd::assertion_exception exception("assertion failed!", "some_file", 123); + reporter->it_failed("my test", exception); + + reporter->context_ended("a nested context"); + reporter->context_ended("my context"); + reporter->test_run_complete(); + }); + + it("reports a failing test run in summary", [&](){ + AssertThat(output(), EndsWith("Test run complete. 1 tests run. 0 succeeded. 1 failed.\n")); + }); + + it("reports the failed assertion", [&](){ + AssertThat(output(), Contains("my context a nested context my test:\nsome_file:123: assertion failed!")); + }); + + it("displays a failed test in progress report", [&](){ + AssertThat(output(), StartsWith("\rExecuted 0 tests." + "\rExecuted 1 tests. 0 succeeded. 1 failed.")); + }); + + it("reports a failed test run", [&](){ + AssertThat(reporter->did_we_pass(), Equals(false)); + }); + + }); + + describe("a context with test run errors", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->context_starting("my context"); + + bd::test_run_error error("we dun goofed!"); + reporter->test_run_error("my context", error); + + reporter->context_ended("my context"); + reporter->test_run_complete(); + }); + + it("reports that the context has failed", [&](){ + AssertThat(output(), Contains("Failed to run \"my context\": error \"we dun goofed!\"")); + }); + + it("reports test run errors in summary", [&](){ + AssertThat(output(), EndsWith("Test run complete. 0 tests run. 0 succeeded. 1 test run errors.\n")) + }); + + it("reports a failed test run", [&](){ + AssertThat(reporter->did_we_pass(), Equals(false)); + }); + }); + + describe("a context with a skipped test", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->context_starting("my context"); + + reporter->it_starting("my test"); + reporter->it_succeeded("my test"); + reporter->it_skip("my skipped test"); + + reporter->context_ended("my context"); + reporter->test_run_complete(); + }); + + it("reports that there is one skipped test in the summary", [&](){ + AssertThat(output(), EndsWith("Test run complete. 1 tests run. 1 succeeded. 1 skipped.\n")); + }); + + }); + + + }); + +}); diff --git a/vendor/bandit/specs/reporters/xunit_reporter.spec.cpp b/vendor/bandit/specs/reporters/xunit_reporter.spec.cpp new file mode 100644 index 00000000..07f0c3b7 --- /dev/null +++ b/vendor/bandit/specs/reporters/xunit_reporter.spec.cpp @@ -0,0 +1,161 @@ +#include <specs/specs.h> +namespace bd = bandit::detail; + +go_bandit([](){ + + describe("xunit_reporter:", [&](){ + std::unique_ptr<std::stringstream> stm; + bd::default_failure_formatter formatter; + std::unique_ptr<bd::xunit_reporter> reporter; + + auto output = [&](){ return stm->str(); }; + + before_each([&](){ + stm = std::unique_ptr<std::stringstream>(new std::stringstream()); + reporter = std::unique_ptr<bd::xunit_reporter>(new bd::xunit_reporter(*stm, formatter)); + }); + + describe("an empty test run", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->test_run_complete(); + }); + + it("adds a header to the output", [&](){ + AssertThat(output(), StartsWith("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")); + }); + + it("outputs an empty test report", [&](){ + AssertThat(output(), Contains( + "<testsuite name=\"bandit\" tests=\"0\" errors=\"0\" failures=\"0\">\n" + "</testsuite>\n")); + }); + + }); + + describe("a test run with one, successful, test", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->context_starting("my context"); + reporter->it_starting("my test"); + reporter->it_succeeded("my test"); + reporter->context_ended("my context"); + reporter->test_run_complete(); + }); + + it("outputs info about the successful test", [&](){ + AssertThat(output(), Contains( + "<testsuite name=\"bandit\" tests=\"1\" errors=\"0\" failures=\"0\">\n" + "\t<testcase classname=\"my context\" name=\"my test\" time=\"0\">\n" + "\t</testcase>\n" + "</testsuite>\n")); + }); + }); + + describe("a test run with one, failing test", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->context_starting("my context"); + reporter->it_starting("my test"); + + bd::assertion_exception exception("assertion failed!", "some_file", 123); + reporter->it_failed("my test", exception); + + reporter->context_ended("my context"); + reporter->test_run_complete(); + + }); + + it("outputs the failing test", [&](){ + AssertThat(output(), Contains( + "<testsuite name=\"bandit\" tests=\"1\" errors=\"0\" failures=\"1\">\n" + "\t<testcase classname=\"my context\" name=\"my test\" time=\"0\">\n" + "\t\t<failure message=\"some_file:123: assertion failed!\" />\n" + "\t</testcase>\n" + "</testsuite>\n")); + }); + + }); + + describe("a test run with one test with an unknown error", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->context_starting("my context"); + reporter->it_starting("my test"); + + reporter->it_unknown_error("my test"); + + reporter->context_ended("my context"); + reporter->test_run_complete(); + }); + + it("outputs the erroneous test", [&](){ + AssertThat(output(), Contains( + "<testsuite name=\"bandit\" tests=\"1\" errors=\"0\" failures=\"1\">\n" + "\t<testcase classname=\"my context\" name=\"my test\" time=\"0\">\n" + "\t\t<failure message=\"Unknown exception\" />\n" + "\t</testcase>\n" + "</testsuite>\n")); + }); + + }); + + describe("a test run with one test failing with characters that need escaping", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->context_starting("my context & < > \\ \""); + reporter->it_starting("my test & < > \\ \""); + + bd::assertion_exception exception("assertion failed & < > \\ \"", "some_file", 123); + reporter->it_failed("my test & < > \\ \"", exception); + + reporter->context_ended("my context & < > \\ \""); + reporter->test_run_complete(); + }); + + it("outputs the escaped characters", [&](){ + AssertThat(output(), Contains( + "<testsuite name=\"bandit\" tests=\"1\" errors=\"0\" failures=\"1\">\n" + "\t<testcase classname=\"my context & < > ' "\" name=\"my test & < > ' "\" time=\"0\">\n" + "\t\t<failure message=\"some_file:123: assertion failed & < > ' "\" />\n" + "\t</testcase>\n" + "</testsuite>\n")); + }); + + }); + + describe("a context with a skipped test", [&](){ + + before_each([&](){ + reporter->test_run_starting(); + reporter->context_starting("my context"); + + reporter->it_starting("my test"); + reporter->it_succeeded("my test"); + reporter->it_skip("my skipped test"); + + reporter->context_ended("my context"); + reporter->test_run_complete(); + }); + + it("outputs info about the skipped test", [&](){ + AssertThat(output(), Contains( + "<testsuite name=\"bandit\" tests=\"1\" errors=\"0\" failures=\"0\" skipped=\"1\">\n" + "\t<testcase classname=\"my context\" name=\"my test\" time=\"0\">\n" + "\t</testcase>\n" + "\t<testcase classname=\"my context\" name=\"my skipped test\" time=\"0\">\n" + "\t\t<skipped />\n" + "\t</testcase>\n" + "</testsuite>\n")); + }); + + }); + + }); + +}); diff --git a/vendor/bandit/specs/run.spec.cpp b/vendor/bandit/specs/run.spec.cpp new file mode 100644 index 00000000..6e59bac7 --- /dev/null +++ b/vendor/bandit/specs/run.spec.cpp @@ -0,0 +1,77 @@ +#include <specs/specs.h> +using namespace bandit::fakes; +using namespace bandit::specs::util; +namespace bd = bandit::detail; + +go_bandit([](){ + + describe("run:", [&](){ + std::unique_ptr<bd::spec_registry> specs; + std::unique_ptr<argv_helper> argv; + fake_reporter_ptr reporter; + std::unique_ptr<bd::contextstack_t> context_stack; + + auto call_run = [&]() -> int { + bd::options opt(argv->argc(), argv->argv()); + return bandit::run(opt, *specs, *context_stack, *reporter); + }; + + before_each([&](){ + specs = std::unique_ptr<bd::spec_registry>(new bd::spec_registry()); + + reporter = fake_reporter_ptr(new fake_reporter()); + + context_stack = std::unique_ptr<bd::contextstack_t>(new bd::contextstack_t()); + + const char* args[] = {"executable"}; + argv = std::unique_ptr<argv_helper>(new argv_helper(1, args)); + }); + + it("pushes the global context on the context stack", [&](){ + call_run(); + AssertThat(*context_stack, Is().OfLength(1)); + }); + + describe("a successful test run", [&](){ + int number_of_specs_called; + + before_each([&](){ + number_of_specs_called = 0; + specs->push_back([&](){ number_of_specs_called++; }); + }); + + it("calls the context", [&](){ + call_run(); + AssertThat(number_of_specs_called, Equals(1)); + }); + + it("tells reporter a test run is about to start", [&](){ + call_run(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("test_run_starting")); + }); + + it("tells reporter a test run has completed", [&](){ + call_run(); + AssertThat(reporter->call_log(), Has().Exactly(1).EqualTo("test_run_complete")); + }); + + it("returns 0 as no specs failed", [&](){ + AssertThat(call_run(), Equals(0)); + }); + }); + + + describe("a failing test run", [&](){ + + before_each([&](){ + reporter->set_test_run_status(false); + }); + + it("returns a non-zero error code", [&](){ + AssertThat(call_run(), IsGreaterThan(0)); + }); + + }); + }); + +}); diff --git a/vendor/bandit/specs/run_policies/bandit_run_policy.spec.cpp b/vendor/bandit/specs/run_policies/bandit_run_policy.spec.cpp new file mode 100644 index 00000000..75f56bc6 --- /dev/null +++ b/vendor/bandit/specs/run_policies/bandit_run_policy.spec.cpp @@ -0,0 +1,250 @@ +#include <specs/specs.h> + +go_bandit([](){ + namespace bd = bandit::detail; + + describe("bandit run policy", [&](){ + std::unique_ptr<bd::contextstack_t> contextstack; + std::unique_ptr<bd::context> global_context; + std::string only_pattern; + std::string skip_pattern; + bool break_on_failure; + + auto create_policy = [&]() -> bd::bandit_run_policy { + return bd::bandit_run_policy(skip_pattern.c_str(), only_pattern.c_str(), break_on_failure); + }; + + before_each([&](){ + contextstack = std::unique_ptr<bd::contextstack_t>(new bd::contextstack_t()); + bool hard_skip = false; + global_context = std::unique_ptr<bd::context>(new bd::bandit_context("", hard_skip)); + contextstack->push_back(global_context.get()); + break_on_failure = false; + }); + + describe("neither skip nor only specified", [&](){ + before_each([&](){ + only_pattern = ""; + skip_pattern = ""; + }); + + it("always says run", [&](){ + bd::bandit_run_policy policy = create_policy(); + AssertThat(policy.should_run("it name", *contextstack), IsTrue()); + }); + + describe("with 'break-on-failure' set", [&](){ + + before_each([&](){ + break_on_failure = true; + }); + + it("says run if no failure has been encountered", [&](){ + bd::bandit_run_policy policy = create_policy(); + AssertThat(policy.should_run("it name", *contextstack), IsTrue()); + }); + + it("says don't run if a failure has been encountered", [&](){ + bd::bandit_run_policy policy = create_policy(); + policy.encountered_failure(); + AssertThat(policy.should_run("it name", *contextstack), IsFalse()); + }); + + }); + + describe("has context marked with 'hard_skip' in stack", [&](){ + std::unique_ptr<bd::context> hard_skip_context; + + before_each([&](){ + bool hard_skip = true; + hard_skip_context = std::unique_ptr<bd::context>(new bd::bandit_context("always ignore", hard_skip)); + contextstack->push_back(hard_skip_context.get()); + }); + + it("never runs", [&](){ + bd::bandit_run_policy policy = create_policy(); + AssertThat(policy.should_run("it name", *contextstack), IsFalse()); + AssertThat(policy.should_run("it name matches 'skip'", *contextstack), IsFalse()); + AssertThat(policy.should_run("it name matches 'only'", *contextstack), IsFalse()); + }); + + }); + + }); + + describe("'skip' specified, 'only' unspecified", [&](){ + + before_each([&](){ + only_pattern = ""; + skip_pattern = "skip"; + }); + + describe("current context matches 'skip'", [&](){ + std::unique_ptr<bd::context> current_context; + + before_each([&](){ + bool hard_skip = false; + current_context = std::unique_ptr<bd::context>(new bd::bandit_context("context matches 'skip'", hard_skip)); + contextstack->push_back(current_context.get()); + }); + + it("never runs", [&](){ + bd::bandit_run_policy policy = create_policy(); + AssertThat(policy.should_run("it name", *contextstack), IsFalse()); + }); + + }); + + describe("current context doesn't match 'skip'", [&](){ + std::unique_ptr<bd::context> current_context; + + before_each([&](){ + bool hard_skip = false; + current_context = std::unique_ptr<bd::context>(new bd::bandit_context("context doesn't match", hard_skip)); + contextstack->push_back(current_context.get()); + }); + + it("runs if spec's name doesn't match", [&](){ + bd::bandit_run_policy policy = create_policy(); + AssertThat(policy.should_run("it name", *contextstack), IsTrue()); + }); + + it("doesn't run if spec's name matches", [&](){ + bd::bandit_run_policy policy = create_policy(); + AssertThat(policy.should_run("it name matching 'skip'", *contextstack), IsFalse()); + }); + + }); + + }); + + describe("'only' specified, 'skip' unspecified", [&](){ + + before_each([&](){ + only_pattern = "only"; + skip_pattern = ""; + }); + + describe("current context matches 'only'", [&](){ + std::unique_ptr<bd::context> current_context; + + before_each([&](){ + bool hard_skip = false; + current_context = std::unique_ptr<bd::context>(new bd::bandit_context("context matches 'only'", hard_skip)); + contextstack->push_back(current_context.get()); + }); + + it("always runs", [&](){ + bd::bandit_run_policy policy = create_policy(); + AssertThat(policy.should_run("it name", *contextstack), IsTrue()); + }); + + }); + + describe("current context doesn't match 'only'", [&](){ + std::unique_ptr<bd::context> current_context; + + before_each([&](){ + bool hard_skip = false; + current_context = std::unique_ptr<bd::context>(new bd::bandit_context("context doesn't match", hard_skip)); + contextstack->push_back(current_context.get()); + }); + + it("doesn't run if spec's name doesn't match", [&](){ + bd::bandit_run_policy policy = create_policy(); + AssertThat(policy.should_run("it name", *contextstack), IsFalse()); + }); + + it("runs if spec's name matches", [&](){ + bd::bandit_run_policy policy = create_policy(); + AssertThat(policy.should_run("it name matching 'only'", *contextstack), IsTrue()); + }); + + }); + + }); + + describe("'skip' specified, 'only' specified", [&](){ + + before_each([&](){ + only_pattern = "only"; + skip_pattern = "skip"; + }); + + describe("current context matches 'skip'", [&](){ + std::unique_ptr<bd::context> current_context; + + before_each([&](){ + bool hard_skip = false; + current_context = std::unique_ptr<bd::context>(new bd::bandit_context("context matches 'skip'", hard_skip)); + contextstack->push_back(current_context.get()); + }); + + it("doesn't run if 'it' doesn't match 'only'", [&](){ + bd::bandit_run_policy policy = create_policy(); + AssertThat(policy.should_run("it name", *contextstack), IsFalse()); + }); + + it("runs if 'it' matches 'only'", [&](){ + bd::bandit_run_policy policy = create_policy(); + AssertThat(policy.should_run("it matches 'only'", *contextstack), IsTrue()); + }); + + }); + + describe("current context 'only'", [&](){ + std::unique_ptr<bd::context> current_context; + + before_each([&](){ + bool hard_skip = false; + current_context = std::unique_ptr<bd::context>(new bd::bandit_context("context matches 'only'", hard_skip)); + contextstack->push_back(current_context.get()); + }); + + it("runs if spec's name doesn't match anything", [&](){ + bd::bandit_run_policy policy = create_policy(); + AssertThat(policy.should_run("it name", *contextstack), IsTrue()); + }); + + it("doesn't run if spec's name matches 'skip'", [&](){ + bd::bandit_run_policy policy = create_policy(); + AssertThat(policy.should_run("it name matching 'skip'", *contextstack), IsFalse()); + }); + + }); + + describe("has both 'only' and 'skip' in context stack", [&](){ + std::unique_ptr<bd::context> current_context; + std::unique_ptr<bd::context> parent_context; + + before_each([&](){ + bool hard_skip = false; + current_context = std::unique_ptr<bd::context>(new bd::bandit_context("context matches 'only'", hard_skip)); + parent_context = std::unique_ptr<bd::context>(new bd::bandit_context("context matches 'skip'", hard_skip)); + contextstack->push_back(parent_context.get()); + contextstack->push_back(current_context.get()); + }); + + it("runs if spec's name doesn't match anything", [&](){ + bd::bandit_run_policy policy = create_policy(); + AssertThat(policy.should_run("it name", *contextstack), IsTrue()); + }); + + it("doesn't run if spec's name matches 'skip'", [&](){ + bd::bandit_run_policy policy = create_policy(); + AssertThat(policy.should_run("it name matching 'skip'", *contextstack), IsFalse()); + }); + it("runs if spec's name matches 'only'", [&](){ + bd::bandit_run_policy policy = create_policy(); + AssertThat(policy.should_run("it name matching 'only'", *contextstack), IsTrue()); + }); + + }); + + }); + + + }); + +}); + diff --git a/vendor/bandit/specs/specs.h b/vendor/bandit/specs/specs.h new file mode 100644 index 00000000..219e89ee --- /dev/null +++ b/vendor/bandit/specs/specs.h @@ -0,0 +1,10 @@ +#ifndef BANDIT_SPECS +#define BANDIT_SPECS + +#include <bandit/bandit.h> +using namespace bandit; + +#include <specs/fakes/fakes.h> +#include <specs/util/util.h> + +#endif diff --git a/vendor/bandit/specs/synopsis.spec.cpp b/vendor/bandit/specs/synopsis.spec.cpp new file mode 100644 index 00000000..3b717f75 --- /dev/null +++ b/vendor/bandit/specs/synopsis.spec.cpp @@ -0,0 +1,54 @@ +#include <specs/specs.h> + +go_bandit([](){ + describe("my first spec", [&]() { + int a; + + before_each([&](){ + a = 99; + }); + + it("should be initialized", [&](){ + AssertThat(a, Equals(99)); + a = 102; + }); + + describe("nested spec", [&](){ + + before_each([&](){ + a += 3; + }); + + it("should build on outer spec", [&](){ + AssertThat(a, Equals(102)); + a = 666; + }); + + it("should build on outer spec yet again", [&](){ + AssertThat(a, Equals(102)); + a = 667; + }); + + }); + + it("should be initialized before each it", [&](){ + AssertThat(a, Equals(99)); + }); + }); + + describe("my second spec", [&](){ + int b; + + before_each([&](){ + b = 22; + }); + + before_each([&](){ + b += 3; + }); + + it("should be 25", [&](){ + AssertThat(b, Equals(25)); + }); + }); +}); diff --git a/vendor/bandit/specs/util/argv_helper.h b/vendor/bandit/specs/util/argv_helper.h new file mode 100644 index 00000000..dac26765 --- /dev/null +++ b/vendor/bandit/specs/util/argv_helper.h @@ -0,0 +1,62 @@ +#ifndef BANDIT_SPECS_ARGV_HELPER_H +#define BANDIT_SPECS_ARGV_HELPER_H + +#include <string.h> + +namespace bandit { namespace specs { namespace util { + + // + // main() is supposed to receive its arguments as a non const 'char* argv[]'. + // This is a pain to create for each test. It's a whole lot easier to create + // a 'const char* argv[]' construct. + // + // This class helps copy from 'const char**' to 'char**' and handle cleanup + // automatically. + // + struct argv_helper + { + argv_helper(int argc_a, const char* argv_a[]) + : argc_(argc_a) + { + non_const_argv_ = new char*[argc_]; + for(int i=0; i < argc_; i++) + { + std::string s(argv_a[i]); + non_const_argv_[i] = new char[s.size() + 1]; + for(size_t c=0;c<s.size();c++) + { + non_const_argv_[i][c] = s[c]; + } + non_const_argv_[i][s.size()] = 0; + } + } + + + + ~argv_helper() + { + for(int i=0; i < argc_; i++) + { + delete[] non_const_argv_[i]; + } + + delete[] non_const_argv_; + } + + char** argv() + { + return non_const_argv_; + } + + int argc() + { + return argc_; + } + + private: + int argc_; + char** non_const_argv_; + }; + +}}} +#endif diff --git a/vendor/bandit/specs/util/util.h b/vendor/bandit/specs/util/util.h new file mode 100644 index 00000000..7ed17dd8 --- /dev/null +++ b/vendor/bandit/specs/util/util.h @@ -0,0 +1,6 @@ +#ifndef BANDIT_SPECS_UTIL_H +#define BANDIT_SPECS_UTIL_H + +#include "argv_helper.h" + +#endif |