• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 // This test directly verifies the facade logic, by leveraging a fake backend
16 // that captures arguments and returns rather than aborting execution.
17 
18 #include "pw_assert_test/fake_backend.h"
19 
20 // This directly includes the assert facade implementation header rather than
21 // going through the backend header indirection mechanism, to prevent the real
22 // assert backend from triggering.
23 //
24 // clang-format off
25 #include "pw_assert/internal/check_impl.h"
26 // clang-format on
27 
28 #include "pw_compilation_testing/negative_compilation.h"
29 #include "pw_status/status.h"
30 #include "pw_unit_test/framework.h"
31 
32 namespace {
33 
34 #define EXPECT_MESSAGE(expected_assert_message)                        \
35   do {                                                                 \
36     EXPECT_STREQ(pw_captured_assert.message, expected_assert_message); \
37   } while (0)
38 
39 class AssertFailTest : public ::testing::Test {
40  protected:
SetUp()41   void SetUp() override { pw_captured_assert.triggered = 0; }
TearDown()42   void TearDown() override { EXPECT_EQ(pw_captured_assert.triggered, 1); }
43 };
44 
45 class AssertPassTest : public ::testing::Test {
46  protected:
SetUp()47   void SetUp() override { pw_captured_assert.triggered = 0; }
TearDown()48   void TearDown() override { EXPECT_EQ(pw_captured_assert.triggered, 0); }
49 };
50 
51 // PW_CRASH(...)
TEST_F(AssertFailTest,CrashMessageNoArguments)52 TEST_F(AssertFailTest, CrashMessageNoArguments) {
53   PW_CRASH("Goodbye");
54   EXPECT_MESSAGE("Goodbye");
55 }
TEST_F(AssertFailTest,CrashMessageWithArguments)56 TEST_F(AssertFailTest, CrashMessageWithArguments) {
57   PW_CRASH("Goodbye cruel %s", "world");
58   EXPECT_MESSAGE("Goodbye cruel world");
59 }
60 
61 // PW_CHECK(...) - No message
TEST_F(AssertPassTest,CheckNoMessage)62 TEST_F(AssertPassTest, CheckNoMessage) { PW_CHECK(true); }
TEST_F(AssertFailTest,CheckNoMessage)63 TEST_F(AssertFailTest, CheckNoMessage) {
64   PW_CHECK(false);
65   EXPECT_MESSAGE("Check failed: false. ");
66 }
TEST_F(AssertPassTest,CheckNoMessageComplexExpression)67 TEST_F(AssertPassTest, CheckNoMessageComplexExpression) { PW_CHECK(2 == 2); }
TEST_F(AssertFailTest,CheckNoMessageComplexExpression)68 TEST_F(AssertFailTest, CheckNoMessageComplexExpression) {
69   PW_CHECK(1 == 2);
70   EXPECT_MESSAGE("Check failed: 1 == 2. ");
71 }
72 
73 // PW_CHECK(..., msg) - With message; with and without arguments.
TEST_F(AssertPassTest,CheckMessageNoArguments)74 TEST_F(AssertPassTest, CheckMessageNoArguments) { PW_CHECK(true, "Hello"); }
TEST_F(AssertFailTest,CheckMessageNoArguments)75 TEST_F(AssertFailTest, CheckMessageNoArguments) {
76   PW_CHECK(false, "Hello");
77   EXPECT_MESSAGE("Check failed: false. Hello");
78 }
TEST_F(AssertPassTest,CheckMessageWithArguments)79 TEST_F(AssertPassTest, CheckMessageWithArguments) {
80   PW_CHECK(true, "Hello %d", 5);
81 }
TEST_F(AssertFailTest,CheckMessageWithArguments)82 TEST_F(AssertFailTest, CheckMessageWithArguments) {
83   PW_CHECK(false, "Hello %d", 5);
84   EXPECT_MESSAGE("Check failed: false. Hello 5");
85 }
86 
87 // PW_CHECK_INT_*(...)
88 // Binary checks with ints, comparisons: <, <=, =, !=, >, >=.
89 
90 // Test message formatting separate from the triggering.
91 // Only test formatting for the type once.
TEST_F(AssertFailTest,IntLessThanNoMessageNoArguments)92 TEST_F(AssertFailTest, IntLessThanNoMessageNoArguments) {
93   PW_CHECK_INT_LT(5, -2);
94   EXPECT_MESSAGE("Check failed: 5 (=5) < -2 (=-2). ");
95 }
TEST_F(AssertFailTest,IntLessThanMessageNoArguments)96 TEST_F(AssertFailTest, IntLessThanMessageNoArguments) {
97   PW_CHECK_INT_LT(5, -2, "msg");
98   EXPECT_MESSAGE("Check failed: 5 (=5) < -2 (=-2). msg");
99 }
TEST_F(AssertFailTest,IntLessThanMessageArguments)100 TEST_F(AssertFailTest, IntLessThanMessageArguments) {
101   PW_CHECK_INT_LT(5, -2, "msg: %d", 6);
102   EXPECT_MESSAGE("Check failed: 5 (=5) < -2 (=-2). msg: 6");
103 }
104 
105 // Test comparison boundaries.
106 
107 // INT <
TEST_F(AssertPassTest,IntLt1)108 TEST_F(AssertPassTest, IntLt1) { PW_CHECK_INT_LT(-1, 2); }
TEST_F(AssertPassTest,IntLt2)109 TEST_F(AssertPassTest, IntLt2) { PW_CHECK_INT_LT(1, 2); }
TEST_F(AssertFailTest,IntLt3)110 TEST_F(AssertFailTest, IntLt3) { PW_CHECK_INT_LT(-1, -2); }
TEST_F(AssertFailTest,IntLt4)111 TEST_F(AssertFailTest, IntLt4) { PW_CHECK_INT_LT(1, 1); }
112 
113 // INT <=
TEST_F(AssertPassTest,IntLe1)114 TEST_F(AssertPassTest, IntLe1) { PW_CHECK_INT_LE(-1, 2); }
TEST_F(AssertPassTest,IntLe2)115 TEST_F(AssertPassTest, IntLe2) { PW_CHECK_INT_LE(1, 2); }
TEST_F(AssertFailTest,IntLe3)116 TEST_F(AssertFailTest, IntLe3) { PW_CHECK_INT_LE(-1, -2); }
TEST_F(AssertPassTest,IntLe4)117 TEST_F(AssertPassTest, IntLe4) { PW_CHECK_INT_LE(1, 1); }
118 
119 // INT ==
TEST_F(AssertFailTest,IntEq1)120 TEST_F(AssertFailTest, IntEq1) { PW_CHECK_INT_EQ(-1, 2); }
TEST_F(AssertFailTest,IntEq2)121 TEST_F(AssertFailTest, IntEq2) { PW_CHECK_INT_EQ(1, 2); }
TEST_F(AssertFailTest,IntEq3)122 TEST_F(AssertFailTest, IntEq3) { PW_CHECK_INT_EQ(-1, -2); }
TEST_F(AssertPassTest,IntEq4)123 TEST_F(AssertPassTest, IntEq4) { PW_CHECK_INT_EQ(1, 1); }
124 
125 // INT !=
TEST_F(AssertPassTest,IntNe1)126 TEST_F(AssertPassTest, IntNe1) { PW_CHECK_INT_NE(-1, 2); }
TEST_F(AssertPassTest,IntNe2)127 TEST_F(AssertPassTest, IntNe2) { PW_CHECK_INT_NE(1, 2); }
TEST_F(AssertPassTest,IntNe3)128 TEST_F(AssertPassTest, IntNe3) { PW_CHECK_INT_NE(-1, -2); }
TEST_F(AssertFailTest,IntNe4)129 TEST_F(AssertFailTest, IntNe4) { PW_CHECK_INT_NE(1, 1); }
130 
131 // INT >
TEST_F(AssertFailTest,IntGt1)132 TEST_F(AssertFailTest, IntGt1) { PW_CHECK_INT_GT(-1, 2); }
TEST_F(AssertFailTest,IntGt2)133 TEST_F(AssertFailTest, IntGt2) { PW_CHECK_INT_GT(1, 2); }
TEST_F(AssertPassTest,IntGt3)134 TEST_F(AssertPassTest, IntGt3) { PW_CHECK_INT_GT(-1, -2); }
TEST_F(AssertFailTest,IntGt4)135 TEST_F(AssertFailTest, IntGt4) { PW_CHECK_INT_GT(1, 1); }
136 
137 // INT >=
TEST_F(AssertFailTest,IntGe1)138 TEST_F(AssertFailTest, IntGe1) { PW_CHECK_INT_GE(-1, 2); }
TEST_F(AssertFailTest,IntGe2)139 TEST_F(AssertFailTest, IntGe2) { PW_CHECK_INT_GE(1, 2); }
TEST_F(AssertPassTest,IntGe3)140 TEST_F(AssertPassTest, IntGe3) { PW_CHECK_INT_GE(-1, -2); }
TEST_F(AssertPassTest,IntGe4)141 TEST_F(AssertPassTest, IntGe4) { PW_CHECK_INT_GE(1, 1); }
142 
143 // PW_CHECK_UINT_*(...)
144 // Binary checks with uints, comparisons: <, <=, =, !=, >, >=.
145 
146 // Test message formatting separate from the triggering.
147 // Only test formatting for the type once.
TEST_F(AssertFailTest,UintLessThanNoMessageNoArguments)148 TEST_F(AssertFailTest, UintLessThanNoMessageNoArguments) {
149   PW_CHECK_UINT_LT(5, 2);
150   EXPECT_MESSAGE("Check failed: 5 (=5) < 2 (=2). ");
151 }
TEST_F(AssertFailTest,UintLessThanMessageNoArguments)152 TEST_F(AssertFailTest, UintLessThanMessageNoArguments) {
153   PW_CHECK_UINT_LT(5, 2, "msg");
154   EXPECT_MESSAGE("Check failed: 5 (=5) < 2 (=2). msg");
155 }
TEST_F(AssertFailTest,UintLessThanMessageArguments)156 TEST_F(AssertFailTest, UintLessThanMessageArguments) {
157   PW_CHECK_UINT_LT(5, 2, "msg: %d", 6);
158   EXPECT_MESSAGE("Check failed: 5 (=5) < 2 (=2). msg: 6");
159 }
160 
161 // Test comparison boundaries.
162 
163 // UINT <
TEST_F(AssertPassTest,UintLt1)164 TEST_F(AssertPassTest, UintLt1) { PW_CHECK_UINT_LT(1, 2); }
TEST_F(AssertFailTest,UintLt2)165 TEST_F(AssertFailTest, UintLt2) { PW_CHECK_UINT_LT(2, 2); }
TEST_F(AssertFailTest,UintLt3)166 TEST_F(AssertFailTest, UintLt3) { PW_CHECK_UINT_LT(2, 1); }
167 
168 // UINT <=
TEST_F(AssertPassTest,UintLe1)169 TEST_F(AssertPassTest, UintLe1) { PW_CHECK_UINT_LE(1, 2); }
TEST_F(AssertPassTest,UintLe2)170 TEST_F(AssertPassTest, UintLe2) { PW_CHECK_UINT_LE(2, 2); }
TEST_F(AssertFailTest,UintLe3)171 TEST_F(AssertFailTest, UintLe3) { PW_CHECK_UINT_LE(2, 1); }
172 
173 // UINT ==
TEST_F(AssertFailTest,UintEq1)174 TEST_F(AssertFailTest, UintEq1) { PW_CHECK_UINT_EQ(1, 2); }
TEST_F(AssertPassTest,UintEq2)175 TEST_F(AssertPassTest, UintEq2) { PW_CHECK_UINT_EQ(2, 2); }
TEST_F(AssertFailTest,UintEq3)176 TEST_F(AssertFailTest, UintEq3) { PW_CHECK_UINT_EQ(2, 1); }
177 
178 // UINT !=
TEST_F(AssertPassTest,UintNe1)179 TEST_F(AssertPassTest, UintNe1) { PW_CHECK_UINT_NE(1, 2); }
TEST_F(AssertFailTest,UintNe2)180 TEST_F(AssertFailTest, UintNe2) { PW_CHECK_UINT_NE(2, 2); }
TEST_F(AssertPassTest,UintNe3)181 TEST_F(AssertPassTest, UintNe3) { PW_CHECK_UINT_NE(2, 1); }
182 
183 // UINT >
TEST_F(AssertFailTest,UintGt1)184 TEST_F(AssertFailTest, UintGt1) { PW_CHECK_UINT_GT(1, 2); }
TEST_F(AssertFailTest,UintGt2)185 TEST_F(AssertFailTest, UintGt2) { PW_CHECK_UINT_GT(2, 2); }
TEST_F(AssertPassTest,UintGt3)186 TEST_F(AssertPassTest, UintGt3) { PW_CHECK_UINT_GT(2, 1); }
187 
188 // UINT >=
TEST_F(AssertFailTest,UintGe1)189 TEST_F(AssertFailTest, UintGe1) { PW_CHECK_UINT_GE(1, 2); }
TEST_F(AssertPassTest,UintGe2)190 TEST_F(AssertPassTest, UintGe2) { PW_CHECK_UINT_GE(2, 2); }
TEST_F(AssertPassTest,UintGe3)191 TEST_F(AssertPassTest, UintGe3) { PW_CHECK_UINT_GE(2, 1); }
192 
193 // PW_CHECK_PTR_*(...)
194 // Binary checks with uints, comparisons: <, <=, =, !=, >, >=.
195 // Note: The format checks are skipped since they're not portable.
196 
197 // Test comparison boundaries.
198 
199 // PTR <
TEST_F(AssertPassTest,PtrLt1)200 TEST_F(AssertPassTest, PtrLt1) {
201   PW_CHECK_PTR_LT(reinterpret_cast<void*>(0xa), reinterpret_cast<void*>(0xb));
202 }
TEST_F(AssertFailTest,PtrLt2)203 TEST_F(AssertFailTest, PtrLt2) {
204   PW_CHECK_PTR_LT(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xb));
205 }
TEST_F(AssertFailTest,PtrLt3)206 TEST_F(AssertFailTest, PtrLt3) {
207   PW_CHECK_PTR_LT(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xa));
208 }
209 
210 // PTR <=
TEST_F(AssertPassTest,PtrLe1)211 TEST_F(AssertPassTest, PtrLe1) {
212   PW_CHECK_PTR_LE(reinterpret_cast<void*>(0xa), reinterpret_cast<void*>(0xb));
213 }
TEST_F(AssertPassTest,PtrLe2)214 TEST_F(AssertPassTest, PtrLe2) {
215   PW_CHECK_PTR_LE(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xb));
216 }
TEST_F(AssertFailTest,PtrLe3)217 TEST_F(AssertFailTest, PtrLe3) {
218   PW_CHECK_PTR_LE(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xa));
219 }
220 
221 // PTR ==
TEST_F(AssertFailTest,PtrEq1)222 TEST_F(AssertFailTest, PtrEq1) {
223   PW_CHECK_PTR_EQ(reinterpret_cast<void*>(0xa), reinterpret_cast<void*>(0xb));
224 }
TEST_F(AssertPassTest,PtrEq2)225 TEST_F(AssertPassTest, PtrEq2) {
226   PW_CHECK_PTR_EQ(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xb));
227 }
TEST_F(AssertFailTest,PtrEq3)228 TEST_F(AssertFailTest, PtrEq3) {
229   PW_CHECK_PTR_EQ(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xa));
230 }
231 
232 // PTR !=
TEST_F(AssertPassTest,PtrNe1)233 TEST_F(AssertPassTest, PtrNe1) {
234   PW_CHECK_PTR_NE(reinterpret_cast<void*>(0xa), reinterpret_cast<void*>(0xb));
235 }
TEST_F(AssertFailTest,PtrNe2)236 TEST_F(AssertFailTest, PtrNe2) {
237   PW_CHECK_PTR_NE(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xb));
238 }
TEST_F(AssertPassTest,PtrNe3)239 TEST_F(AssertPassTest, PtrNe3) {
240   PW_CHECK_PTR_NE(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xa));
241 }
242 
243 // PTR >
TEST_F(AssertFailTest,PtrGt1)244 TEST_F(AssertFailTest, PtrGt1) {
245   PW_CHECK_PTR_GT(reinterpret_cast<void*>(0xa), reinterpret_cast<void*>(0xb));
246 }
TEST_F(AssertFailTest,PtrGt2)247 TEST_F(AssertFailTest, PtrGt2) {
248   PW_CHECK_PTR_GT(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xb));
249 }
TEST_F(AssertPassTest,PtrGt3)250 TEST_F(AssertPassTest, PtrGt3) {
251   PW_CHECK_PTR_GT(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xa));
252 }
253 
254 // PTR >=
TEST_F(AssertFailTest,PtrGe1)255 TEST_F(AssertFailTest, PtrGe1) {
256   PW_CHECK_PTR_GE(reinterpret_cast<void*>(0xa), reinterpret_cast<void*>(0xb));
257 }
TEST_F(AssertPassTest,PtrGe2)258 TEST_F(AssertPassTest, PtrGe2) {
259   PW_CHECK_PTR_GE(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xb));
260 }
TEST_F(AssertPassTest,PtrGe3)261 TEST_F(AssertPassTest, PtrGe3) {
262   PW_CHECK_PTR_GE(reinterpret_cast<void*>(0xb), reinterpret_cast<void*>(0xa));
263 }
264 
265 // NOTNULL
TEST_F(AssertPassTest,PtrNotNull)266 TEST_F(AssertPassTest, PtrNotNull) {
267   PW_CHECK_NOTNULL(reinterpret_cast<void*>(0xa));
268 }
TEST_F(AssertFailTest,PtrNotNull)269 TEST_F(AssertFailTest, PtrNotNull) {
270   PW_CHECK_NOTNULL(reinterpret_cast<void*>(0x0));
271 }
272 
Function1()273 [[maybe_unused]] void Function1() {}
Function2(int)274 [[maybe_unused]] bool Function2(int) { return false; }
275 
276 // NOTNULL for function poionters
TEST_F(AssertPassTest,FunctionPtrNotNull)277 TEST_F(AssertPassTest, FunctionPtrNotNull) {
278   PW_CHECK_NOTNULL(&Function1);
279   PW_CHECK_NOTNULL(&Function2);
280 }
TEST_F(AssertFailTest,FunctionPtrNotNull)281 TEST_F(AssertFailTest, FunctionPtrNotNull) {
282   void (*const function)() = nullptr;
283   PW_CHECK_NOTNULL(function);
284 }
285 
CompareIntWithString()286 [[maybe_unused]] void CompareIntWithString() {
287 #if PW_NC_TEST(CompareIntWithString)
288   PW_NC_EXPECT("cannot initialize|invalid conversion");
289 
290   PW_CHECK_INT_EQ(123l, "This check message is accidentally compared to 123!");
291 #endif  // PW_NC_TEST
292 }
293 
294 // Note: Due to platform inconsistencies, the below test for the NOTNULL
295 // message doesn't work. Some platforms print NULL formatted as %p as "(nil)",
296 // others "0x0". Leaving this here for reference.
297 //
298 //   TEST_F(AssertFailTest, PtrNotNullDescription) {
299 //     intptr_t intptr = 0;
300 //     PW_CHECK_NOTNULL(intptr);
301 //     EXPECT_MESSAGE("Check failed: intptr (=0x0) != nullptr (=0x0). ");
302 //   }
303 
304 // PW_CHECK_FLOAT_*(...)
305 // Binary checks with floats, comparisons: EXACT_LT, EXACT_LE, NEAR, EXACT_EQ,
306 // EXACT_NE, EXACT_GE, EXACT_GT.
307 
308 // Test message formatting separate from the triggering.
309 // Only test formatting for the type once.
TEST_F(AssertFailTest,FloatLessThanNoMessageNoArguments)310 TEST_F(AssertFailTest, FloatLessThanNoMessageNoArguments) {
311   PW_CHECK_FLOAT_EXACT_LT(5.2, 2.3);
312   EXPECT_MESSAGE("Check failed: 5.2 (=5.200000) < 2.3 (=2.300000). ");
313 }
TEST_F(AssertFailTest,FloatLessThanMessageNoArguments)314 TEST_F(AssertFailTest, FloatLessThanMessageNoArguments) {
315   PW_CHECK_FLOAT_EXACT_LT(5.2, 2.3, "msg");
316   EXPECT_MESSAGE("Check failed: 5.2 (=5.200000) < 2.3 (=2.300000). msg");
317 }
TEST_F(AssertFailTest,FloatLessThanMessageArguments)318 TEST_F(AssertFailTest, FloatLessThanMessageArguments) {
319   PW_CHECK_FLOAT_EXACT_LT(5.2, 2.3, "msg: %d", 6);
320   EXPECT_MESSAGE("Check failed: 5.2 (=5.200000) < 2.3 (=2.300000). msg: 6");
321 }
322 // Check float NEAR both above and below the permitted range.
TEST_F(AssertFailTest,FloatNearAboveNoMessageNoArguments)323 TEST_F(AssertFailTest, FloatNearAboveNoMessageNoArguments) {
324   PW_CHECK_FLOAT_NEAR(5.2, 2.3, 0.1);
325   EXPECT_MESSAGE(
326       "Check failed: 5.2 (=5.200000) <= 2.3 + abs_tolerance (=2.400000). ");
327 }
TEST_F(AssertFailTest,FloatNearAboveMessageNoArguments)328 TEST_F(AssertFailTest, FloatNearAboveMessageNoArguments) {
329   PW_CHECK_FLOAT_NEAR(5.2, 2.3, 0.1, "msg");
330   EXPECT_MESSAGE(
331       "Check failed: 5.2 (=5.200000) <= 2.3 + abs_tolerance (=2.400000). msg");
332 }
TEST_F(AssertFailTest,FloatNearAboveMessageArguments)333 TEST_F(AssertFailTest, FloatNearAboveMessageArguments) {
334   PW_CHECK_FLOAT_NEAR(5.2, 2.3, 0.1, "msg: %d", 6);
335   EXPECT_MESSAGE(
336       "Check failed: 5.2 (=5.200000) <= 2.3 + abs_tolerance (=2.400000). msg: "
337       "6");
338 }
TEST_F(AssertFailTest,FloatNearBelowNoMessageNoArguments)339 TEST_F(AssertFailTest, FloatNearBelowNoMessageNoArguments) {
340   PW_CHECK_FLOAT_NEAR(1.2, 2.3, 0.1);
341   EXPECT_MESSAGE(
342       "Check failed: 1.2 (=1.200000) >= 2.3 - abs_tolerance (=2.200000). ");
343 }
TEST_F(AssertFailTest,FloatNearBelowMessageNoArguments)344 TEST_F(AssertFailTest, FloatNearBelowMessageNoArguments) {
345   PW_CHECK_FLOAT_NEAR(1.2, 2.3, 0.1, "msg");
346   EXPECT_MESSAGE(
347       "Check failed: 1.2 (=1.200000) >= 2.3 - abs_tolerance (=2.200000). msg");
348 }
TEST_F(AssertFailTest,FloatNearBelowMessageArguments)349 TEST_F(AssertFailTest, FloatNearBelowMessageArguments) {
350   PW_CHECK_FLOAT_NEAR(1.2, 2.3, 0.1, "msg: %d", 6);
351   EXPECT_MESSAGE(
352       "Check failed: 1.2 (=1.200000) >= 2.3 - abs_tolerance (=2.200000). msg: "
353       "6");
354 }
355 // Test comparison boundaries.
356 // Note: The below example numbers all round to integer 1, to detect accidental
357 // integer conversions in the asserts.
358 
359 // FLOAT <
TEST_F(AssertPassTest,FloatLt1)360 TEST_F(AssertPassTest, FloatLt1) { PW_CHECK_FLOAT_EXACT_LT(1.1, 1.2); }
TEST_F(AssertFailTest,FloatLt2)361 TEST_F(AssertFailTest, FloatLt2) { PW_CHECK_FLOAT_EXACT_LT(1.2, 1.2); }
TEST_F(AssertFailTest,FloatLt3)362 TEST_F(AssertFailTest, FloatLt3) { PW_CHECK_FLOAT_EXACT_LT(1.2, 1.1); }
363 
364 // FLOAT <=
TEST_F(AssertPassTest,FloatLe1)365 TEST_F(AssertPassTest, FloatLe1) { PW_CHECK_FLOAT_EXACT_LE(1.1, 1.2); }
TEST_F(AssertPassTest,FloatLe2)366 TEST_F(AssertPassTest, FloatLe2) { PW_CHECK_FLOAT_EXACT_LE(1.2, 1.2); }
TEST_F(AssertFailTest,FloatLe3)367 TEST_F(AssertFailTest, FloatLe3) { PW_CHECK_FLOAT_EXACT_LE(1.2, 1.1); }
368 
369 // FLOAT ~= based on absolute error.
TEST_F(AssertFailTest,FloatNearAbs1)370 TEST_F(AssertFailTest, FloatNearAbs1) { PW_CHECK_FLOAT_NEAR(1.09, 1.2, 0.1); }
TEST_F(AssertPassTest,FloatNearAbs2)371 TEST_F(AssertPassTest, FloatNearAbs2) { PW_CHECK_FLOAT_NEAR(1.1, 1.2, 0.1); }
TEST_F(AssertPassTest,FloatNearAbs3)372 TEST_F(AssertPassTest, FloatNearAbs3) { PW_CHECK_FLOAT_NEAR(1.2, 1.2, 0.1); }
TEST_F(AssertPassTest,FloatNearAbs4)373 TEST_F(AssertPassTest, FloatNearAbs4) { PW_CHECK_FLOAT_NEAR(1.2, 1.1, 0.1); }
TEST_F(AssertFailTest,FloatNearAbs5)374 TEST_F(AssertFailTest, FloatNearAbs5) { PW_CHECK_FLOAT_NEAR(1.21, 1.1, 0.1); }
375 // Make sure the abs_tolerance is asserted to be >= 0.
TEST_F(AssertFailTest,FloatNearAbs6)376 TEST_F(AssertFailTest, FloatNearAbs6) { PW_CHECK_FLOAT_NEAR(1.2, 1.2, -0.1); }
TEST_F(AssertPassTest,FloatNearAbs7)377 TEST_F(AssertPassTest, FloatNearAbs7) { PW_CHECK_FLOAT_NEAR(1.2, 1.2, 0.0); }
378 
379 // FLOAT ==
TEST_F(AssertFailTest,FloatEq1)380 TEST_F(AssertFailTest, FloatEq1) { PW_CHECK_FLOAT_EXACT_EQ(1.1, 1.2); }
TEST_F(AssertPassTest,FloatEq2)381 TEST_F(AssertPassTest, FloatEq2) { PW_CHECK_FLOAT_EXACT_EQ(1.2, 1.2); }
TEST_F(AssertFailTest,FloatEq3)382 TEST_F(AssertFailTest, FloatEq3) { PW_CHECK_FLOAT_EXACT_EQ(1.2, 1.1); }
383 
384 // FLOAT !=
TEST_F(AssertPassTest,FloatNe1)385 TEST_F(AssertPassTest, FloatNe1) { PW_CHECK_FLOAT_EXACT_NE(1.1, 1.2); }
TEST_F(AssertFailTest,FloatNe2)386 TEST_F(AssertFailTest, FloatNe2) { PW_CHECK_FLOAT_EXACT_NE(1.2, 1.2); }
TEST_F(AssertPassTest,FloatNe3)387 TEST_F(AssertPassTest, FloatNe3) { PW_CHECK_FLOAT_EXACT_NE(1.2, 1.1); }
388 
389 // FLOAT >
TEST_F(AssertFailTest,FloatGt1)390 TEST_F(AssertFailTest, FloatGt1) { PW_CHECK_FLOAT_EXACT_GT(1.1, 1.2); }
TEST_F(AssertFailTest,FloatGt2)391 TEST_F(AssertFailTest, FloatGt2) { PW_CHECK_FLOAT_EXACT_GT(1.2, 1.2); }
TEST_F(AssertPassTest,FloatGt3)392 TEST_F(AssertPassTest, FloatGt3) { PW_CHECK_FLOAT_EXACT_GT(1.2, 1.1); }
393 
394 // FLOAT >=
TEST_F(AssertFailTest,FloatGe1)395 TEST_F(AssertFailTest, FloatGe1) { PW_CHECK_FLOAT_EXACT_GE(1.1, 1.2); }
TEST_F(AssertPassTest,FloatGe2)396 TEST_F(AssertPassTest, FloatGe2) { PW_CHECK_FLOAT_EXACT_GE(1.2, 1.2); }
TEST_F(AssertPassTest,FloatGe3)397 TEST_F(AssertPassTest, FloatGe3) { PW_CHECK_FLOAT_EXACT_GE(1.2, 1.1); }
398 
399 // Nested comma handling.
Add3(int a,int b,int c)400 static int Add3(int a, int b, int c) { return a + b + c; }
401 
TEST_F(AssertFailTest,CommaHandlingLeftSide)402 TEST_F(AssertFailTest, CommaHandlingLeftSide) {
403   PW_CHECK_INT_EQ(Add3(1, 2, 3), 4);
404   EXPECT_MESSAGE("Check failed: Add3(1, 2, 3) (=6) == 4 (=4). ");
405 }
TEST_F(AssertFailTest,CommaHandlingRightSide)406 TEST_F(AssertFailTest, CommaHandlingRightSide) {
407   PW_CHECK_INT_EQ(4, Add3(1, 2, 3));
408   EXPECT_MESSAGE("Check failed: 4 (=4) == Add3(1, 2, 3) (=6). ");
409 }
410 
411 // Verify that the CHECK_*(x,y) macros only evaluate their arguments once.
412 struct MultiEvaluateTestContext {
IncrementAndReturnZero__anon7cbe5ff80111::MultiEvaluateTestContext413   int IncrementAndReturnZero() {
414     counter += 1;
415     return 0;
416   }
417   int counter = 0;
418 };
419 
TEST(AssertPass,CheckSingleSideEffectingCall)420 TEST(AssertPass, CheckSingleSideEffectingCall) {
421   MultiEvaluateTestContext ctx;
422   PW_CHECK(ctx.IncrementAndReturnZero() == 0);
423   EXPECT_EQ(ctx.counter, 1);
424 }
TEST(AssertFail,CheckSingleSideEffectingCall)425 TEST(AssertFail, CheckSingleSideEffectingCall) {
426   MultiEvaluateTestContext ctx;
427   PW_CHECK(ctx.IncrementAndReturnZero() == 1);
428   EXPECT_EQ(ctx.counter, 1);
429 }
TEST(AssertPass,BinaryOpSingleSideEffectingCall)430 TEST(AssertPass, BinaryOpSingleSideEffectingCall) {
431   MultiEvaluateTestContext ctx;
432   PW_CHECK_INT_EQ(0, ctx.IncrementAndReturnZero());
433   EXPECT_EQ(ctx.counter, 1);
434 }
TEST(AssertPass,BinaryOpTwoSideEffectingCalls)435 TEST(AssertPass, BinaryOpTwoSideEffectingCalls) {
436   MultiEvaluateTestContext ctx;
437   PW_CHECK_INT_EQ(ctx.IncrementAndReturnZero(), ctx.IncrementAndReturnZero());
438   EXPECT_EQ(ctx.counter, 2);
439 }
TEST(AssertFail,BinaryOpSingleSideEffectingCall)440 TEST(AssertFail, BinaryOpSingleSideEffectingCall) {
441   MultiEvaluateTestContext ctx;
442   PW_CHECK_INT_EQ(12314, ctx.IncrementAndReturnZero());
443   EXPECT_EQ(ctx.counter, 1);
444 }
TEST(AssertFail,BinaryOpTwoSideEffectingCalls)445 TEST(AssertFail, BinaryOpTwoSideEffectingCalls) {
446   MultiEvaluateTestContext ctx;
447   PW_CHECK_INT_EQ(ctx.IncrementAndReturnZero() + 10,
448                   ctx.IncrementAndReturnZero());
449   EXPECT_EQ(ctx.counter, 2);
450 }
TEST(AssertPass,CheckOkSingleSideEffectingCall)451 TEST(AssertPass, CheckOkSingleSideEffectingCall) {
452   MultiEvaluateTestContext ctx;
453   PW_CHECK_OK(ctx.IncrementAndReturnZero() ? pw::OkStatus() : pw::OkStatus());
454   EXPECT_EQ(ctx.counter, 1);
455 }
TEST(AssertFail,CheckOkSingleSideEffectingCall)456 TEST(AssertFail, CheckOkSingleSideEffectingCall) {
457   MultiEvaluateTestContext ctx;
458   PW_CHECK_OK(ctx.IncrementAndReturnZero() ? pw::Status::NotFound()
459                                            : pw::Status::NotFound());
460   EXPECT_EQ(ctx.counter, 1);
461 }
462 
463 // Verify side effects of debug checks work as expected.
464 // Only check a couple of cases, since the logic is all the same.
465 
466 // When DCHECKs are enabled, they behave the same as normal checks.
467 // When DCHECKs are disabled, they should not trip, and their arguments
468 // shouldn't be evaluated.
469 constexpr int kExpectedSideEffects = PW_ASSERT_ENABLE_DEBUG;
470 
TEST(AssertPass,DCheckEnabledSingleSideEffectingCall)471 TEST(AssertPass, DCheckEnabledSingleSideEffectingCall) {
472   MultiEvaluateTestContext ctx;
473   PW_DCHECK(ctx.IncrementAndReturnZero() == 0);
474   EXPECT_EQ(ctx.counter, kExpectedSideEffects);
475 }
TEST(AssertFail,DCheckEnabledSingleSideEffectingCall)476 TEST(AssertFail, DCheckEnabledSingleSideEffectingCall) {
477   MultiEvaluateTestContext ctx;
478   PW_DCHECK(ctx.IncrementAndReturnZero() == 1);
479   EXPECT_EQ(ctx.counter, kExpectedSideEffects);
480 }
TEST(AssertPass,DCheckEnabledBinaryOpSingleSideEffectingCall)481 TEST(AssertPass, DCheckEnabledBinaryOpSingleSideEffectingCall) {
482   MultiEvaluateTestContext ctx;
483   PW_DCHECK_INT_EQ(0, ctx.IncrementAndReturnZero());
484   EXPECT_EQ(ctx.counter, kExpectedSideEffects);
485 }
TEST(AssertPass,DCheckEnabledBinaryOpTwoSideEffectingCalls)486 TEST(AssertPass, DCheckEnabledBinaryOpTwoSideEffectingCalls) {
487   MultiEvaluateTestContext ctx;
488   PW_DCHECK_INT_EQ(ctx.IncrementAndReturnZero(), ctx.IncrementAndReturnZero());
489   EXPECT_EQ(ctx.counter, 2 * kExpectedSideEffects);
490 }
TEST(AssertFail,DCheckEnabledBinaryOpSingleSideEffectingCall)491 TEST(AssertFail, DCheckEnabledBinaryOpSingleSideEffectingCall) {
492   MultiEvaluateTestContext ctx;
493   PW_DCHECK_INT_EQ(12314, ctx.IncrementAndReturnZero());
494   EXPECT_EQ(ctx.counter, kExpectedSideEffects);
495 }
TEST(AssertFail,DCheckEnabledBinaryOpTwoSideEffectingCalls)496 TEST(AssertFail, DCheckEnabledBinaryOpTwoSideEffectingCalls) {
497   MultiEvaluateTestContext ctx;
498   PW_DCHECK_INT_EQ(ctx.IncrementAndReturnZero() + 10,
499                    ctx.IncrementAndReturnZero());
500   EXPECT_EQ(ctx.counter, 2 * kExpectedSideEffects);
501 }
TEST(AssertPass,DCheckOkSingleSideEffectingCall)502 TEST(AssertPass, DCheckOkSingleSideEffectingCall) {
503   MultiEvaluateTestContext ctx;
504   PW_DCHECK_OK(ctx.IncrementAndReturnZero() ? pw::OkStatus() : pw::OkStatus());
505   EXPECT_EQ(ctx.counter, kExpectedSideEffects);
506 }
TEST(AssertFail,DCheckOkSingleSideEffectingCall)507 TEST(AssertFail, DCheckOkSingleSideEffectingCall) {
508   MultiEvaluateTestContext ctx;
509   PW_DCHECK_OK(ctx.IncrementAndReturnZero() ? pw::Status::NotFound()
510                                             : pw::Status::NotFound());
511   EXPECT_EQ(ctx.counter, kExpectedSideEffects);
512 }
513 
514 // Verify PW_CHECK_OK, including message handling.
TEST_F(AssertFailTest,StatusNotOK)515 TEST_F(AssertFailTest, StatusNotOK) {
516   pw::Status status = pw::Status::Unknown();
517   PW_CHECK_OK(status);
518   EXPECT_MESSAGE("Check failed: status (=UNKNOWN) == OkStatus() (=OK). ");
519 }
520 
TEST_F(AssertFailTest,StatusNotOKMessageNoArguments)521 TEST_F(AssertFailTest, StatusNotOKMessageNoArguments) {
522   pw::Status status = pw::Status::Unknown();
523   PW_CHECK_OK(status, "msg");
524   EXPECT_MESSAGE("Check failed: status (=UNKNOWN) == OkStatus() (=OK). msg");
525 }
526 
TEST_F(AssertFailTest,StatusNotOKMessageArguments)527 TEST_F(AssertFailTest, StatusNotOKMessageArguments) {
528   pw::Status status = pw::Status::Unknown();
529   PW_CHECK_OK(status, "msg: %d", 5);
530   EXPECT_MESSAGE("Check failed: status (=UNKNOWN) == OkStatus() (=OK). msg: 5");
531 }
532 
533 // Example expression for the test below.
DoTheThing()534 pw::Status DoTheThing() { return pw::Status::ResourceExhausted(); }
535 
TEST_F(AssertFailTest,NonTrivialExpression)536 TEST_F(AssertFailTest, NonTrivialExpression) {
537   PW_CHECK_OK(DoTheThing());
538   EXPECT_MESSAGE(
539       "Check failed: DoTheThing() (=RESOURCE_EXHAUSTED) == OkStatus() (=OK). ");
540 }
541 
542 // Note: This function seems pointless but it is not, since pw::Status::FOO
543 // constants are not actually status objects, but code objects. This way we can
544 // ensure the macros work with both real status objects and literals.
TEST_F(AssertPassTest,Function)545 TEST_F(AssertPassTest, Function) { PW_CHECK_OK(pw::OkStatus()); }
TEST_F(AssertPassTest,Enum)546 TEST_F(AssertPassTest, Enum) { PW_CHECK_OK(PW_STATUS_OK); }
TEST_F(AssertFailTest,Function)547 TEST_F(AssertFailTest, Function) { PW_CHECK_OK(pw::Status::Unknown()); }
TEST_F(AssertFailTest,Enum)548 TEST_F(AssertFailTest, Enum) { PW_CHECK_OK(PW_STATUS_UNKNOWN); }
549 
550 #if PW_ASSERT_ENABLE_DEBUG
551 
552 // In debug mode, the asserts should check their arguments.
TEST_F(AssertPassTest,DCheckFunction)553 TEST_F(AssertPassTest, DCheckFunction) { PW_DCHECK_OK(pw::OkStatus()); }
TEST_F(AssertPassTest,DCheckEnum)554 TEST_F(AssertPassTest, DCheckEnum) { PW_DCHECK_OK(PW_STATUS_OK); }
TEST_F(AssertFailTest,DCheckFunction)555 TEST_F(AssertFailTest, DCheckFunction) { PW_DCHECK_OK(pw::Status::Unknown()); }
TEST_F(AssertFailTest,DCheckEnum)556 TEST_F(AssertFailTest, DCheckEnum) { PW_DCHECK_OK(PW_STATUS_UNKNOWN); }
557 #else   // PW_ASSERT_ENABLE_DEBUG
558 
559 // In release mode, all the asserts should pass.
TEST_F(AssertPassTest,DCheckFunction_Ok)560 TEST_F(AssertPassTest, DCheckFunction_Ok) { PW_DCHECK_OK(pw::OkStatus()); }
TEST_F(AssertPassTest,DCheckEnum_Ok)561 TEST_F(AssertPassTest, DCheckEnum_Ok) { PW_DCHECK_OK(PW_STATUS_OK); }
TEST_F(AssertPassTest,DCheckFunction_Err)562 TEST_F(AssertPassTest, DCheckFunction_Err) {
563   PW_DCHECK_OK(pw::Status::Unknown());
564 }
TEST_F(AssertPassTest,DCheckEnum_Err)565 TEST_F(AssertPassTest, DCheckEnum_Err) { PW_DCHECK_OK(PW_STATUS_UNKNOWN); }
566 #endif  // PW_ASSERT_ENABLE_DEBUG
567 
568 // TODO(keir): Figure out how to run some of these tests is C.
569 
570 }  // namespace
571