1 | // Copyright Joakim Karlsson & Kim Gräsman 2010-2012. |
2 | // Distributed under the Boost Software License, Version 1.0. |
3 | // (See accompanying file LICENSE_1_0.txt or copy at |
4 | // http://www.boost.org/LICENSE_1_0.txt) |
5 | |
6 | #ifndef SNOWHOUSE_ASSERT_H |
7 | #define SNOWHOUSE_ASSERT_H |
8 | |
9 | #include "assertionexception.h" |
10 | #include "fluent/expressionbuilder.h" |
11 | |
12 | // clang-format off |
13 | #define SNOWHOUSE_ASSERT_THAT(P1, P2, FAILURE_HANDLER) \ |
14 | ::snowhouse::ConfigurableAssert<FAILURE_HANDLER>::That((P1), (P2), __FILE__, __LINE__) |
15 | |
16 | #ifndef SNOWHOUSE_NO_MACROS |
17 | # define AssertThat(P1, P2) \ |
18 | SNOWHOUSE_ASSERT_THAT((P1), (P2), ::snowhouse::DefaultFailureHandler) |
19 | #endif |
20 | // clang-format on |
21 | |
22 | namespace snowhouse |
23 | { |
24 | struct DefaultFailureHandler |
25 | { |
26 | template<typename ExpectedType, typename ActualType> |
27 | static void Handle(const ExpectedType& expected, const ActualType& actual, const char* file_name, int line_number) |
28 | { |
29 | std::ostringstream str; |
30 | |
31 | str << "Expected: " << snowhouse::Stringize(expected) << std::endl; |
32 | str << "Actual: " << snowhouse::Stringize(actual) << std::endl; |
33 | |
34 | throw AssertionException(str.str(), file_name, line_number); |
35 | } |
36 | |
37 | static void Handle(const std::string& message) |
38 | { |
39 | throw AssertionException(message); |
40 | } |
41 | }; |
42 | |
43 | template<typename FailureHandler> |
44 | struct ConfigurableAssert |
45 | { |
46 | template<typename ActualType, typename ConstraintListType> |
47 | static void That(const ActualType& actual, ExpressionBuilder<ConstraintListType> expression, const char* file_name = "" , int line_number = 0) |
48 | { |
49 | try |
50 | { |
51 | ResultStack result; |
52 | OperatorStack operators; |
53 | expression.Evaluate(result, operators, actual); |
54 | |
55 | while (!operators.empty()) |
56 | { |
57 | ConstraintOperator* op = operators.top(); |
58 | op->PerformOperation(result); |
59 | operators.pop(); |
60 | } |
61 | |
62 | if (result.empty()) |
63 | { |
64 | throw InvalidExpressionException("The expression did not yield any result" ); |
65 | } |
66 | |
67 | if (!result.top()) |
68 | { |
69 | FailureHandler::Handle(expression, actual, file_name, line_number); |
70 | } |
71 | } |
72 | catch (const InvalidExpressionException& e) |
73 | { |
74 | FailureHandler::Handle("Malformed expression: \"" + snowhouse::Stringize(expression) + "\"\n" + e.Message()); |
75 | } |
76 | } |
77 | |
78 | template<typename ConstraintListType> |
79 | static void That(const char* actual, ExpressionBuilder<ConstraintListType> expression, const char* file_name = "" , int line_number = 0) |
80 | { |
81 | return That(std::string(actual), expression, file_name, line_number); |
82 | } |
83 | |
84 | template<typename ActualType, typename ExpressionType> |
85 | static void That(const ActualType& actual, const ExpressionType& expression, const char* file_name = "" , int line_number = 0) |
86 | { |
87 | if (!expression(actual)) |
88 | { |
89 | FailureHandler::Handle(expression, actual, file_name, line_number); |
90 | } |
91 | } |
92 | |
93 | template<typename ExpressionType> |
94 | static void That(const char* actual, const ExpressionType& expression, const char* file_name = "" , int line_number = 0) |
95 | { |
96 | return That(std::string(actual), expression, file_name, line_number); |
97 | } |
98 | |
99 | static void That(bool actual) |
100 | { |
101 | if (!actual) |
102 | { |
103 | FailureHandler::Handle("Expected: true\nActual: false" ); |
104 | } |
105 | } |
106 | |
107 | static void Failure(const std::string& message) |
108 | { |
109 | FailureHandler::Handle(message); |
110 | } |
111 | }; |
112 | |
113 | typedef ConfigurableAssert<DefaultFailureHandler> Assert; |
114 | } |
115 | |
116 | #endif |
117 | |