Skip to content

Commit dd9009e

Browse files
committed
🐛 ASSERT should return on failure
1 parent 2f8d95a commit dd9009e

File tree

3 files changed

+73
-32
lines changed

3 files changed

+73
-32
lines changed

include/GUnit/GAssert.h

Lines changed: 72 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <gtest/gtest.h>
1111

1212
#include <string>
13+
1314
#include "GUnit/Detail/StringUtils.h"
1415

1516
namespace 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)>
2829
class 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>
5364
class 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__)

include/GUnit/GSteps.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ class Steps : public ::testing::EmptyTestEventListener {
388388
return Step<-1, true>{*this, {"Then", File::c_str(), line}, pattern};
389389
}
390390

391-
// clang-format off
391+
// clang-format off
392392
#if defined(__clang__)
393393
#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension"
394394
#endif

test/GAssert.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ TEST(GAssert, ShouldSupportASSERT) {
3838

3939
ASSERT(i == 42);
4040
ASSERT(42 == i);
41-
ASSERT(42 == i);
4241

4342
ASSERT(i != 0);
4443
ASSERT(0 != i);

0 commit comments

Comments
 (0)