10
10
#include < gtest/gtest.h>
11
11
12
12
#include < string>
13
+
13
14
#include " GUnit/Detail/StringUtils.h"
14
15
15
16
namespace testing {
@@ -23,40 +24,56 @@ struct info {
23
24
TestPartResult::Type failure{};
24
25
};
25
26
26
- template <class TLhs , class TRhs ,
27
+ template <class TShouldError , class TLhs , class TRhs ,
27
28
AssertionResult (*Comp)(const char *, const char *, TLhs, TRhs)>
28
29
class msg : public decltype(Message()) {
29
30
public:
30
31
msg (const info& info, const std::string& comp, TLhs lhs, TRhs rhs)
31
- : info_{info}, comp_{comp}, lhs_{lhs}, rhs_{rhs} {}
32
+ : info_{info},
33
+ comp_{comp},
34
+ lhs_{lhs},
35
+ rhs_{rhs},
36
+ result_{Comp (" " , " " , lhs_, rhs_)} {}
32
37
~msg () {
33
- const auto begin = info_.expr .find (comp_);
34
- auto lhs_expr = info_.expr .substr (0 , begin);
35
- trim (lhs_expr);
36
- auto rhs_expr = info_.expr .substr (begin + comp_.size ());
37
- trim (rhs_expr);
38
- const AssertionResult gtest_ar =
39
- (Comp (lhs_expr.c_str (), rhs_expr.c_str (), lhs_, rhs_));
40
- if (!gtest_ar) {
41
- internal::AssertHelper (info_.failure , info_.file , info_.line ,
42
- gtest_ar.failure_message ()) = *this ;
38
+ if (TShouldError::value) {
39
+ const auto begin = info_.expr .find (comp_);
40
+ auto lhs_expr = info_.expr .substr (0 , begin);
41
+ trim (lhs_expr);
42
+ auto rhs_expr = info_.expr .substr (begin + comp_.size ());
43
+ trim (rhs_expr);
44
+ const AssertionResult gtest_ar =
45
+ (Comp (lhs_expr.c_str (), rhs_expr.c_str (), lhs_, rhs_));
46
+ if (!gtest_ar) {
47
+ internal::AssertHelper (info_.failure , info_.file , info_.line ,
48
+ gtest_ar.failure_message ()) = *this ;
49
+ }
43
50
}
44
51
}
45
52
53
+ operator bool () const { return result_; }
54
+
46
55
private:
47
56
info info_{};
48
57
std::string comp_{};
49
58
TLhs lhs_;
50
59
TRhs rhs_;
60
+ bool result_{};
51
61
};
52
62
63
+ template <class TShouldError >
53
64
class op {
54
65
template <class TLhs >
55
66
class comp : public decltype (Message()) {
56
67
public:
57
- explicit comp (const info& info, const TLhs& lhs) : info_{info}, lhs_{lhs} {}
68
+ explicit comp (const info& info, const TLhs& lhs) : info_{info}, lhs_{lhs} {
69
+ if (std::is_same<bool , TLhs>::value) {
70
+ result_ = internal::CmpHelperEQ (" " , " " , lhs_, true );
71
+ }
72
+ }
73
+
58
74
~comp () {
59
- if (!followed_ && std::is_same<bool , TLhs>::value) {
75
+ if (TShouldError::value && !followed_ &&
76
+ std::is_same<bool , TLhs>::value) {
60
77
const AssertionResult gtest_ar =
61
78
(internal::CmpHelperEQ (info_.expr .c_str (), " true" , lhs_, true ));
62
79
if (!gtest_ar) {
@@ -72,8 +89,9 @@ class op {
72
89
int > = 0 >
73
90
auto operator ==(const TRhs& rhs) const {
74
91
followed_ = true ;
75
- return msg<TLhs, TRhs, internal::CmpHelperFloatingPointEQ<TLhs>>{
76
- info_, " ==" , lhs_, rhs};
92
+ return msg<TShouldError, TLhs, TRhs,
93
+ internal::CmpHelperFloatingPointEQ<TLhs>>{info_, " ==" , lhs_,
94
+ rhs};
77
95
}
78
96
79
97
template <class TRhs ,
@@ -82,49 +100,52 @@ class op {
82
100
int > = 0 >
83
101
auto operator ==(const TRhs& rhs) const {
84
102
followed_ = true ;
85
- return msg<const TLhs&, const TRhs&, internal::CmpHelperEQ>{
103
+ return msg<TShouldError, const TLhs&, const TRhs&, internal::CmpHelperEQ>{
86
104
info_, " ==" , lhs_, rhs};
87
105
}
88
106
89
107
template <class TRhs >
90
108
auto operator !=(const TRhs& rhs) const {
91
109
followed_ = true ;
92
- return msg<const TLhs&, const TRhs&, internal::CmpHelperNE>{
110
+ return msg<TShouldError, const TLhs&, const TRhs&, internal::CmpHelperNE>{
93
111
info_, " !=" , lhs_, rhs};
94
112
}
95
113
96
114
template <class TRhs >
97
115
auto operator >(const TRhs& rhs) const {
98
116
followed_ = true ;
99
- return msg<const TLhs&, const TRhs&, internal::CmpHelperGT>{info_, " > " ,
100
- lhs_, rhs};
117
+ return msg<TShouldError, const TLhs&, const TRhs&, internal::CmpHelperGT>{
118
+ info_, " > " , lhs_, rhs};
101
119
}
102
120
103
121
template <class TRhs >
104
122
auto operator >=(const TRhs& rhs) const {
105
123
followed_ = true ;
106
- return msg<const TLhs&, const TRhs&, internal::CmpHelperGE>{
124
+ return msg<TShouldError, const TLhs&, const TRhs&, internal::CmpHelperGE>{
107
125
info_, " >=" , lhs_, rhs};
108
126
}
109
127
110
128
template <class TRhs >
111
129
auto operator <=(const TRhs& rhs) const {
112
130
followed_ = true ;
113
- return msg<const TLhs&, const TRhs&, internal::CmpHelperLE>{
131
+ return msg<TShouldError, const TLhs&, const TRhs&, internal::CmpHelperLE>{
114
132
info_, " <=" , lhs_, rhs};
115
133
}
116
134
117
135
template <class TRhs >
118
136
auto operator <(const TRhs& rhs) const {
119
137
followed_ = true ;
120
- return msg<const TLhs&, const TRhs&, internal::CmpHelperLT>{info_, " < " ,
121
- lhs_, rhs};
138
+ return msg<TShouldError, const TLhs&, const TRhs&, internal::CmpHelperLT>{
139
+ info_, " < " , lhs_, rhs};
122
140
}
123
141
142
+ operator bool () const { return result_; }
143
+
124
144
private:
125
145
info info_{};
126
146
TLhs lhs_{};
127
147
mutable bool followed_{false };
148
+ bool result_{};
128
149
};
129
150
130
151
public:
@@ -138,17 +159,38 @@ class op {
138
159
private:
139
160
info info_{};
140
161
};
162
+
163
+ struct drop {
164
+ template <class T >
165
+ drop& operator <<(const T&) {
166
+ return *this ;
167
+ }
168
+ };
169
+
170
+ struct ret_void {
171
+ template <class T >
172
+ void operator ==(const T&) {}
173
+ };
174
+
141
175
} // namespace detail
142
176
} // namespace v1
143
177
} // namespace testing
144
178
145
179
#define EXPECT (...) \
146
- (::testing::detail::op{ \
180
+ (::testing::detail::op<std::true_type>{ \
147
181
::testing::detail::info{__FILE__, __LINE__, #__VA_ARGS__, \
148
182
::testing::TestPartResult::kNonFatalFailure }} % \
149
183
__VA_ARGS__)
150
- #define ASSERT (...) \
151
- (::testing::detail::op{ \
152
- ::testing::detail::info{__FILE__, __LINE__, #__VA_ARGS__, \
153
- ::testing::TestPartResult::kFatalFailure }} % \
154
- __VA_ARGS__)
184
+
185
+ #define ASSERT (...) \
186
+ if (::testing::detail::op<std::false_type>{ \
187
+ ::testing::detail::info{__FILE__, __LINE__, #__VA_ARGS__, \
188
+ ::testing::TestPartResult::kFatalFailure }} % \
189
+ __VA_ARGS__) \
190
+ ::testing::detail::drop{}; \
191
+ else \
192
+ return ::testing::detail::ret_void{} == \
193
+ (::testing::detail::op<std::true_type>{::testing::detail::info{ \
194
+ __FILE__, __LINE__, #__VA_ARGS__, \
195
+ ::testing::TestPartResult::kFatalFailure }} % \
196
+ __VA_ARGS__)
0 commit comments