1010#include < gtest/gtest.h>
1111
1212#include < string>
13+
1314#include " GUnit/Detail/StringUtils.h"
1415
1516namespace testing {
@@ -23,40 +24,56 @@ struct info {
2324 TestPartResult::Type failure{};
2425};
2526
26- template <class TLhs , class TRhs ,
27+ template <class TShouldError , class TLhs , class TRhs ,
2728 AssertionResult (*Comp)(const char *, const char *, TLhs, TRhs)>
2829class msg : public decltype(Message()) {
2930 public:
3031 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_)} {}
3237 ~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+ }
4350 }
4451 }
4552
53+ operator bool () const { return result_; }
54+
4655 private:
4756 info info_{};
4857 std::string comp_{};
4958 TLhs lhs_;
5059 TRhs rhs_;
60+ bool result_{};
5161};
5262
63+ template <class TShouldError >
5364class op {
5465 template <class TLhs >
5566 class comp : public decltype (Message()) {
5667 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+
5874 ~comp () {
59- if (!followed_ && std::is_same<bool , TLhs>::value) {
75+ if (TShouldError::value && !followed_ &&
76+ std::is_same<bool , TLhs>::value) {
6077 const AssertionResult gtest_ar =
6178 (internal::CmpHelperEQ (info_.expr .c_str (), " true" , lhs_, true ));
6279 if (!gtest_ar) {
@@ -72,8 +89,9 @@ class op {
7289 int > = 0 >
7390 auto operator ==(const TRhs& rhs) const {
7491 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};
7795 }
7896
7997 template <class TRhs ,
@@ -82,49 +100,52 @@ class op {
82100 int > = 0 >
83101 auto operator ==(const TRhs& rhs) const {
84102 followed_ = true ;
85- return msg<const TLhs&, const TRhs&, internal::CmpHelperEQ>{
103+ return msg<TShouldError, const TLhs&, const TRhs&, internal::CmpHelperEQ>{
86104 info_, " ==" , lhs_, rhs};
87105 }
88106
89107 template <class TRhs >
90108 auto operator !=(const TRhs& rhs) const {
91109 followed_ = true ;
92- return msg<const TLhs&, const TRhs&, internal::CmpHelperNE>{
110+ return msg<TShouldError, const TLhs&, const TRhs&, internal::CmpHelperNE>{
93111 info_, " !=" , lhs_, rhs};
94112 }
95113
96114 template <class TRhs >
97115 auto operator >(const TRhs& rhs) const {
98116 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};
101119 }
102120
103121 template <class TRhs >
104122 auto operator >=(const TRhs& rhs) const {
105123 followed_ = true ;
106- return msg<const TLhs&, const TRhs&, internal::CmpHelperGE>{
124+ return msg<TShouldError, const TLhs&, const TRhs&, internal::CmpHelperGE>{
107125 info_, " >=" , lhs_, rhs};
108126 }
109127
110128 template <class TRhs >
111129 auto operator <=(const TRhs& rhs) const {
112130 followed_ = true ;
113- return msg<const TLhs&, const TRhs&, internal::CmpHelperLE>{
131+ return msg<TShouldError, const TLhs&, const TRhs&, internal::CmpHelperLE>{
114132 info_, " <=" , lhs_, rhs};
115133 }
116134
117135 template <class TRhs >
118136 auto operator <(const TRhs& rhs) const {
119137 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};
122140 }
123141
142+ operator bool () const { return result_; }
143+
124144 private:
125145 info info_{};
126146 TLhs lhs_{};
127147 mutable bool followed_{false };
148+ bool result_{};
128149 };
129150
130151 public:
@@ -138,17 +159,38 @@ class op {
138159 private:
139160 info info_{};
140161};
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+
141175} // namespace detail
142176} // namespace v1
143177} // namespace testing
144178
145179#define EXPECT (...) \
146- (::testing::detail::op{ \
180+ (::testing::detail::op<std::true_type>{ \
147181 ::testing::detail::info{__FILE__, __LINE__, #__VA_ARGS__, \
148182 ::testing::TestPartResult::kNonFatalFailure }} % \
149183 __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