1 | #ifndef BANDIT_CONTEXT_H |
---|---|
2 | #define BANDIT_CONTEXT_H |
3 | |
4 | #include <algorithm> |
5 | #include <deque> |
6 | #include <list> |
7 | #include <string> |
8 | #include <bandit/types.h> |
9 | #include <bandit/test_run_error.h> |
10 | |
11 | namespace bandit { |
12 | namespace detail { |
13 | struct context { |
14 | virtual ~context() {} |
15 | virtual const std::string& name() = 0; |
16 | virtual void execution_is_starting() = 0; |
17 | virtual void register_before_each(voidfunc_t func) = 0; |
18 | virtual void register_after_each(voidfunc_t func) = 0; |
19 | virtual void run_before_eaches() = 0; |
20 | virtual void run_after_eaches() = 0; |
21 | virtual bool hard_skip() = 0; |
22 | }; |
23 | |
24 | struct bandit_context : public context { |
25 | bandit_context(const std::string& desc, bool hard_skip_a) |
26 | : desc_(desc), hard_skip_(hard_skip_a), is_executing_(false) {} |
27 | |
28 | const std::string& name() override { |
29 | return desc_; |
30 | } |
31 | |
32 | void execution_is_starting() override { |
33 | is_executing_ = true; |
34 | } |
35 | |
36 | void register_before_each(voidfunc_t func) override { |
37 | if (is_executing_) { |
38 | throw test_run_error("before_each was called after 'describe' or 'it'"); |
39 | } |
40 | |
41 | before_eaches_.push_back(func); |
42 | } |
43 | |
44 | void register_after_each(voidfunc_t func) override { |
45 | if (is_executing_) { |
46 | throw test_run_error("after_each was called after 'describe' or 'it'"); |
47 | } |
48 | |
49 | after_eaches_.push_back(func); |
50 | } |
51 | |
52 | void run_before_eaches() override { |
53 | run_all(before_eaches_); |
54 | } |
55 | |
56 | void run_after_eaches() override { |
57 | run_all(after_eaches_); |
58 | } |
59 | |
60 | bool hard_skip() override { |
61 | return hard_skip_; |
62 | } |
63 | |
64 | private: |
65 | void run_all(const std::list<voidfunc_t>& funcs) { |
66 | for (auto f : funcs) { |
67 | f(); |
68 | } |
69 | } |
70 | |
71 | std::string desc_; |
72 | bool hard_skip_; |
73 | bool is_executing_; |
74 | std::list<voidfunc_t> before_eaches_; |
75 | std::list<voidfunc_t> after_eaches_; |
76 | }; |
77 | |
78 | typedef std::deque<context*> contextstack_t; |
79 | |
80 | inline contextstack_t& context_stack() { |
81 | static contextstack_t contexts; |
82 | return contexts; |
83 | } |
84 | } |
85 | } |
86 | #endif |
87 |