#include 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 context_stack; std::unique_ptr global_context; before_each([&](){ reporter = fake_reporter_ptr(new fake_reporter()); context_stack = std::unique_ptr(new bd::contextstack_t()); global_context = std::unique_ptr(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