#ifndef BANDIT_CONTEXT_H #define BANDIT_CONTEXT_H namespace bandit { namespace detail { class context { public: virtual ~context() {} virtual const std::string& name() = 0; virtual void execution_is_starting() = 0; virtual void register_before_each(voidfunc_t func) = 0; virtual void register_after_each(voidfunc_t func) = 0; virtual void run_before_eaches() = 0; virtual void run_after_eaches() = 0; virtual bool hard_skip() = 0; }; class bandit_context : public context { public: bandit_context(const char* desc, bool hard_skip_a) : desc_(desc), hard_skip_(hard_skip_a), is_executing_(false) {} const std::string& name() { return desc_; } void execution_is_starting() { is_executing_ = true; } void register_before_each(voidfunc_t func) { if(is_executing_) { throw test_run_error("before_each was called after 'describe' or 'it'"); } before_eaches_.push_back(func); } void register_after_each(voidfunc_t func) { if(is_executing_) { throw test_run_error("after_each was called after 'describe' or 'it'"); } after_eaches_.push_back(func); } void run_before_eaches() { run_all(before_eaches_); } void run_after_eaches() { run_all(after_eaches_); } bool hard_skip() { return hard_skip_; } private: void run_all(const std::list& funcs) { auto call_func = [](voidfunc_t f){ f(); }; for_each(funcs.begin(), funcs.end(), call_func); } private: std::string desc_; bool hard_skip_; bool is_executing_; std::list before_eaches_; std::list after_eaches_; }; typedef std::deque contextstack_t; inline contextstack_t& context_stack() { static contextstack_t contexts; return contexts; } } } #endif