forked from banditcpp/bandit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontext.h
88 lines (73 loc) · 2.32 KB
/
context.h
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
#ifndef BANDIT_CONTEXT_H
#define BANDIT_CONTEXT_H
#include <algorithm>
#include <deque>
#include <functional>
#include <string>
#include <vector>
#include <bandit/test_run_error.h>
namespace bandit {
namespace context {
struct interface {
virtual ~interface() = default;
virtual const std::string& name() = 0;
virtual void execution_is_starting() = 0;
virtual void register_before_each(std::function<void()> func) = 0;
virtual void register_after_each(std::function<void()> func) = 0;
virtual void run_before_eaches() = 0;
virtual void run_after_eaches() = 0;
virtual bool hard_skip() = 0;
};
struct bandit : public interface {
bandit(const std::string& desc, bool hard_skip_a)
: desc_(desc), hard_skip_(hard_skip_a), is_executing_(false) {}
const std::string& name() override {
return desc_;
}
void execution_is_starting() override {
is_executing_ = true;
}
void register_before_each(std::function<void()> func) override {
throw_if_executing("before_each");
before_eaches_.push_back(func);
}
void register_after_each(std::function<void()> func) override {
throw_if_executing("after_each");
after_eaches_.push_back(func);
}
void run_before_eaches() override {
run_all(before_eaches_);
}
void run_after_eaches() override {
run_all(after_eaches_);
}
bool hard_skip() override {
return hard_skip_;
}
private:
void throw_if_executing(std::string&& method) const {
if (is_executing_) {
throw detail::test_run_error("'" + method + "' was called after 'describe' or 'it'");
}
}
void run_all(const std::vector<std::function<void()>>& funcs) {
for (auto f : funcs) {
f();
}
}
std::string desc_;
bool hard_skip_;
bool is_executing_;
std::vector<std::function<void()>> before_eaches_;
std::vector<std::function<void()>> after_eaches_;
};
struct stack_t : public std::deque<context::interface*> {
void throw_if_empty(std::string&& method) const {
if (empty()) {
throw detail::test_run_error("'" + method + "' was called without surrounding 'describe'");
}
}
};
}
}
#endif