1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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
|