| 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 |