C++Spec 1.0.0
BDD testing for C++
Loading...
Searching...
No Matches
be_within.hpp
1#pragma once
2
4
5namespace CppSpec::Matchers {
6template <typename A, typename E>
7class BeWithin;
8
9template <typename A, typename E>
10class BeWithinHelper {
11 Expectation<A>& expectation;
12 E tolerance;
13 std::string msg;
14
15 public:
16 BeWithinHelper(Expectation<A>& expectation, E tolerance) : expectation(expectation), tolerance(tolerance) {}
17
19 BeWithin<A, E> percent_of(E expected);
20 void set_message(const std::string& msg) { this->msg = msg; }
21 std::string get_message() { return this->msg; }
22};
23
24template <typename A, typename E>
25class BeWithin : public MatcherBase<A, E> {
26 E tolerance;
27 std::string unit;
28
29 public:
30 BeWithin(Expectation<A>& expectation, E tolerance, E value, std::string_view unit)
31 : MatcherBase<A, E>(expectation, value), tolerance{tolerance}, unit{unit} {}
32
33 bool match() override;
34
35 std::string failure_message() override;
36 std::string failure_message_when_negated() override;
37 std::string description() override;
38 std::string verb() override { return "be within"; }
39};
40
41template <typename A, typename E>
42BeWithin<A, E> BeWithinHelper<A, E>::of(E expected) {
43 auto matcher = BeWithin<A, E>(expectation, tolerance, expected, ""); // No unit specified
44 matcher.set_message(msg);
45 matcher.run(); // of() completes the expectation, like every other to_* matcher
46 return matcher;
47}
48
49template <typename A, typename E>
50BeWithin<A, E> BeWithinHelper<A, E>::percent_of(E expected) {
51 auto matcher = BeWithin<A, E>(expectation, tolerance, expected, "%"); // Percent unit specified
52 matcher.set_message(msg);
53 matcher.run(); // percent_of() completes the expectation, like every other to_* matcher
54 return matcher;
55}
56
57template <typename A, typename E>
58bool BeWithin<A, E>::match() {
59 const auto actual = static_cast<long double>(this->actual());
60 const auto expected = static_cast<long double>(this->expected());
61 // A percentage tolerance is relative to the expected value.
62 const auto tolerance = unit == "%" ? std::abs(expected) * static_cast<long double>(this->tolerance) / 100
63 : static_cast<long double>(this->tolerance);
64 return std::abs(actual - expected) <= tolerance;
65}
66
67template <typename A, typename E>
69 return std::format("expected {} to {}", this->actual(), description());
70}
71
72template <typename A, typename E>
74 return std::format("expected {} not to {}", this->actual(), description());
75}
76
77template <typename A, typename E>
79 return std::format("be within {}{} of {}", this->tolerance, this->unit, this->expected());
80}
81
82} // namespace CppSpec::Matchers
Wraps the target of an expectation.
Definition expectation.hpp:48
Definition be_within.hpp:25
std::string description() override
Get the description of the Matcher.
Definition be_within.hpp:78
std::string failure_message() override
Get message to give on match failure.
Definition be_within.hpp:68
std::string failure_message_when_negated() override
Get message to give on match failure when negated.
Definition be_within.hpp:73
Definition have_error.hpp:9
Contains the base class for all Matchers.