diff options
Diffstat (limited to 'vendor/bandit/bandit/run_policies/bandit_run_policy.h')
-rw-r--r-- | vendor/bandit/bandit/run_policies/bandit_run_policy.h | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/vendor/bandit/bandit/run_policies/bandit_run_policy.h b/vendor/bandit/bandit/run_policies/bandit_run_policy.h new file mode 100644 index 00000000..4a5c0808 --- /dev/null +++ b/vendor/bandit/bandit/run_policies/bandit_run_policy.h @@ -0,0 +1,161 @@ +#ifndef BANDIT_BANDIT_RUN_POLICY_H +#define BANDIT_BANDIT_RUN_POLICY_H + +namespace bandit { namespace detail { + + struct bandit_run_policy : public run_policy + { + bandit_run_policy(const char* skip_pattern, const char* only_pattern, bool break_on_failure) + : run_policy(), skip_pattern_(skip_pattern), only_pattern_(only_pattern), break_on_failure_(break_on_failure) + {} + + bool should_run(const char* it_name, const contextstack_t& contexts) const + { + if(break_on_failure_ && has_encountered_failure()) + { + return false; + } + + // + // Never run if a context has been marked as skip + // using 'describe_skip' + // + if(has_context_with_hard_skip(contexts)) + { + return false; + } + + // + // Always run if no patterns have been specifed + // + if(!has_skip_pattern() && !has_only_pattern()) + { + return true; + } + + if(has_only_pattern() && !has_skip_pattern()) + { + return context_matches_only_pattern(contexts) + || matches_only_pattern(it_name); + } + + if(has_skip_pattern() && !has_only_pattern()) + { + bool skip = context_matches_skip_pattern(contexts) || + matches_skip_pattern(it_name); + return !skip; + } + + // + // If we've come this far, both 'skip' and 'only' + // have been specified. + // + // If our contexts match 'only' we're still good + // regardless of whether there's a 'skip' somewhere + // in the context stack as well. + if(context_matches_only_pattern(contexts)) + { + // + // We can still mark the current 'it' as 'skip' + // and ignore it. We check that here. + // + return !matches_skip_pattern(it_name); + } + + // + // If we've gotten this far, the context matches 'skip' + // We can still run this spec if it is specifically marked + // as 'only'. + // + return matches_only_pattern(it_name); + } + + private: + bool has_context_with_hard_skip(const contextstack_t& contexts) const + { + contextstack_t::const_iterator it; + for(it = contexts.begin(); it != contexts.end(); it++) + { + if((*it)->hard_skip()) + { + return true; + } + } + + return false; + } + + bool has_only_pattern() const + { + return only_pattern_.size() > 0; + } + + bool has_skip_pattern() const + { + return skip_pattern_.size() > 0; + } + + bool context_matches_only_pattern(const contextstack_t& contexts) const + { + contextstack_t::const_iterator it; + for(it = contexts.begin(); it != contexts.end(); it++) + { + if(matches_only_pattern((*it)->name())) + { + return true; + } + } + + return false; + } + + bool context_matches_skip_pattern(const contextstack_t& contexts) const + { + contextstack_t::const_iterator it; + for(it = contexts.begin(); it != contexts.end(); it++) + { + if(matches_skip_pattern((*it)->name())) + { + return true; + } + } + + return false; + } + + bool matches_only_pattern(const char* name) const + { + std::string n(name); + return matches_only_pattern(n); + } + + bool matches_only_pattern(const std::string& name) const + { + return matches_pattern(name, only_pattern_); + } + + bool matches_skip_pattern(const char* name) const + { + std::string n(name); + return matches_skip_pattern(n); + } + + bool matches_skip_pattern(const std::string& name) const + { + return matches_pattern(name, skip_pattern_); + } + + bool matches_pattern(const std::string& name, const std::string& pattern) const + { + return name.find(pattern) != std::string::npos; + } + + private: + std::string skip_pattern_; + std::string only_pattern_; + bool break_on_failure_; + }; + +}} + +#endif |