blob: 088f72596d1a6ef9b04f886dcc8a06a625b71bcb [file] [log] [blame]
Keir Mierle8d2a84f2020-04-14 22:00:00 -07001// 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
Wyatt Heplera59998f2021-03-19 14:35:10 -070025#include "pw_assert/internal/check_impl.h"
Keir Mierle8d2a84f2020-04-14 22:00:00 -070026// clang-format on
27
28#include "gtest/gtest.h"
29
30namespace {
31
32#define EXPECT_MESSAGE(expected_assert_message) \
33 do { \
34 EXPECT_STREQ(pw_captured_assert.message, expected_assert_message); \
35 } while (0)
36
37class AssertFail : public ::testing::Test {
38 protected:
39 void SetUp() override { pw_captured_assert.triggered = 0; }
40 void TearDown() override { EXPECT_EQ(pw_captured_assert.triggered, 1); }
41};
42
43class AssertPass : public ::testing::Test {
44 protected:
45 void SetUp() override { pw_captured_assert.triggered = 0; }
46 void TearDown() override { EXPECT_EQ(pw_captured_assert.triggered, 0); }
47};
48
49// PW_CRASH(...)
50TEST_F(AssertFail, CrashMessageNoArguments) {
51 PW_CRASH("Goodbye");
52 EXPECT_MESSAGE("Goodbye");
53}
54TEST_F(AssertFail, CrashMessageWithArguments) {
55 PW_CRASH("Goodbye cruel %s", "world");
56 EXPECT_MESSAGE("Goodbye cruel world");
57}
58
59// PW_CHECK(...) - No message
60TEST_F(AssertPass, CheckNoMessage) { PW_CHECK(true); }
61TEST_F(AssertFail, CheckNoMessage) {
62 PW_CHECK(false);
63 EXPECT_MESSAGE("Check failed: false. ");
64}
65TEST_F(AssertPass, CheckNoMessageComplexExpression) { PW_CHECK(2 == 2); }
66TEST_F(AssertFail, CheckNoMessageComplexExpression) {
67 PW_CHECK(1 == 2);
68 EXPECT_MESSAGE("Check failed: 1 == 2. ");
69}
70
71// PW_CHECK(..., msg) - With message; with and without arguments.
72TEST_F(AssertPass, CheckMessageNoArguments) { PW_CHECK(true, "Hello"); }
73TEST_F(AssertFail, CheckMessageNoArguments) {
74 PW_CHECK(false, "Hello");
75 EXPECT_MESSAGE("Check failed: false. Hello");
76}
77TEST_F(AssertPass, CheckMessageWithArguments) { PW_CHECK(true, "Hello %d", 5); }
78TEST_F(AssertFail, CheckMessageWithArguments) {
79 PW_CHECK(false, "Hello %d", 5);
80 EXPECT_MESSAGE("Check failed: false. Hello 5");
81}
82
83// PW_CHECK_INT_*(...)
Keir Mierlefa8f89d2020-04-15 16:20:02 -070084// Binary checks with ints, comparisons: <, <=, =, !=, >, >=.
Keir Mierle8d2a84f2020-04-14 22:00:00 -070085
86// Test message formatting separate from the triggering.
87// Only test formatting for the type once.
88TEST_F(AssertFail, IntLessThanNoMessageNoArguments) {
89 PW_CHECK_INT_LT(5, -2);
90 EXPECT_MESSAGE("Check failed: 5 (=5) < -2 (=-2). ");
91}
92TEST_F(AssertFail, IntLessThanMessageNoArguments) {
93 PW_CHECK_INT_LT(5, -2, "msg");
94 EXPECT_MESSAGE("Check failed: 5 (=5) < -2 (=-2). msg");
95}
96TEST_F(AssertFail, IntLessThanMessageArguments) {
97 PW_CHECK_INT_LT(5, -2, "msg: %d", 6);
98 EXPECT_MESSAGE("Check failed: 5 (=5) < -2 (=-2). msg: 6");
99}
100
101// Test comparison boundaries.
102
103// INT <
104TEST_F(AssertPass, IntLt1) { PW_CHECK_INT_LT(-1, 2); }
105TEST_F(AssertPass, IntLt2) { PW_CHECK_INT_LT(1, 2); }
106TEST_F(AssertFail, IntLt3) { PW_CHECK_INT_LT(-1, -2); }
107TEST_F(AssertFail, IntLt4) { PW_CHECK_INT_LT(1, 1); }
108
109// INT <=
110TEST_F(AssertPass, IntLe1) { PW_CHECK_INT_LE(-1, 2); }
111TEST_F(AssertPass, IntLe2) { PW_CHECK_INT_LE(1, 2); }
112TEST_F(AssertFail, IntLe3) { PW_CHECK_INT_LE(-1, -2); }
113TEST_F(AssertPass, IntLe4) { PW_CHECK_INT_LE(1, 1); }
114
115// INT ==
116TEST_F(AssertFail, IntEq1) { PW_CHECK_INT_EQ(-1, 2); }
117TEST_F(AssertFail, IntEq2) { PW_CHECK_INT_EQ(1, 2); }
118TEST_F(AssertFail, IntEq3) { PW_CHECK_INT_EQ(-1, -2); }
119TEST_F(AssertPass, IntEq4) { PW_CHECK_INT_EQ(1, 1); }
120
Keir Mierlefa8f89d2020-04-15 16:20:02 -0700121// INT !=
122TEST_F(AssertPass, IntNe1) { PW_CHECK_INT_NE(-1, 2); }
123TEST_F(AssertPass, IntNe2) { PW_CHECK_INT_NE(1, 2); }
124TEST_F(AssertPass, IntNe3) { PW_CHECK_INT_NE(-1, -2); }
125TEST_F(AssertFail, IntNe4) { PW_CHECK_INT_NE(1, 1); }
126
Keir Mierle8d2a84f2020-04-14 22:00:00 -0700127// INT >
128TEST_F(AssertFail, IntGt1) { PW_CHECK_INT_GT(-1, 2); }
129TEST_F(AssertFail, IntGt2) { PW_CHECK_INT_GT(1, 2); }
130TEST_F(AssertPass, IntGt3) { PW_CHECK_INT_GT(-1, -2); }
131TEST_F(AssertFail, IntGt4) { PW_CHECK_INT_GT(1, 1); }
132
133// INT >=
134TEST_F(AssertFail, IntGe1) { PW_CHECK_INT_GE(-1, 2); }
135TEST_F(AssertFail, IntGe2) { PW_CHECK_INT_GE(1, 2); }
136TEST_F(AssertPass, IntGe3) { PW_CHECK_INT_GE(-1, -2); }
137TEST_F(AssertPass, IntGe4) { PW_CHECK_INT_GE(1, 1); }
138
139// PW_CHECK_UINT_*(...)
Keir Mierlefa8f89d2020-04-15 16:20:02 -0700140// Binary checks with uints, comparisons: <, <=, =, !=, >, >=.
Keir Mierle8d2a84f2020-04-14 22:00:00 -0700141
142// Test message formatting separate from the triggering.
143// Only test formatting for the type once.
144TEST_F(AssertFail, UintLessThanNoMessageNoArguments) {
145 PW_CHECK_UINT_LT(5, 2);
146 EXPECT_MESSAGE("Check failed: 5 (=5) < 2 (=2). ");
147}
148TEST_F(AssertFail, UintLessThanMessageNoArguments) {
149 PW_CHECK_UINT_LT(5, 2, "msg");
150 EXPECT_MESSAGE("Check failed: 5 (=5) < 2 (=2). msg");
151}
152TEST_F(AssertFail, UintLessThanMessageArguments) {
153 PW_CHECK_UINT_LT(5, 2, "msg: %d", 6);
154 EXPECT_MESSAGE("Check failed: 5 (=5) < 2 (=2). msg: 6");
155}
156
157// Test comparison boundaries.
158
159// UINT <
160TEST_F(AssertPass, UintLt1) { PW_CHECK_UINT_LT(1, 2); }
161TEST_F(AssertFail, UintLt2) { PW_CHECK_UINT_LT(2, 2); }
162TEST_F(AssertFail, UintLt3) { PW_CHECK_UINT_LT(2, 1); }
163
164// UINT <=
165TEST_F(AssertPass, UintLe1) { PW_CHECK_UINT_LE(1, 2); }
166TEST_F(AssertPass, UintLe2) { PW_CHECK_UINT_LE(2, 2); }
167TEST_F(AssertFail, UintLe3) { PW_CHECK_UINT_LE(2, 1); }
168
169// UINT ==
170TEST_F(AssertFail, UintEq1) { PW_CHECK_UINT_EQ(1, 2); }
171TEST_F(AssertPass, UintEq2) { PW_CHECK_UINT_EQ(2, 2); }
172TEST_F(AssertFail, UintEq3) { PW_CHECK_UINT_EQ(2, 1); }
173
Keir Mierlefa8f89d2020-04-15 16:20:02 -0700174// UINT !=
175TEST_F(AssertPass, UintNe1) { PW_CHECK_UINT_NE(1, 2); }
176TEST_F(AssertFail, UintNe2) { PW_CHECK_UINT_NE(2, 2); }
177TEST_F(AssertPass, UintNe3) { PW_CHECK_UINT_NE(2, 1); }
178
Keir Mierle8d2a84f2020-04-14 22:00:00 -0700179// UINT >
180TEST_F(AssertFail, UintGt1) { PW_CHECK_UINT_GT(1, 2); }
181TEST_F(AssertFail, UintGt2) { PW_CHECK_UINT_GT(2, 2); }
182TEST_F(AssertPass, UintGt3) { PW_CHECK_UINT_GT(2, 1); }
183
184// UINT >=
185TEST_F(AssertFail, UintGe1) { PW_CHECK_UINT_GE(1, 2); }
186TEST_F(AssertPass, UintGe2) { PW_CHECK_UINT_GE(2, 2); }
187TEST_F(AssertPass, UintGe3) { PW_CHECK_UINT_GE(2, 1); }
188
Keir Mierlefa8f89d2020-04-15 16:20:02 -0700189// PW_CHECK_PTR_*(...)
190// Binary checks with uints, comparisons: <, <=, =, !=, >, >=.
191// Note: The format checks are skipped since they're not portable.
192
193// Test comparison boundaries.
194
195// PTR <
196TEST_F(AssertPass, PtrLt1) { PW_CHECK_PTR_LT(0xa, 0xb); }
197TEST_F(AssertFail, PtrLt2) { PW_CHECK_PTR_LT(0xb, 0xb); }
198TEST_F(AssertFail, PtrLt3) { PW_CHECK_PTR_LT(0xb, 0xa); }
199
200// PTR <=
201TEST_F(AssertPass, PtrLe1) { PW_CHECK_PTR_LE(0xa, 0xb); }
202TEST_F(AssertPass, PtrLe2) { PW_CHECK_PTR_LE(0xb, 0xb); }
203TEST_F(AssertFail, PtrLe3) { PW_CHECK_PTR_LE(0xb, 0xa); }
204
205// PTR ==
206TEST_F(AssertFail, PtrEq1) { PW_CHECK_PTR_EQ(0xa, 0xb); }
207TEST_F(AssertPass, PtrEq2) { PW_CHECK_PTR_EQ(0xb, 0xb); }
208TEST_F(AssertFail, PtrEq3) { PW_CHECK_PTR_EQ(0xb, 0xa); }
209
210// PTR !=
211TEST_F(AssertPass, PtrNe1) { PW_CHECK_PTR_NE(0xa, 0xb); }
212TEST_F(AssertFail, PtrNe2) { PW_CHECK_PTR_NE(0xb, 0xb); }
213TEST_F(AssertPass, PtrNe3) { PW_CHECK_PTR_NE(0xb, 0xa); }
214
215// PTR >
216TEST_F(AssertFail, PtrGt1) { PW_CHECK_PTR_GT(0xa, 0xb); }
217TEST_F(AssertFail, PtrGt2) { PW_CHECK_PTR_GT(0xb, 0xb); }
218TEST_F(AssertPass, PtrGt3) { PW_CHECK_PTR_GT(0xb, 0xa); }
219
220// PTR >=
221TEST_F(AssertFail, PtrGe1) { PW_CHECK_PTR_GE(0xa, 0xb); }
222TEST_F(AssertPass, PtrGe2) { PW_CHECK_PTR_GE(0xb, 0xb); }
223TEST_F(AssertPass, PtrGe3) { PW_CHECK_PTR_GE(0xb, 0xa); }
224
225// NOTNULL
226TEST_F(AssertPass, PtrNotNull) { PW_CHECK_NOTNULL(0xa); }
227TEST_F(AssertFail, PtrNotNull) { PW_CHECK_NOTNULL(0x0); }
228
Keir Mierlea84fd8d2020-08-07 21:29:26 -0700229// Note: Due to platform inconsistencies, the below test for the NOTNULL
230// message doesn't work. Some platforms print NULL formatted as %p as "(nil)",
231// others "0x0". Leaving this here for reference.
232//
233// TEST_F(AssertFail, PtrNotNullDescription) {
234// intptr_t intptr = 0;
235// PW_CHECK_NOTNULL(intptr);
236// EXPECT_MESSAGE("Check failed: intptr (=0x0) != nullptr (=0x0). ");
237// }
238
Keir Mierle8d2a84f2020-04-14 22:00:00 -0700239// PW_CHECK_FLOAT_*(...)
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700240// Binary checks with floats, comparisons: EXACT_LT, EXACT_LE, NEAR, EXACT_EQ,
241// EXACT_NE, EXACT_GE, EXACT_GT.
Keir Mierle8d2a84f2020-04-14 22:00:00 -0700242
243// Test message formatting separate from the triggering.
244// Only test formatting for the type once.
245TEST_F(AssertFail, FloatLessThanNoMessageNoArguments) {
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700246 PW_CHECK_FLOAT_EXACT_LT(5.2, 2.3);
Keir Mierle8d2a84f2020-04-14 22:00:00 -0700247 EXPECT_MESSAGE("Check failed: 5.2 (=5.200000) < 2.3 (=2.300000). ");
248}
249TEST_F(AssertFail, FloatLessThanMessageNoArguments) {
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700250 PW_CHECK_FLOAT_EXACT_LT(5.2, 2.3, "msg");
Keir Mierle8d2a84f2020-04-14 22:00:00 -0700251 EXPECT_MESSAGE("Check failed: 5.2 (=5.200000) < 2.3 (=2.300000). msg");
252}
253TEST_F(AssertFail, FloatLessThanMessageArguments) {
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700254 PW_CHECK_FLOAT_EXACT_LT(5.2, 2.3, "msg: %d", 6);
Keir Mierle8d2a84f2020-04-14 22:00:00 -0700255 EXPECT_MESSAGE("Check failed: 5.2 (=5.200000) < 2.3 (=2.300000). msg: 6");
256}
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700257// Check float NEAR both above and below the permitted range.
258TEST_F(AssertFail, FloatNearAboveNoMessageNoArguments) {
259 PW_CHECK_FLOAT_NEAR(5.2, 2.3, 0.1);
260 EXPECT_MESSAGE(
261 "Check failed: 5.2 (=5.200000) <= 2.3 + abs_tolerance (=2.400000). ");
262}
263TEST_F(AssertFail, FloatNearAboveMessageNoArguments) {
264 PW_CHECK_FLOAT_NEAR(5.2, 2.3, 0.1, "msg");
265 EXPECT_MESSAGE(
266 "Check failed: 5.2 (=5.200000) <= 2.3 + abs_tolerance (=2.400000). msg");
267}
268TEST_F(AssertFail, FloatNearAboveMessageArguments) {
269 PW_CHECK_FLOAT_NEAR(5.2, 2.3, 0.1, "msg: %d", 6);
270 EXPECT_MESSAGE(
271 "Check failed: 5.2 (=5.200000) <= 2.3 + abs_tolerance (=2.400000). msg: "
272 "6");
273}
274TEST_F(AssertFail, FloatNearBelowNoMessageNoArguments) {
275 PW_CHECK_FLOAT_NEAR(1.2, 2.3, 0.1);
276 EXPECT_MESSAGE(
277 "Check failed: 1.2 (=1.200000) >= 2.3 - abs_tolerance (=2.200000). ");
278}
279TEST_F(AssertFail, FloatNearBelowMessageNoArguments) {
280 PW_CHECK_FLOAT_NEAR(1.2, 2.3, 0.1, "msg");
281 EXPECT_MESSAGE(
282 "Check failed: 1.2 (=1.200000) >= 2.3 - abs_tolerance (=2.200000). msg");
283}
284TEST_F(AssertFail, FloatNearBelowMessageArguments) {
285 PW_CHECK_FLOAT_NEAR(1.2, 2.3, 0.1, "msg: %d", 6);
286 EXPECT_MESSAGE(
287 "Check failed: 1.2 (=1.200000) >= 2.3 - abs_tolerance (=2.200000). msg: "
288 "6");
289}
Keir Mierle8d2a84f2020-04-14 22:00:00 -0700290// Test comparison boundaries.
291// Note: The below example numbers all round to integer 1, to detect accidental
292// integer conversions in the asserts.
293
294// FLOAT <
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700295TEST_F(AssertPass, FloatLt1) { PW_CHECK_FLOAT_EXACT_LT(1.1, 1.2); }
296TEST_F(AssertFail, FloatLt2) { PW_CHECK_FLOAT_EXACT_LT(1.2, 1.2); }
297TEST_F(AssertFail, FloatLt3) { PW_CHECK_FLOAT_EXACT_LT(1.2, 1.1); }
Keir Mierle8d2a84f2020-04-14 22:00:00 -0700298
299// FLOAT <=
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700300TEST_F(AssertPass, FloatLe1) { PW_CHECK_FLOAT_EXACT_LE(1.1, 1.2); }
301TEST_F(AssertPass, FloatLe2) { PW_CHECK_FLOAT_EXACT_LE(1.2, 1.2); }
302TEST_F(AssertFail, FloatLe3) { PW_CHECK_FLOAT_EXACT_LE(1.2, 1.1); }
303
304// FLOAT ~= based on absolute error.
305TEST_F(AssertFail, FloatNearAbs1) { PW_CHECK_FLOAT_NEAR(1.09, 1.2, 0.1); }
306TEST_F(AssertPass, FloatNearAbs2) { PW_CHECK_FLOAT_NEAR(1.1, 1.2, 0.1); }
307TEST_F(AssertPass, FloatNearAbs3) { PW_CHECK_FLOAT_NEAR(1.2, 1.2, 0.1); }
308TEST_F(AssertPass, FloatNearAbs4) { PW_CHECK_FLOAT_NEAR(1.2, 1.1, 0.1); }
309TEST_F(AssertFail, FloatNearAbs5) { PW_CHECK_FLOAT_NEAR(1.21, 1.1, 0.1); }
310// Make sure the abs_tolerance is asserted to be >= 0.
311TEST_F(AssertFail, FloatNearAbs6) { PW_CHECK_FLOAT_NEAR(1.2, 1.2, -0.1); }
312TEST_F(AssertPass, FloatNearAbs7) { PW_CHECK_FLOAT_NEAR(1.2, 1.2, 0.0); }
Keir Mierle8d2a84f2020-04-14 22:00:00 -0700313
314// FLOAT ==
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700315TEST_F(AssertFail, FloatEq1) { PW_CHECK_FLOAT_EXACT_EQ(1.1, 1.2); }
316TEST_F(AssertPass, FloatEq2) { PW_CHECK_FLOAT_EXACT_EQ(1.2, 1.2); }
317TEST_F(AssertFail, FloatEq3) { PW_CHECK_FLOAT_EXACT_EQ(1.2, 1.1); }
Keir Mierle8d2a84f2020-04-14 22:00:00 -0700318
Keir Mierlefa8f89d2020-04-15 16:20:02 -0700319// FLOAT !=
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700320TEST_F(AssertPass, FloatNe1) { PW_CHECK_FLOAT_EXACT_NE(1.1, 1.2); }
321TEST_F(AssertFail, FloatNe2) { PW_CHECK_FLOAT_EXACT_NE(1.2, 1.2); }
322TEST_F(AssertPass, FloatNe3) { PW_CHECK_FLOAT_EXACT_NE(1.2, 1.1); }
Keir Mierlefa8f89d2020-04-15 16:20:02 -0700323
Keir Mierle8d2a84f2020-04-14 22:00:00 -0700324// FLOAT >
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700325TEST_F(AssertFail, FloatGt1) { PW_CHECK_FLOAT_EXACT_GT(1.1, 1.2); }
326TEST_F(AssertFail, FloatGt2) { PW_CHECK_FLOAT_EXACT_GT(1.2, 1.2); }
327TEST_F(AssertPass, FloatGt3) { PW_CHECK_FLOAT_EXACT_GT(1.2, 1.1); }
Keir Mierle8d2a84f2020-04-14 22:00:00 -0700328
329// FLOAT >=
Ewout van Bekkum9e97cfd2020-07-16 13:57:24 -0700330TEST_F(AssertFail, FloatGe1) { PW_CHECK_FLOAT_EXACT_GE(1.1, 1.2); }
331TEST_F(AssertPass, FloatGe2) { PW_CHECK_FLOAT_EXACT_GE(1.2, 1.2); }
332TEST_F(AssertPass, FloatGe3) { PW_CHECK_FLOAT_EXACT_GE(1.2, 1.1); }
Keir Mierle8d2a84f2020-04-14 22:00:00 -0700333
334// Nested comma handling.
335static int Add3(int a, int b, int c) { return a + b + c; }
336
337TEST_F(AssertFail, CommaHandlingLeftSide) {
338 PW_CHECK_INT_EQ(Add3(1, 2, 3), 4);
339 EXPECT_MESSAGE("Check failed: Add3(1, 2, 3) (=6) == 4 (=4). ");
340}
341TEST_F(AssertFail, CommaHandlingRightSide) {
342 PW_CHECK_INT_EQ(4, Add3(1, 2, 3));
343 EXPECT_MESSAGE("Check failed: 4 (=4) == Add3(1, 2, 3) (=6). ");
344}
345
346// Verify that the CHECK_*(x,y) macros only evaluate their arguments once.
347static int global_state_for_multi_evaluate_test;
348static int IncrementsGlobal() {
349 global_state_for_multi_evaluate_test++;
350 return 0;
351}
352
353TEST(AssertPass, CheckSingleSideEffectingCall) {
354 global_state_for_multi_evaluate_test = 0;
355 PW_CHECK(IncrementsGlobal() == 0);
356 EXPECT_EQ(global_state_for_multi_evaluate_test, 1);
357}
358TEST(AssertFail, CheckSingleSideEffectingCall) {
359 global_state_for_multi_evaluate_test = 0;
360 PW_CHECK(IncrementsGlobal() == 1);
361 EXPECT_EQ(global_state_for_multi_evaluate_test, 1);
362}
363TEST(AssertPass, BinaryOpSingleSideEffectingCall) {
364 global_state_for_multi_evaluate_test = 0;
365 PW_CHECK_INT_EQ(0, IncrementsGlobal());
366 EXPECT_EQ(global_state_for_multi_evaluate_test, 1);
367}
368TEST(AssertPass, BinaryOpTwoSideEffectingCalls) {
369 global_state_for_multi_evaluate_test = 0;
370 PW_CHECK_INT_EQ(IncrementsGlobal(), IncrementsGlobal());
371 EXPECT_EQ(global_state_for_multi_evaluate_test, 2);
372}
373TEST(AssertFail, BinaryOpSingleSideEffectingCall) {
374 global_state_for_multi_evaluate_test = 0;
375 PW_CHECK_INT_EQ(12314, IncrementsGlobal());
376 EXPECT_EQ(global_state_for_multi_evaluate_test, 1);
377}
378TEST(AssertFail, BinaryOpTwoSideEffectingCalls) {
379 global_state_for_multi_evaluate_test = 0;
380 PW_CHECK_INT_EQ(IncrementsGlobal() + 10, IncrementsGlobal());
381 EXPECT_EQ(global_state_for_multi_evaluate_test, 2);
382}
383
Keir Mierleb9b88162020-04-15 20:43:09 -0700384// Verify side effects of debug checks work as expected.
385// Only check a couple of cases, since the logic is all the same.
Keir Mierle854adec2020-09-03 14:07:19 -0700386#if PW_ASSERT_ENABLE_DEBUG
Keir Mierleb9b88162020-04-15 20:43:09 -0700387// When DCHECKs are enabled, they behave the same as normal checks.
388TEST(AssertPass, DCheckEnabledSingleSideEffectingCall) {
389 global_state_for_multi_evaluate_test = 0;
390 PW_DCHECK(IncrementsGlobal() == 0);
391 EXPECT_EQ(global_state_for_multi_evaluate_test, 1);
392}
393TEST(AssertFail, DCheckEnabledSingleSideEffectingCall) {
394 global_state_for_multi_evaluate_test = 0;
395 PW_DCHECK(IncrementsGlobal() == 1);
396 EXPECT_EQ(global_state_for_multi_evaluate_test, 1);
397}
398TEST(AssertPass, DCheckEnabledBinaryOpSingleSideEffectingCall) {
399 global_state_for_multi_evaluate_test = 0;
400 PW_DCHECK_INT_EQ(0, IncrementsGlobal());
401 EXPECT_EQ(global_state_for_multi_evaluate_test, 1);
402}
403TEST(AssertPass, DCheckEnabledBinaryOpTwoSideEffectingCalls) {
404 global_state_for_multi_evaluate_test = 0;
405 PW_DCHECK_INT_EQ(IncrementsGlobal(), IncrementsGlobal());
406 EXPECT_EQ(global_state_for_multi_evaluate_test, 2);
407}
408TEST(AssertFail, DCheckEnabledBinaryOpSingleSideEffectingCall) {
409 global_state_for_multi_evaluate_test = 0;
410 PW_DCHECK_INT_EQ(12314, IncrementsGlobal());
411 EXPECT_EQ(global_state_for_multi_evaluate_test, 1);
412}
413TEST(AssertFail, DCheckEnabledBinaryOpTwoSideEffectingCalls) {
414 global_state_for_multi_evaluate_test = 0;
415 PW_DCHECK_INT_EQ(IncrementsGlobal() + 10, IncrementsGlobal());
416 EXPECT_EQ(global_state_for_multi_evaluate_test, 2);
417}
418
Keir Mierle854adec2020-09-03 14:07:19 -0700419#else // PW_ASSERT_ENABLE_DEBUG
Keir Mierleb9b88162020-04-15 20:43:09 -0700420
421// When DCHECKs are disabled, they should not trip, and their arguments
422// shouldn't be evaluated.
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700423TEST(AssertPass, DCheckDisabledSingleSideEffectingCall_1) {
Keir Mierleb9b88162020-04-15 20:43:09 -0700424 global_state_for_multi_evaluate_test = 0;
425 PW_DCHECK(IncrementsGlobal() == 0);
426 EXPECT_EQ(global_state_for_multi_evaluate_test, 0);
427}
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700428TEST(AssertPass, DCheckDisabledSingleSideEffectingCall_2) {
Keir Mierleb9b88162020-04-15 20:43:09 -0700429 global_state_for_multi_evaluate_test = 0;
430 PW_DCHECK(IncrementsGlobal() == 1);
431 EXPECT_EQ(global_state_for_multi_evaluate_test, 0);
432}
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700433TEST(AssertPass, DCheckDisabledBinaryOpSingleSideEffectingCall_1) {
Keir Mierleb9b88162020-04-15 20:43:09 -0700434 global_state_for_multi_evaluate_test = 0;
435 PW_DCHECK_INT_EQ(0, IncrementsGlobal());
436 EXPECT_EQ(global_state_for_multi_evaluate_test, 0);
437}
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700438TEST(AssertPass, DCheckDisabledBinaryOpTwoSideEffectingCalls_1) {
Keir Mierleb9b88162020-04-15 20:43:09 -0700439 global_state_for_multi_evaluate_test = 0;
440 PW_DCHECK_INT_EQ(IncrementsGlobal(), IncrementsGlobal());
441 EXPECT_EQ(global_state_for_multi_evaluate_test, 0);
442}
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700443TEST(AssertPass, DCheckDisabledBinaryOpSingleSideEffectingCall_2) {
Keir Mierleb9b88162020-04-15 20:43:09 -0700444 global_state_for_multi_evaluate_test = 0;
445 PW_DCHECK_INT_EQ(12314, IncrementsGlobal());
446 EXPECT_EQ(global_state_for_multi_evaluate_test, 0);
447}
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700448TEST(AssertPass, DCheckDisabledBinaryOpTwoSideEffectingCalls_2) {
Keir Mierleb9b88162020-04-15 20:43:09 -0700449 global_state_for_multi_evaluate_test = 0;
450 PW_DCHECK_INT_EQ(IncrementsGlobal() + 10, IncrementsGlobal());
451 EXPECT_EQ(global_state_for_multi_evaluate_test, 0);
452}
Keir Mierle854adec2020-09-03 14:07:19 -0700453#endif // PW_ASSERT_ENABLE_DEBUG
Keir Mierleb9b88162020-04-15 20:43:09 -0700454
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700455// Verify PW_CHECK_OK, including message handling.
456TEST_F(AssertFail, StatusNotOK) {
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700457 pw::Status status = pw::Status::Unknown();
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700458 PW_CHECK_OK(status);
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800459 EXPECT_MESSAGE("Check failed: status (=UNKNOWN) == OkStatus() (=OK). ");
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700460}
461
462TEST_F(AssertFail, StatusNotOKMessageNoArguments) {
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700463 pw::Status status = pw::Status::Unknown();
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700464 PW_CHECK_OK(status, "msg");
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800465 EXPECT_MESSAGE("Check failed: status (=UNKNOWN) == OkStatus() (=OK). msg");
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700466}
467
468TEST_F(AssertFail, StatusNotOKMessageArguments) {
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700469 pw::Status status = pw::Status::Unknown();
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700470 PW_CHECK_OK(status, "msg: %d", 5);
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800471 EXPECT_MESSAGE("Check failed: status (=UNKNOWN) == OkStatus() (=OK). msg: 5");
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700472}
473
474// Example expression for the test below.
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700475pw::Status DoTheThing() { return pw::Status::ResourceExhausted(); }
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700476
477TEST_F(AssertFail, NonTrivialExpression) {
478 PW_CHECK_OK(DoTheThing());
479 EXPECT_MESSAGE(
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800480 "Check failed: DoTheThing() (=RESOURCE_EXHAUSTED) == OkStatus() (=OK). ");
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700481}
482
483// Note: This function seems pointless but it is not, since pw::Status::FOO
484// constants are not actually status objects, but code objects. This way we can
485// ensure the macros work with both real status objects and literals.
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800486TEST_F(AssertPass, Function) { PW_CHECK_OK(pw::OkStatus()); }
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700487TEST_F(AssertPass, Enum) { PW_CHECK_OK(PW_STATUS_OK); }
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700488TEST_F(AssertFail, Function) { PW_CHECK_OK(pw::Status::Unknown()); }
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700489TEST_F(AssertFail, Enum) { PW_CHECK_OK(PW_STATUS_UNKNOWN); }
490
Keir Mierle854adec2020-09-03 14:07:19 -0700491#if PW_ASSERT_ENABLE_DEBUG
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700492
493// In debug mode, the asserts should check their arguments.
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800494TEST_F(AssertPass, DCheckFunction) { PW_DCHECK_OK(pw::OkStatus()); }
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700495TEST_F(AssertPass, DCheckEnum) { PW_DCHECK_OK(PW_STATUS_OK); }
496TEST_F(AssertFail, DCheckFunction) { PW_DCHECK_OK(pw::Status::Unknown()); }
497TEST_F(AssertFail, DCheckEnum) { PW_DCHECK_OK(PW_STATUS_UNKNOWN); }
Keir Mierle854adec2020-09-03 14:07:19 -0700498#else // PW_ASSERT_ENABLE_DEBUG
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700499
500// In release mode, all the asserts should pass.
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800501TEST_F(AssertPass, DCheckFunction_Ok) { PW_DCHECK_OK(pw::OkStatus()); }
Wyatt Heplerd78f7c62020-09-28 14:27:32 -0700502TEST_F(AssertPass, DCheckEnum_Ok) { PW_DCHECK_OK(PW_STATUS_OK); }
503TEST_F(AssertPass, DCheckFunction_Err) { PW_DCHECK_OK(pw::Status::Unknown()); }
504TEST_F(AssertPass, DCheckEnum_Err) { PW_DCHECK_OK(PW_STATUS_UNKNOWN); }
Keir Mierle854adec2020-09-03 14:07:19 -0700505#endif // PW_ASSERT_ENABLE_DEBUG
Keir Mierle0fa7f7d2020-05-07 12:34:00 -0700506
Keir Mierle8d2a84f2020-04-14 22:00:00 -0700507// TODO: Figure out how to run some of these tests is C.
508
509} // namespace