C/C++ API Reference
Loading...
Searching...
No Matches
framework_backend.h
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#pragma once
15
16// IWYU pragma: private, include "pw_unit_test/framework.h"
17
18#if defined(GTEST_TEST)
19#error \
20 "GTEST_TEST is already defined. Make sure googletest headers are not " \
21 "included when using the pw_unit_test light backend."
22#endif // GTEST_TEST
23
24#include <cmath>
25#include <cstddef>
26#include <cstdint>
27#include <cstring>
28#include <new>
29#include <string_view>
30
31#include "pw_bytes/alignment.h"
32#include "pw_polyfill/standard.h"
33#include "pw_preprocessor/compiler.h"
34#include "pw_preprocessor/util.h"
35#include "pw_span/span.h"
36#include "pw_status/status.h"
37#include "pw_string/string_builder.h"
38#include "pw_unit_test/config.h"
39#include "pw_unit_test/event_handler.h"
40
42
45#define GTEST_TEST(test_suite_name, test_name) \
46 _PW_TEST_SUITE_NAMES_MUST_BE_UNIQUE(void /* TEST */, test_suite_name); \
47 _PW_TEST(test_suite_name, test_name, ::pw::unit_test::internal::Test)
48
58#if !(defined(GTEST_DONT_DEFINE_TEST) && GTEST_DONT_DEFINE_TEST)
59#define TEST(test_suite_name, test_name) GTEST_TEST(test_suite_name, test_name)
60#endif // !GTEST_DONT_DEFINE_TEST
61
72#define TEST_F(test_fixture, test_name) \
73 _PW_TEST_SUITE_NAMES_MUST_BE_UNIQUE(int /* TEST_F */, test_fixture); \
74 _PW_TEST(test_fixture, test_name, test_fixture)
75
85#define FRIEND_TEST(test_suite_name, test_name) \
86 friend class test_suite_name##_##test_name##_Test
87
89
91
96#define EXPECT_TRUE(expr) _PW_TEST_EXPECT(_PW_TEST_BOOL(expr, true))
97
102#define EXPECT_FALSE(expr) _PW_TEST_EXPECT(_PW_TEST_BOOL(expr, false))
103
117#define EXPECT_EQ(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, ==))
118
128
131#define EXPECT_NE(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, !=))
132
138#define EXPECT_GT(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, >))
139
145#define EXPECT_GE(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, >=))
146
152#define EXPECT_LT(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, <))
153
159#define EXPECT_LE(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, <=))
160
168#define EXPECT_NEAR(lhs, rhs, epsilon) \
169 _PW_TEST_EXPECT(_PW_TEST_NEAR(lhs, rhs, epsilon))
170
177#define EXPECT_FLOAT_EQ(lhs, rhs) \
178 _PW_TEST_EXPECT( \
179 _PW_TEST_NEAR(lhs, rhs, 4 * std::numeric_limits<float>::epsilon()))
180
187#define EXPECT_DOUBLE_EQ(lhs, rhs) \
188 _PW_TEST_EXPECT( \
189 _PW_TEST_NEAR(lhs, rhs, 4 * std::numeric_limits<double>::epsilon()))
190
196#define EXPECT_STREQ(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_C_STR(lhs, rhs, ==))
197
203#define EXPECT_STRNE(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_C_STR(lhs, rhs, !=))
204
206
208
211#define ASSERT_TRUE(expr) _PW_TEST_ASSERT(_PW_TEST_BOOL(expr, true))
212
215#define ASSERT_FALSE(expr) _PW_TEST_ASSERT(_PW_TEST_BOOL(expr, false))
216
219#define ASSERT_EQ(lhs, rhs) _PW_TEST_ASSERT(_PW_TEST_OP(lhs, rhs, ==))
220
223#define ASSERT_NE(lhs, rhs) _PW_TEST_ASSERT(_PW_TEST_OP(lhs, rhs, !=))
224
227#define ASSERT_GT(lhs, rhs) _PW_TEST_ASSERT(_PW_TEST_OP(lhs, rhs, >))
228
231#define ASSERT_GE(lhs, rhs) _PW_TEST_ASSERT(_PW_TEST_OP(lhs, rhs, >=))
232
235#define ASSERT_LT(lhs, rhs) _PW_TEST_ASSERT(_PW_TEST_OP(lhs, rhs, <))
236
239#define ASSERT_LE(lhs, rhs) _PW_TEST_ASSERT(_PW_TEST_OP(lhs, rhs, <=))
240
243#define ASSERT_NEAR(lhs, rhs, epsilon) \
244 _PW_TEST_ASSERT(_PW_TEST_NEAR(lhs, rhs, epsilon))
245
248#define ASSERT_FLOAT_EQ(lhs, rhs) \
249 _PW_TEST_ASSERT( \
250 _PW_TEST_NEAR(lhs, rhs, 4 * std::numeric_limits<float>::epsilon()))
251
254#define ASSERT_DOUBLE_EQ(lhs, rhs) \
255 _PW_TEST_ASSERT( \
256 _PW_TEST_NEAR(lhs, rhs, 4 * std::numeric_limits<double>::epsilon()))
257
260#define ASSERT_STREQ(lhs, rhs) _PW_TEST_ASSERT(_PW_TEST_C_STR(lhs, rhs, ==))
261
264#define ASSERT_STRNE(lhs, rhs) _PW_TEST_ASSERT(_PW_TEST_C_STR(lhs, rhs, !=))
265
267
269
272#define ADD_FAILURE() \
273 ::pw::unit_test::internal::ReturnHelper() = \
274 ::pw::unit_test::internal::Framework::Get().CurrentTestExpectSimple( \
275 "(line is not executed)", \
276 "(line was executed)", \
277 __FILE__, \
278 __LINE__, \
279 false)
280
284#define GTEST_FAIL() return ADD_FAILURE()
285
289#define GTEST_SKIP() \
290 return ::pw::unit_test::internal::ReturnHelper() = \
291 ::pw::unit_test::internal::Framework::Get().CurrentTestSkip( \
292 __FILE__, __LINE__)
293
299#if !(defined(GTEST_DONT_DEFINE_FAIL) && GTEST_DONT_DEFINE_FAIL)
300#define FAIL() GTEST_FAIL()
301#endif // !GTEST_DONT_DEFINE_FAIL
302
306#define GTEST_SUCCEED() \
307 ::pw::unit_test::internal::Framework::Get().CurrentTestExpectSimple( \
308 "(success)", "(success)", __FILE__, __LINE__, true)
309
316#if !(defined(GTEST_DONT_DEFINE_SUCCEED) && GTEST_DONT_DEFINE_SUCCEED)
317#define SUCCEED() GTEST_SUCCEED()
318#endif // !GTEST_DONT_DEFINE_SUCCEED
319
322// TODO: https://pwbug.dev/441096262 - Add SCOPED_TRACE support.
323#define SCOPED_TRACE(message)
324
332int RUN_ALL_TESTS();
333
336#define GTEST_HAS_DEATH_TEST 0
337
340#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
341 if (0) { \
342 static_cast<void>(statement); \
343 static_cast<void>(regex); \
344 } \
345 static_assert(true, "Macros must be terminated with a semicolon")
346
349#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
350 EXPECT_DEATH_IF_SUPPORTED(statement, regex)
351
353
354namespace pw {
355namespace string {
356
358
359// This function is used to print unknown types that are used in EXPECT or
360// ASSERT statements in tests.
361//
362// You can add support for displaying custom types by defining a ToString
363// template specialization. For example:
364//
365// namespace pw {
366//
367// template <>
368// StatusWithSize ToString<MyType>(const MyType& value,
369// span<char> buffer) {
370// return string::Format("<MyType|%d>", value.id);
371// }
372//
373// } // namespace pw
374//
375// See the documentation in pw_string/string_builder.h for more information.
376template <typename T>
377StatusWithSize UnknownTypeToString(const T& value, span<char> buffer) {
378 StringBuilder sb(buffer);
379 sb << '<' << sizeof(value) << "-byte object at 0x" << &value;
380
381 // How many bytes of the object to print.
382 //
383 // WARNING: Printing the contents of an object may be undefined behavior!
384 // Accessing uninitialized memory is undefined behavior, and objects
385 // sometimes contain uninitialized regions, such as padding bytes or
386 // unallocated storage (e.g. std::optional). kPrintMaybeUninitializedBytes
387 // MUST stay at 0, except when changed locally to help with debugging.
388 constexpr size_t kPrintMaybeUnintializedBytes = 0;
389
390 constexpr size_t kBytesToPrint =
391 std::min(sizeof(value), kPrintMaybeUnintializedBytes);
392
393 if (kBytesToPrint != 0u) {
394 sb << " |";
395
396 // reinterpret_cast to std::byte is permitted by C++'s type aliasing
397 // rules.
398 const std::byte* bytes = reinterpret_cast<const std::byte*>(&value);
399
400 for (size_t i = 0; i < kBytesToPrint; ++i) {
401 sb << ' ' << bytes[i];
402 }
403
404 // If there's just one more byte, output it. Otherwise, output ellipsis.
405 if (sizeof(value) == kBytesToPrint + 1) {
406 sb << ' ' << bytes[sizeof(value) - 1];
407 } else if (sizeof(value) > kBytesToPrint) {
408 sb << " …";
409 }
410 }
411
412 sb << '>';
413 return sb.status_with_size();
414}
415
417
418} // namespace string
419
420namespace unit_test {
421namespace internal {
422
423class Test;
424class TestInfo;
425
426// Types of SetUpTestSuite() and TearDownTestSuite() functions.
427using SetUpTestSuiteFunc = void (*)();
428using TearDownTestSuiteFunc = void (*)();
429
430// Used to tag arguments to EXPECT_STREQ/EXPECT_STRNE so they are treated like
431// C strings rather than pointers.
433 const char* const c_str;
434};
435
436constexpr size_t MaxPaddingNeededToRaiseAlignment(size_t current_align,
437 size_t new_align) {
438 if (new_align < current_align) {
439 return 0;
440 }
441 return new_align - current_align;
442}
443
444// GoogleTest supports stream-style messages, but pw_unit_test does not. This
445// class accepts and ignores C++ <<-style logs.
447 public:
448 constexpr FailureMessageAdapter() = default;
449
450 template <typename T>
451 constexpr const FailureMessageAdapter& operator<<(const T&) const {
452 return *this;
453 }
454};
455
456// Used to ignore a stream-style message in an assert, which returns. This
457// uses a similar approach as upstream GoogleTest, but drops any messages.
459 public:
460 constexpr ReturnHelper() = default;
461
462 // Return void so that assigning to ReturnHelper converts the log expression
463 // to void without blocking the stream-style log with a closing parenthesis.
464 // NOLINTNEXTLINE(misc-unconventional-assign-operator)
465 constexpr void operator=(const FailureMessageAdapter&) const {}
466};
467
468// Singleton test framework class responsible for managing and running test
469// cases. This implementation is internal to Pigweed test; free functions
470// wrapping its functionality are exposed as the public interface.
472 public:
473 constexpr Framework()
474 : current_test_(nullptr),
475 current_result_(TestResult::kSuccess),
476 run_tests_summary_{.passed_tests = 0,
477 .failed_tests = 0,
478 .skipped_tests = 0,
479 .disabled_tests = 0},
480 exit_status_(0),
481 event_handler_(nullptr),
482 memory_pool_() {}
483
484 static Framework& Get() { return framework_; }
485
486 // Registers a single test case with the framework. The framework owns the
487 // registered unit test. Called during static initialization.
488 void RegisterTest(TestInfo* test) const;
489
490 // Sets the handler to which the framework dispatches test events. During a
491 // test run, the framework owns the event handler.
492 inline void RegisterEventHandler(EventHandler* event_handler) {
493 event_handler_ = event_handler;
494 }
495
496 // Runs all registered test cases, returning a status of 0 if all succeeded
497 // or nonzero if there were any failures. Test events that occur during the
498 // run are sent to the registered event handler, if any.
499 int RunAllTests();
500
501 // Only run test suites whose names are included in the provided list during
502 // the next test run.
503 void SetTestSuitesToRun(span<std::string_view> test_suites) {
504 test_suites_to_run_ = test_suites;
505 }
506
507 bool ShouldRunTest(const TestInfo& test_info) const;
508
509 // Whether the current test is skipped.
510 bool IsSkipped() const { return current_result_ == TestResult::kSkipped; }
511
512 // Whether the current test has failed.
513 bool HasFailure() const { return current_result_ == TestResult::kFailure; }
514
515 // Constructs an instance of a unit test class and runs the test.
516 //
517 // Tests are constructed within a static memory pool at run time instead of
518 // being statically allocated to avoid blowing up the size of the test
519 // binary in cases where users have large test fixtures (e.g. containing
520 // buffers) reused many times. Instead, only a small, fixed-size TestInfo
521 // struct is statically allocated per test case, with a run() function that
522 // references this method instantiated for its test class.
523 template <typename TestInstance>
524 static void CreateAndRunTest(const TestInfo& test_info) {
525 static_assert(
526 sizeof(TestInstance) +
527 MaxPaddingNeededToRaiseAlignment(
528 alignof(decltype(memory_pool_)), alignof(TestInstance)) <=
529 sizeof(memory_pool_),
530 "The test memory pool is too small for this test. Either increase "
531 "PW_UNIT_TEST_CONFIG_MEMORY_POOL_SIZE or decrease the size of your "
532 "test fixture.");
533
534 Framework& framework = Get();
535 framework.StartTest(test_info);
536
537 // Reset the memory pool to a marker value to help detect use of
538 // uninitialized memory.
539 std::memset(&framework.memory_pool_, 0xa5, sizeof(framework.memory_pool_));
540
541 framework.SetUpTestSuiteIfNeeded(TestInstance::SetUpTestSuite);
542
543 // Construct the test object within the static memory pool. The StartTest
544 // function has already been called by the TestInfo at this point.
545 void* aligned_pool =
546 AlignUp(&framework.memory_pool_, alignof(TestInstance));
547 TestInstance* test_instance = new (aligned_pool) TestInstance();
548 test_instance->PigweedTestRun();
549
550 // Manually call the destructor as it is not called automatically for
551 // objects constructed using placement new.
552 test_instance->~TestInstance();
553
554 framework.TearDownTestSuiteIfNeeded(TestInstance::TearDownTestSuite);
555
556 framework.EndCurrentTest();
557 }
558
559 template <typename Expectation, typename Lhs, typename Rhs, typename Epsilon>
560 [[nodiscard]] bool CurrentTestExpectWithEpsilon(Expectation expectation,
561 const Lhs& lhs,
562 const Rhs& rhs,
563 const Epsilon& epsilon,
564 const char* expression,
565 const char* file,
566 int line) {
567 const bool success = expectation(lhs, rhs, epsilon);
568 if (!success) {
569 CurrentTestExpectSimple(expression,
570 MakeString<config::kExpectationBufferSizeBytes>(
571 ConvertForPrint(lhs),
572 " within ",
573 ConvertForPrint(epsilon),
574 " of ",
575 ConvertForPrint(rhs))
576 .c_str(),
577 file,
578 line,
579 success);
580 }
581 return success;
582 }
583
584 // Runs an expectation function for the currently active test case.
585 template <typename Expectation, typename Lhs, typename Rhs>
586 [[nodiscard]] bool CurrentTestExpect(Expectation expectation,
587 const Lhs& lhs,
588 const Rhs& rhs,
589 const char* expectation_string,
590 const char* expression,
591 const char* file,
592 int line) {
593 const bool success = expectation(lhs, rhs);
594 if (!success) {
595 CurrentTestExpectSimple(
596 expression,
597 MakeString<config::kExpectationBufferSizeBytes>(ConvertForPrint(lhs),
598 ' ',
599 expectation_string,
600 ' ',
601 ConvertForPrint(rhs))
602 .c_str(),
603 file,
604 line,
605 success);
606 }
607 return success;
608 }
609
610 // Skips the current test and dispatches an event for it.
612 const char* file, int line);
613
614 // Dispatches an event indicating the result of an expectation.
616 const char* expression,
617 const char* evaluated_expression,
618 const char* file,
619 int line,
620 bool success);
621
622 private:
623 // Convert char* to void* so that they are printed as pointers instead of
624 // strings in EXPECT_EQ and other macros. EXPECT_STREQ wraps its pointers in
625 // a CStringArg so its pointers are treated like C strings.
626 static constexpr const void* ConvertForPrint(const char* str) { return str; }
627
628 static constexpr const void* ConvertForPrint(char* str) { return str; }
629
630 static constexpr const char* ConvertForPrint(CStringArg value) {
631 return value.c_str;
632 }
633
634 template <typename T>
635 static constexpr T ConvertForPrint(T&& value) {
636 return std::forward<T>(value);
637 }
638
639 // If current_test_ will be first of its suite, call set_up_ts
640 void SetUpTestSuiteIfNeeded(SetUpTestSuiteFunc set_up_ts) const;
641
642 // If current_test_ was the last of its suite, call tear_down_ts
643 void TearDownTestSuiteIfNeeded(TearDownTestSuiteFunc tear_down_ts) const;
644
645 // Sets current_test_ and dispatches an event indicating that a test
646 // started.
647 void StartTest(const TestInfo& test);
648
649 // Dispatches event indicating that a test finished and clears
650 // current_test_.
651 void EndCurrentTest();
652
653 // Singleton instance of the framework class.
654 static Framework framework_;
655
656 // Linked list of all registered test cases. This is static as it tests are
657 // registered using static initialization.
658 static TestInfo* tests_;
659
660 // The current test case which is running.
661 const TestInfo* current_test_;
662
663 // Overall result of the current test case (pass/fail/skip).
664 TestResult current_result_;
665
666 // Overall result of the ongoing test run, which covers multiple tests.
667 RunTestsSummary run_tests_summary_;
668
669 // Program exit status returned by RunAllTests for GoogleTest compatibility.
670 int exit_status_;
671
672 // Handler to which to dispatch test events.
673 EventHandler* event_handler_;
674
675 span<std::string_view> test_suites_to_run_;
676
677 alignas(std::max_align_t) std::byte memory_pool_[config::kMemoryPoolSize];
678};
679
680// Information about a single test case, including a pointer to a function
681// which constructs and runs the test class. These are statically allocated
682// instead of the test classes, as test classes can be very large.
683class TestInfo {
684 public:
685 TestInfo(const char* const test_suite_name,
686 const char* const test_name,
687 const char* const file_name,
688 void (*run_func)(const TestInfo&))
689 : test_case_{
690 .suite_name = test_suite_name,
691 .test_name = test_name,
692 .file_name = file_name,
693 },
694 run_(run_func) {
695 Framework::Get().RegisterTest(this);
696 }
697
698 // The name of the suite to which the test case belongs, the name of the
699 // test case itself, and the path to the file in which the test case is
700 // located.
701 const TestCase& test_case() const { return test_case_; }
702
703 bool enabled() const;
704
705 void run() const { run_(*this); }
706
707 TestInfo* next() const { return next_; }
708 void set_next(TestInfo* next) { next_ = next; }
709
710 private:
711 TestCase test_case_;
712
713 // Function which runs the test case. Refers to Framework::CreateAndRunTest
714 // instantiated for the test case's class.
715 void (*run_)(const TestInfo&);
716
717 // TestInfo structs are registered with the test framework and stored as a
718 // linked list.
719 TestInfo* next_ = nullptr;
720};
721
722// Base class for all test cases or custom test fixtures.
723// Every unit test created using the TEST or TEST_F macro defines a class that
724// inherits from this (or a subclass of this).
725//
726// For example, given the following test definition:
727//
728// TEST(MyTest, SaysHello) {
729// ASSERT_STREQ(SayHello(), "Hello, world!");
730// }
731//
732// A new class is defined for the test, e.g. MyTest_SaysHello_Test. This class
733// inherits from the Test class and implements its PigweedTestBody function
734// with the block provided to the TEST macro.
735class Test {
736 public:
737 Test(const Test&) = delete;
738 Test& operator=(const Test&) = delete;
739
740 virtual ~Test() = default;
741
742 static void SetUpTestSuite() {}
743 static void TearDownTestSuite() {}
744
745 static bool HasFailure() { return Framework::Get().HasFailure(); }
746
747 // Runs the unit test.
748 void PigweedTestRun() {
749 SetUp();
750 if (!HasFailure() && !Framework::Get().IsSkipped()) {
751 PigweedTestBody();
752 }
753 TearDown();
754 }
755
756 protected:
757 Test() = default;
758
759 // Called immediately before executing the test body.
760 //
761 // Setup and cleanup can typically be done in the test fixture's constructor
762 // and destructor, but there are cases where SetUp/TearDown must be used
763 // instead. See the Google Test documentation for more information.
764 virtual void SetUp() {}
765
766 // Called immediately after executing the test body.
767 virtual void TearDown() {}
768
769 private:
770 friend class internal::Framework;
771
772 // The user-provided body of the test case. Populated by the TEST macro.
773 virtual void PigweedTestBody() = 0;
774};
775
776// Checks that a test suite name is valid.
777constexpr bool HasNoUnderscores(const char* suite) {
778 const char* disabled_prefix = "DISABLED_";
779
780 for (; *suite != '\0'; ++suite) {
781 if (*suite == *disabled_prefix) {
782 disabled_prefix += 1;
783 } else {
784 disabled_prefix = "";
785 if (*suite == '_') {
786 return false;
787 }
788 }
789 }
790 return true;
791}
792
793} // namespace internal
794
795inline void SetTestSuitesToRun(span<std::string_view> test_suites) {
796 internal::Framework::Get().SetTestSuitesToRun(test_suites);
797}
798
799} // namespace unit_test
800} // namespace pw
801
802inline int RUN_ALL_TESTS() {
803 return ::pw::unit_test::internal::Framework::Get().RunAllTests();
804}
805
806#define _PW_TEST(test_suite_name, test_name, parent_class) \
807 static_assert(sizeof(#test_suite_name) > 1, \
808 "The test suite name must not be empty"); \
809 static_assert(::pw::unit_test::internal::HasNoUnderscores(#test_suite_name), \
810 "The test suite name (" #test_suite_name \
811 ") cannot contain underscores"); \
812 static_assert(sizeof(#test_name) > 1, "The test name must not be empty"); \
813 \
814 _PW_TEST_CLASS(test_suite_name, \
815 test_name, \
816 test_suite_name##_##test_name##_Test, \
817 parent_class)
818
819#define _PW_TEST_CLASS(suite, name, class_name, parent_class) \
820 class class_name final : public parent_class { \
821 private: \
822 void PigweedTestBody() override; \
823 }; \
824 \
825 extern "C" { \
826 \
827 /* Silence ASAN to avoid errors in the initialization order checker */ \
828 /* caused by the intentional use of dynamic initializers which modify */ \
829 /* other globals */ \
830 PW_NO_SANITIZE("address") \
831 /* Declare the TestInfo as non-const since const variables do not work */ \
832 /* with the PW_UNIT_TEST_LINK_FILE_CONTAINING_TEST macro. */ \
833 /* NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) */ \
834 ::pw::unit_test::internal::TestInfo _pw_unit_test_Info_##suite##_##name( \
835 #suite, \
836 #name, \
837 __FILE__, \
838 ::pw::unit_test::internal::Framework::CreateAndRunTest<class_name>); \
839 \
840 } /* extern "C" */ \
841 \
842 void class_name::PigweedTestBody()
843
844#define _PW_TEST_ASSERT(expectation) \
845 if (!(expectation)) \
846 return ::pw::unit_test::internal::ReturnHelper() = \
847 ::pw::unit_test::internal::FailureMessageAdapter()
848
849#define _PW_TEST_EXPECT(expectation) \
850 if (!(expectation)) \
851 ::pw::unit_test::internal::FailureMessageAdapter()
852
853#define _PW_TEST_BOOL(expr, value) \
854 ::pw::unit_test::internal::Framework::Get().CurrentTestExpect( \
855 [](bool _pw_lhs, bool _pw_rhs) { return _pw_lhs == _pw_rhs; }, \
856 static_cast<bool>(expr), \
857 value, \
858 "is", \
859 #expr " is " #value, \
860 __FILE__, \
861 __LINE__)
862
863#define _PW_TEST_OP(lhs, rhs, op) \
864 ::pw::unit_test::internal::Framework::Get().CurrentTestExpect( \
865 [](const auto& _pw_lhs, const auto& _pw_rhs) { \
866 return _pw_lhs op _pw_rhs; \
867 }, \
868 (lhs), \
869 (rhs), \
870 #op, \
871 #lhs " " #op " " #rhs, \
872 __FILE__, \
873 __LINE__)
874
875#define _PW_TEST_NEAR(lhs, rhs, epsilon) \
876 ::pw::unit_test::internal::Framework::Get().CurrentTestExpectWithEpsilon( \
877 [](const auto& _pw_lhs, const auto& _pw_rhs, const auto& _pw_epsilon) { \
878 return std::abs(_pw_lhs - _pw_rhs) <= _pw_epsilon; \
879 }, \
880 (lhs), \
881 (rhs), \
882 (epsilon), \
883 #lhs " within " #epsilon " of " #rhs, \
884 __FILE__, \
885 __LINE__)
886
887#define _PW_TEST_C_STR(lhs, rhs, op) \
888 ::pw::unit_test::internal::Framework::Get().CurrentTestExpect( \
889 [](const auto& _pw_lhs, const auto& _pw_rhs) { \
890 auto cmp = [](const char* l, const char* r) -> int { \
891 if (!l || !r) { \
892 return l != r; \
893 } \
894 return std::strcmp(l, r); \
895 }; \
896 return cmp(_pw_lhs.c_str, _pw_rhs.c_str) op 0; \
897 }, \
898 ::pw::unit_test::internal::CStringArg{lhs}, \
899 ::pw::unit_test::internal::CStringArg{rhs}, \
900 #op, \
901 #lhs " " #op " " #rhs, \
902 __FILE__, \
903 __LINE__)
904
905// Checks that test suite names between TEST and TEST_F declarations are unique.
906// This works by declaring a function named for the test suite. The function
907// takes no arguments but is declared with different return types in the TEST
908// and TEST_F macros. If a TEST and TEST_F use the same test suite name, the
909// function declarations conflict, resulting in a compilation error.
910//
911// This catches most conflicts, but a runtime check is ultimately needed since
912// tests may be declared in different translation units.
913#if !defined(__clang__) && !defined(__GNUC___) && __GNUC__ <= 8
914// For some reason GCC8 is unable to ignore -Wredundant-decls here.
915#define _PW_TEST_SUITE_NAMES_MUST_BE_UNIQUE(return_type, test_suite)
916#else // All other compilers.
917#define _PW_TEST_SUITE_NAMES_MUST_BE_UNIQUE(return_type, test_suite) \
918 PW_MODIFY_DIAGNOSTICS_PUSH(); \
919 PW_MODIFY_DIAGNOSTIC(ignored, "-Wredundant-decls"); \
920 extern "C" return_type /* use extern "C" to escape namespacing */ \
921 PwUnitTestSuiteNamesMustBeUniqueBetweenTESTandTEST_F_##test_suite(void); \
922 PW_MODIFY_DIAGNOSTICS_POP()
923#endif // GCC8 or older.
924
925namespace testing {
926
927// Alias Test as ::testing::Test for GoogleTest compatibility.
929
930// Provide a no-op init routine for GoogleTest compatibility.
931inline void InitGoogleTest(int*, char**) {}
932
933} // namespace testing
Definition: span_impl.h:235
Definition: event_handler.h:122
Definition: framework_backend.h:446
Definition: framework_backend.h:471
Definition: framework_backend.h:458
Definition: framework_backend.h:735
Definition: framework_backend.h:683
constexpr size_t AlignUp(uintptr_t value, size_t alignment)
Returns the value rounded up to the nearest multiple of alignment.
Definition: alignment.h:54
int RUN_ALL_TESTS()
Definition: framework_backend.h:802
TestResult
The result of a complete test run.
Definition: event_handler.h:23
The Pigweed namespace.
Definition: alignment.h:27
Definition: event_handler.h:59
Definition: event_handler.h:30
Definition: framework_backend.h:432