xref: /aosp_15_r20/external/pigweed/pw_unit_test/framework_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2019 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 #include "pw_unit_test/framework.h"
16 
17 #include <cstring>
18 
19 #include "pw_assert/check.h"
20 #include "pw_result/result.h"
21 #include "pw_status/status.h"
22 #include "pw_status/status_with_size.h"
23 
24 namespace pw {
25 namespace {
26 
TEST(PigweedTest,ExpectBool)27 TEST(PigweedTest, ExpectBool) {
28   EXPECT_TRUE(true);
29   EXPECT_FALSE(false);
30 
31   EXPECT_TRUE(1);
32   EXPECT_TRUE(1203492);
33   EXPECT_TRUE(-1);
34   EXPECT_TRUE(0.1f);
35 
36   EXPECT_FALSE(0);
37   EXPECT_FALSE(0.0f);
38   EXPECT_FALSE(-0.0f);
39 }
40 
TEST(PigweedTest,ExpectBasicComparisons)41 TEST(PigweedTest, ExpectBasicComparisons) {
42   EXPECT_EQ(1, 1 + 0);
43   ASSERT_EQ(1, 1 + 0);
44 
45   EXPECT_EQ(0.0f, -0.0f);
46   ASSERT_EQ(0.0f, -0.0f);
47 
48   EXPECT_NE(-1, 0);
49   ASSERT_NE(-1, 0);
50 
51   EXPECT_GT(2, 1);
52   ASSERT_GT(3, 0);
53 
54   EXPECT_GE(1, 1);
55   ASSERT_GE(3, 0);
56 
57   EXPECT_LT(0, 1);
58   ASSERT_LT(-2, 1209);
59 
60   EXPECT_LE(-1, 0);
61   ASSERT_LE(-2, -2);
62 }
63 
TEST(PigweedTest,ExpectNearComparisons)64 TEST(PigweedTest, ExpectNearComparisons) {
65   EXPECT_NEAR(1, 2, 1);
66   ASSERT_NEAR(1, 2, 1);
67 
68   EXPECT_NEAR(-5, 5, 10);
69   ASSERT_NEAR(-5, 5, 10);
70 
71   int x = 17;
72   int epsilon = 5;
73 
74   EXPECT_NEAR(x, 15, epsilon);
75   ASSERT_NEAR(x, 15, epsilon);
76 }
77 
TEST(PigweedTest,ExpectFloatComparisons)78 TEST(PigweedTest, ExpectFloatComparisons) {
79   EXPECT_FLOAT_EQ(5.0f, 10.0f / 2);
80   ASSERT_FLOAT_EQ(5.0f, 10.0f / 2);
81 
82   EXPECT_FLOAT_EQ(-0.5f, -5.0f / 10);
83   ASSERT_FLOAT_EQ(-0.5f, -5.0f / 10);
84 
85   float x = 17.0f / 20.0f;
86 
87   EXPECT_FLOAT_EQ(x, 17.0f / 20.0f);
88   ASSERT_FLOAT_EQ(x, 17.0f / 20.0f);
89 }
90 
TEST(PigweedTest,ExpectDoubleComparisons)91 TEST(PigweedTest, ExpectDoubleComparisons) {
92   EXPECT_DOUBLE_EQ(5.0, 10.0 / 2);
93   ASSERT_DOUBLE_EQ(5.0, 10.0 / 2);
94 
95   EXPECT_DOUBLE_EQ(-0.5, -5.0 / 10);
96   ASSERT_DOUBLE_EQ(-0.5, -5.0 / 10);
97 
98   double x = 17.0 / 20.0;
99 
100   EXPECT_DOUBLE_EQ(x, 17.0 / 20.0);
101   ASSERT_DOUBLE_EQ(x, 17.0 / 20.0);
102 }
103 
TEST(PigweedTest,ExpectStringEquality)104 TEST(PigweedTest, ExpectStringEquality) {
105   EXPECT_STREQ("", "");
106   EXPECT_STREQ("Yes", "Yes");
107 
108   char no[] = {'N', 'o', '\0'};
109   ASSERT_STREQ("No", no);
110 
111   EXPECT_STRNE("NO", "no");
112   ASSERT_STRNE("yes", no);
113 
114   const char* invalid_string = nullptr;
115   EXPECT_STREQ(invalid_string, nullptr);
116   EXPECT_STRNE("abc", nullptr);
117 }
118 
TEST(PigweedTest,SucceedAndFailMacros)119 TEST(PigweedTest, SucceedAndFailMacros) {
120   SUCCEED();
121 
122   // The ADD_FAILURE() and FAIL() macros cause a test to fail if they are
123   // reached. Use them, but don't let them run so that this test still passes.
124   if (false) {
125     ADD_FAILURE();
126     FAIL();
127   }
128 
129   // Without braces, clang-tidy complains if these are multiple statements.
130   if (false)
131     ADD_FAILURE();
132 
133   if (false)
134     FAIL();
135 }
136 
TEST(PigweedTest,SkipMacro)137 TEST(PigweedTest, SkipMacro) {
138   // Without a brace, clang-tidy complains if GTEST_SKIP is multiple statements.
139   if (false)
140     GTEST_SKIP();
141 
142   GTEST_SKIP();
143   // This code should not run.
144   EXPECT_TRUE(false);
145 }
146 
TEST(PigweedTest,Logs)147 TEST(PigweedTest, Logs) {
148   EXPECT_TRUE(true) << "This message is ignored";
149   EXPECT_FALSE(false) << "This message is ignored";
150   EXPECT_EQ(0, 0) << "This message is ignored";
151   EXPECT_NE(0, 1) << "This message is ignored";
152   EXPECT_GT(1, 0) << "This message is ignored";
153   EXPECT_GE(0, 0) << "This message is ignored";
154   EXPECT_LT(0, 1) << "This message is ignored";
155   EXPECT_LE(0, 0) << "This message is ignored";
156   EXPECT_STREQ("", "") << "This message is ignored";
157   EXPECT_STRNE("", "?") << "This message is ignored";
158 
159   ASSERT_TRUE(true) << "This message is ignored";
160   ASSERT_FALSE(false) << "This message is ignored";
161   ASSERT_EQ(0, 0) << "This message is ignored";
162   ASSERT_NE(0, 1) << "This message is ignored";
163   ASSERT_GT(1, 0) << "This message is ignored";
164   ASSERT_GE(0, 0) << "This message is ignored";
165   ASSERT_LT(0, 1) << "This message is ignored";
166   ASSERT_LE(0, 0) << "This message is ignored";
167   ASSERT_STREQ("", "") << "This message is ignored";
168   ASSERT_STRNE("", "?") << "This message is ignored";
169 
170   if (false) {
171     ADD_FAILURE() << "This failed!" << 123;
172     GTEST_FAIL() << "This failed!" << 123 << '?';
173     GTEST_SKIP() << 1.0f << " skips!";
174   }
175   GTEST_SUCCEED() << "This message is ignored";
176 }
177 
TEST(PigweedTest,PwOkMatchers)178 TEST(PigweedTest, PwOkMatchers) {
179   PW_TEST_ASSERT_OK(OkStatus());
180   PW_TEST_ASSERT_OK(StatusWithSize(123));
181   PW_TEST_ASSERT_OK(Result<int>(123));
182 
183   PW_TEST_EXPECT_OK(OkStatus());
184   PW_TEST_EXPECT_OK(StatusWithSize(123));
185   PW_TEST_EXPECT_OK(Result<int>(123));
186 
187   PW_TEST_ASSERT_OK_AND_ASSIGN(auto val, Result<int>(123));
188   EXPECT_EQ(val, 123);
189   PW_TEST_ASSERT_OK_AND_ASSIGN(auto size, StatusWithSize(123U));
190   EXPECT_EQ(size, 123U);
191 }
192 
TEST(AssertOkAndAssign,AssignsOkValueToNewLvalue)193 TEST(AssertOkAndAssign, AssignsOkValueToNewLvalue) {
194   const auto value = Result<int>(5);
195   PW_TEST_ASSERT_OK_AND_ASSIGN(int declare_and_assign, value);
196   EXPECT_EQ(5, declare_and_assign);
197 }
198 
TEST(AssertOkAndAssign,AssignsOkValueToExistingLvalue)199 TEST(AssertOkAndAssign, AssignsOkValueToExistingLvalue) {
200   const auto value = Result<int>(5);
201   int existing_value = 0;
202   PW_TEST_ASSERT_OK_AND_ASSIGN(existing_value, value);
203   EXPECT_EQ(5, existing_value);
204 }
205 
TEST(AssertOkAndAssign,AssignsExistingLvalueToConstReference)206 TEST(AssertOkAndAssign, AssignsExistingLvalueToConstReference) {
207   const auto value = Result<int>(5);
208   PW_TEST_ASSERT_OK_AND_ASSIGN(const auto& ref, value);
209   EXPECT_EQ(5, ref);
210 }
211 
212 class CopyMoveCounter {
213  public:
214   CopyMoveCounter() = delete;
CopyMoveCounter(int & copies,int & moves)215   CopyMoveCounter(int& copies, int& moves) : copies_(&copies), moves_(&moves) {}
CopyMoveCounter(const CopyMoveCounter & other)216   CopyMoveCounter(const CopyMoveCounter& other)
217       : copies_(other.copies_), moves_(other.moves_) {
218     ++(*copies_);
219   }
CopyMoveCounter(CopyMoveCounter && other)220   CopyMoveCounter(CopyMoveCounter&& other)
221       : copies_(other.copies_), moves_(other.moves_) {
222     ++(*moves_);
223   }
operator =(const CopyMoveCounter & other)224   CopyMoveCounter& operator=(const CopyMoveCounter& other) {
225     copies_ = other.copies_;
226     moves_ = other.moves_;
227     ++(*copies_);
228     return *this;
229   }
operator =(CopyMoveCounter && other)230   CopyMoveCounter& operator=(CopyMoveCounter&& other) {
231     copies_ = other.copies_;
232     moves_ = other.moves_;
233     ++(*moves_);
234     return *this;
235   }
236 
237  private:
238   int* copies_;
239   int* moves_;
240 };
241 
TEST(AssertOkAndAssign,OkRvalueDoesNotCopy)242 TEST(AssertOkAndAssign, OkRvalueDoesNotCopy) {
243   int copies = 0;
244   int moves = 0;
245   PW_TEST_ASSERT_OK_AND_ASSIGN([[maybe_unused]] CopyMoveCounter cm,
246                                Result(CopyMoveCounter(copies, moves)));
247   EXPECT_EQ(copies, 0);
248   EXPECT_EQ(moves, 2);
249 }
250 
TEST(AssertOkAndAssign,OkLvalueMovedDoesNotCopy)251 TEST(AssertOkAndAssign, OkLvalueMovedDoesNotCopy) {
252   int copies = 0;
253   int moves = 0;
254   Result result(CopyMoveCounter(copies, moves));
255   PW_TEST_ASSERT_OK_AND_ASSIGN([[maybe_unused]] CopyMoveCounter cm,
256                                std::move(result));
257   EXPECT_EQ(copies, 0);
258   EXPECT_EQ(moves, 3);
259 }
260 
TEST(AssertOkAndAssign,OkLvalueCopiesOnce)261 TEST(AssertOkAndAssign, OkLvalueCopiesOnce) {
262   int copies = 0;
263   int moves = 0;
264   Result result(CopyMoveCounter(copies, moves));
265   PW_TEST_ASSERT_OK_AND_ASSIGN([[maybe_unused]] CopyMoveCounter cm, result);
266   EXPECT_EQ(copies, 1);
267   EXPECT_EQ(moves, 2);
268 }
269 
270 // The following test contents are disabled and is only for checking what
271 // failure cases would look like. For example, when enabling the test,
272 // the output is:
273 // clang-format off
274 // ERR  pw_unit_test/framework_test.cc:294: Failure
275 // ERR        Expected: ::pw::internal::ConvertToStatus(Status::Unknown()) == pw::OkStatus()
276 // ERR          Actual: UNKNOWN == OK
277 // ERR  pw_unit_test/framework_test.cc:295: Failure
278 // ERR        Expected: ::pw::internal::ConvertToStatus(Status::Unknown()) == pw::OkStatus()
279 // ERR          Actual: UNKNOWN == OK
280 // clang-format on
TEST(TestMatchers,SampleFailures)281 TEST(TestMatchers, SampleFailures) {
282   if (false) {
283     PW_TEST_EXPECT_OK(Status::Unknown());
284     PW_TEST_ASSERT_OK(Status::Unknown());
285   }
286 }
287 
288 class SkipOnSetUpTest : public ::testing::Test {
289  public:
SetUp()290   void SetUp() override { GTEST_SKIP(); }
291 };
292 
TEST_F(SkipOnSetUpTest,FailTest)293 TEST_F(SkipOnSetUpTest, FailTest) {
294   // This code should not run because the test was skipped in SetUp().
295   EXPECT_TRUE(false);
296 }
297 
298 class NonCopyable {
299  public:
NonCopyable(int value)300   NonCopyable(int value) : value_(value) {}
301 
302   NonCopyable(const NonCopyable&) = delete;
303   NonCopyable& operator=(const NonCopyable&) = delete;
304 
operator ==(const NonCopyable & rhs) const305   bool operator==(const NonCopyable& rhs) const { return value_ == rhs.value_; }
operator !=(const NonCopyable & rhs) const306   bool operator!=(const NonCopyable& rhs) const { return value_ != rhs.value_; }
307 
operator bool() const308   operator bool() const { return value_ > 0; }
309 
310  private:
311   const int value_;
312 };
313 
TEST(PigweedTest,NonCopyableType)314 TEST(PigweedTest, NonCopyableType) {
315   EXPECT_TRUE(NonCopyable(6));
316   EXPECT_FALSE(NonCopyable(-1));
317 
318   const NonCopyable this_one(100);
319   EXPECT_EQ(this_one, this_one);
320   EXPECT_TRUE(this_one);
321 
322   EXPECT_EQ(NonCopyable(5), NonCopyable(5));
323   EXPECT_NE(NonCopyable(5), NonCopyable(6));
324 }
325 
Increment(int * i)326 bool Increment(int* i) {
327   (*i)++;
328   return true;
329 }
330 
TEST(PigweedTest,MacroArgumentsOnlyAreEvaluatedOnce)331 TEST(PigweedTest, MacroArgumentsOnlyAreEvaluatedOnce) {
332   int i = 1;
333 
334   EXPECT_TRUE(Increment(&i));
335   EXPECT_EQ(i, 2);
336   ASSERT_TRUE(Increment(&i));
337   EXPECT_EQ(i, 3);
338 
339   EXPECT_EQ(0x600dbeef, [&i]() {
340     i += 1;
341     return 0x600dbeef;
342   }());
343 
344   EXPECT_EQ(i, 4);
345 }
346 
347 class ClassWithPrivateMethod {
348   FRIEND_TEST(FixtureTest, FriendClass);
349 
350  private:
Return314()351   int Return314() { return 314; }
352 };
353 
354 class FixtureTest : public ::testing::Test {
355  public:
FixtureTest()356   FixtureTest() : string_("hello world") {}
357 
ReturnTrue()358   bool ReturnTrue() { return true; }
StringLength()359   int StringLength() { return std::strlen(string_); }
360 
361  protected:
362   const char* string_;
363 };
364 
TEST_F(FixtureTest,CustomFixture)365 TEST_F(FixtureTest, CustomFixture) {
366   EXPECT_TRUE(ReturnTrue());
367   EXPECT_EQ(StringLength(), 11);
368 }
369 
TEST_F(FixtureTest,FriendClass)370 TEST_F(FixtureTest, FriendClass) {
371   EXPECT_EQ(ClassWithPrivateMethod().Return314(), 314);
372 }
373 
374 class PigweedTestFixture : public ::testing::Test {
375  protected:
PigweedTestFixture()376   PigweedTestFixture() : cool_number_(35) {}
377 
378   int cool_number_;
379 };
380 
TEST_F(PigweedTestFixture,TheNumberIs35)381 TEST_F(PigweedTestFixture, TheNumberIs35) {
382   EXPECT_EQ(cool_number_, 35);
383   cool_number_ += 1;
384   EXPECT_EQ(cool_number_, 36);
385 }
386 
TEST_F(PigweedTestFixture,YupTheNumberIs35)387 TEST_F(PigweedTestFixture, YupTheNumberIs35) {
388   EXPECT_EQ(cool_number_, 35);
389   cool_number_ *= 100;
390   EXPECT_EQ(cool_number_, 3500);
391 }
392 
393 class Expectations : public ::testing::Test {
394  protected:
Expectations()395   Expectations() : cool_number_(3) { PW_CHECK_INT_EQ(cool_number_, 3); }
396 
~Expectations()397   ~Expectations() override { PW_CHECK_INT_EQ(cool_number_, 14159); }
398 
399   int cool_number_;
400 };
401 
TEST_F(Expectations,SetCoolNumber)402 TEST_F(Expectations, SetCoolNumber) { cool_number_ = 14159; }
403 
404 class SetUpAndTearDown : public ::testing::Test {
405  public:
406   static int value;
407 
SetUpTestSuite()408   static void SetUpTestSuite() {
409     value = 1;
410     EXPECT_EQ(value, 1);
411     value++;
412   }
413 
TearDownTestSuite()414   static void TearDownTestSuite() {
415     EXPECT_EQ(value, 7);
416     value++;
417   }
418 
419  protected:
SetUpAndTearDown()420   SetUpAndTearDown() {
421     EXPECT_EQ(value, 2);
422     value++;
423   }
424 
~SetUpAndTearDown()425   ~SetUpAndTearDown() override {
426     EXPECT_EQ(value, 6);
427     value++;
428   }
429 
SetUp()430   void SetUp() override {
431     EXPECT_EQ(value, 3);
432     value++;
433   }
434 
TearDown()435   void TearDown() override {
436     EXPECT_EQ(value, 5);
437     value++;
438   }
439 };
440 
441 int SetUpAndTearDown::value = 1;
442 
TEST_F(SetUpAndTearDown,MakeSureItIsSet)443 TEST_F(SetUpAndTearDown, MakeSureItIsSet) {
444   EXPECT_EQ(value, 4);
445   value++;
446 }
447 
TEST(TestSuiteTearDown,MakeSureItRan)448 TEST(TestSuiteTearDown, MakeSureItRan) {
449   EXPECT_EQ(SetUpAndTearDown::value, 8);
450 }
451 
452 class Interleaved : public ::testing::Test {
453  public:
SetUpTestSuite()454   static void SetUpTestSuite() { suites_running++; }
TearDownTestSuite()455   static void TearDownTestSuite() { suites_running--; }
456 
457  protected:
458   static int suites_running;
459 };
460 
461 int Interleaved::suites_running = 0;
462 
463 class InterleavedA : public Interleaved {};
464 class InterleavedB : public Interleaved {};
465 
TEST_F(InterleavedA,Test1)466 TEST_F(InterleavedA, Test1) { ASSERT_EQ(suites_running, 1); }
TEST_F(InterleavedB,Test1)467 TEST_F(InterleavedB, Test1) { ASSERT_EQ(suites_running, 1); }
TEST_F(Interleaved,Test12)468 TEST_F(Interleaved, Test12) { ASSERT_EQ(suites_running, 1); }
TEST_F(InterleavedB,Test2)469 TEST_F(InterleavedB, Test2) { ASSERT_EQ(suites_running, 1); }
TEST_F(InterleavedA,Test2)470 TEST_F(InterleavedA, Test2) { ASSERT_EQ(suites_running, 1); }
471 
472 }  // namespace
473 }  // namespace pw
474