diff options
author | Wyatt Hepler <hepler@google.com> | 2023-08-31 21:46:11 +0000 |
---|---|---|
committer | CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-08-31 21:46:11 +0000 |
commit | 1961c9c8ef71c4fec09b34a96f86bf2b9456fe38 (patch) | |
tree | 59275a6ecf76adfd98fcc97ef6cdb90850cb9c39 /pw_unit_test | |
parent | d87b6d5a00113bda15ad32595ba2bb55f2c1f9b9 (diff) | |
download | pigweed-1961c9c8ef71c4fec09b34a96f86bf2b9456fe38.tar.gz |
pw_unit_test: Allow <<-style messages in test expectations
For compatibility with GoogleTest, support <<-style messages in
pw_unit_test test expectations. These messages are currently ignored.
Change-Id: I4cab3240a78a127ad56d527d0e494d1d06c0b764
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/168860
Reviewed-by: Alexei Frolov <frolv@google.com>
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Gilhooley <dgilhooley@google.com>
Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed-service-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'pw_unit_test')
-rw-r--r-- | pw_unit_test/docs.rst | 31 | ||||
-rw-r--r-- | pw_unit_test/framework_test.cc | 31 | ||||
-rw-r--r-- | pw_unit_test/public/pw_unit_test/internal/framework.h | 77 |
3 files changed, 105 insertions, 34 deletions
diff --git a/pw_unit_test/docs.rst b/pw_unit_test/docs.rst index d67127521..74e7f18cc 100644 --- a/pw_unit_test/docs.rst +++ b/pw_unit_test/docs.rst @@ -33,22 +33,29 @@ for examples of how to define unit test cases. expected in a complete testing framework; nevertheless, it is already used heavily within Pigweed. -.. note:: +GoogleTest compatibility +======================== +pw_unit_test implements a subset of GoogleTest. Supported features include: + +* Test and test suite declarations. +* Most ``EXPECT`` and ``ASSERT`` macros. +* Stream-style expectation messages, such as + ``EXPECT_EQ(val, 5) << "Inputs: " << input``. Messages are currently ignored. - Many of GoogleTest's more advanced features are not yet implemented. Missing - features include: +Many of GoogleTest's advanced features are not yet implemented. Missing features +include: - * Any GoogleMock features (e.g. :c:macro:`EXPECT_THAT`) - * Floating point comparison macros (e.g. :c:macro:`EXPECT_FLOAT_EQ`) - * Death tests (e.g. :c:macro:`EXPECT_DEATH`); ``EXPECT_DEATH_IF_SUPPORTED`` - does nothing but silently passes - * Value-parameterized tests +* Any GoogleMock features (e.g. :c:macro:`EXPECT_THAT`) +* Floating point comparison macros (e.g. :c:macro:`EXPECT_FLOAT_EQ`) +* Death tests (e.g. :c:macro:`EXPECT_DEATH`); ``EXPECT_DEATH_IF_SUPPORTED`` + does nothing but silently passes +* Value-parameterized tests - To request a feature addition, please - `let us know <mailto:pigweed@googlegroups.com>`_. +To request a feature addition, please `let us know +<mailto:pigweed@googlegroups.com>`_. - See `Using upstream GoogleTest`_ below for information - about using upstream GoogleTest instead. +See `Using upstream GoogleTest`_ below for information +about using upstream GoogleTest instead. The EventHandler interface ========================== diff --git a/pw_unit_test/framework_test.cc b/pw_unit_test/framework_test.cc index 6581d8c20..a9d8312f8 100644 --- a/pw_unit_test/framework_test.cc +++ b/pw_unit_test/framework_test.cc @@ -88,6 +88,37 @@ TEST(PigweedTest, SkipMacro) { EXPECT_TRUE(false); } +TEST(PigweedTest, Logs) { + EXPECT_TRUE(true) << "This message is ignored"; + EXPECT_FALSE(false) << "This message is ignored"; + EXPECT_EQ(0, 0) << "This message is ignored"; + EXPECT_NE(0, 1) << "This message is ignored"; + EXPECT_GT(1, 0) << "This message is ignored"; + EXPECT_GE(0, 0) << "This message is ignored"; + EXPECT_LT(0, 1) << "This message is ignored"; + EXPECT_LE(0, 0) << "This message is ignored"; + EXPECT_STREQ("", "") << "This message is ignored"; + EXPECT_STRNE("", "?") << "This message is ignored"; + + ASSERT_TRUE(true) << "This message is ignored"; + ASSERT_FALSE(false) << "This message is ignored"; + ASSERT_EQ(0, 0) << "This message is ignored"; + ASSERT_NE(0, 1) << "This message is ignored"; + ASSERT_GT(1, 0) << "This message is ignored"; + ASSERT_GE(0, 0) << "This message is ignored"; + ASSERT_LT(0, 1) << "This message is ignored"; + ASSERT_LE(0, 0) << "This message is ignored"; + ASSERT_STREQ("", "") << "This message is ignored"; + ASSERT_STRNE("", "?") << "This message is ignored"; + + if (false) { + ADD_FAILURE() << "This failed!" << 123; + GTEST_FAIL() << "This failed!" << 123 << '?'; + GTEST_SKIP() << 1.0f << " skips!"; + } + GTEST_SUCCEED() << "This message is ignored"; +} + class SkipOnSetUpTest : public ::testing::Test { public: void SetUp() override { GTEST_SKIP(); } diff --git a/pw_unit_test/public/pw_unit_test/internal/framework.h b/pw_unit_test/public/pw_unit_test/internal/framework.h index 11bccc727..6084ed510 100644 --- a/pw_unit_test/public/pw_unit_test/internal/framework.h +++ b/pw_unit_test/public/pw_unit_test/internal/framework.h @@ -47,16 +47,16 @@ _PW_TEST_SUITE_NAMES_MUST_BE_UNIQUE(int /* TEST_F */, test_fixture); \ _PW_TEST(test_fixture, test_name, test_fixture) -#define EXPECT_TRUE(expr) static_cast<void>(_PW_TEST_BOOL(expr, true)) -#define EXPECT_FALSE(expr) static_cast<void>(_PW_TEST_BOOL(expr, false)) -#define EXPECT_EQ(lhs, rhs) static_cast<void>(_PW_TEST_OP(lhs, rhs, ==)) -#define EXPECT_NE(lhs, rhs) static_cast<void>(_PW_TEST_OP(lhs, rhs, !=)) -#define EXPECT_GT(lhs, rhs) static_cast<void>(_PW_TEST_OP(lhs, rhs, >)) -#define EXPECT_GE(lhs, rhs) static_cast<void>(_PW_TEST_OP(lhs, rhs, >=)) -#define EXPECT_LT(lhs, rhs) static_cast<void>(_PW_TEST_OP(lhs, rhs, <)) -#define EXPECT_LE(lhs, rhs) static_cast<void>(_PW_TEST_OP(lhs, rhs, <=)) -#define EXPECT_STREQ(lhs, rhs) static_cast<void>(_PW_TEST_C_STR(lhs, rhs, ==)) -#define EXPECT_STRNE(lhs, rhs) static_cast<void>(_PW_TEST_C_STR(lhs, rhs, !=)) +#define EXPECT_TRUE(expr) _PW_TEST_EXPECT(_PW_TEST_BOOL(expr, true)) +#define EXPECT_FALSE(expr) _PW_TEST_EXPECT(_PW_TEST_BOOL(expr, false)) +#define EXPECT_EQ(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, ==)) +#define EXPECT_NE(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, !=)) +#define EXPECT_GT(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, >)) +#define EXPECT_GE(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, >=)) +#define EXPECT_LT(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, <)) +#define EXPECT_LE(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_OP(lhs, rhs, <=)) +#define EXPECT_STREQ(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_C_STR(lhs, rhs, ==)) +#define EXPECT_STRNE(lhs, rhs) _PW_TEST_EXPECT(_PW_TEST_C_STR(lhs, rhs, !=)) #define ASSERT_TRUE(expr) _PW_TEST_ASSERT(_PW_TEST_BOOL(expr, true)) #define ASSERT_FALSE(expr) _PW_TEST_ASSERT(_PW_TEST_BOOL(expr, false)) @@ -70,17 +70,19 @@ #define ASSERT_STRNE(lhs, rhs) _PW_TEST_ASSERT(_PW_TEST_C_STR(lhs, rhs, !=)) // Generates a non-fatal failure with a generic message. -#define ADD_FAILURE() \ - ::pw::unit_test::internal::Framework::Get().CurrentTestExpectSimple( \ - "(line is not executed)", "(line was executed)", __LINE__, false) +#define ADD_FAILURE() \ + ::pw::unit_test::internal::Framework::Get().CurrentTestExpectSimple( \ + "(line is not executed)", "(line was executed)", __LINE__, false); \ + _PW_UNIT_TEST_LOG // Generates a fatal failure with a generic message. #define GTEST_FAIL() return ADD_FAILURE() // Skips test at runtime, which is neither successful nor failed. Skip aborts // current function. -#define GTEST_SKIP() \ - return ::pw::unit_test::internal::Framework::Get().CurrentTestSkip(__LINE__) +#define GTEST_SKIP() \ + ::pw::unit_test::internal::Framework::Get().CurrentTestSkip(__LINE__); \ + return _PW_UNIT_TEST_LOG // Define either macro to 1 to omit the definition of FAIL(), which is a // generic name and clashes with some other libraries. @@ -91,7 +93,8 @@ // Generates a success with a generic message. #define GTEST_SUCCEED() \ ::pw::unit_test::internal::Framework::Get().CurrentTestExpectSimple( \ - "(success)", "(success)", __LINE__, true) + "(success)", "(success)", __LINE__, true); \ + _PW_UNIT_TEST_LOG // Define either macro to 1 to omit the definition of SUCCEED(), which // is a generic name and clashes with some other libraries. @@ -497,6 +500,35 @@ constexpr bool HasNoUnderscores(const char* suite) { return true; } +// GoogleTest supports stream-style messages, but pw_unit_test does not. This +// class accepts and ignores C++ <<-style logs. This could be replaced with +// pw_log/glog_adapter.h. +class IgnoreLogs { + public: + constexpr IgnoreLogs() = default; + + template <typename T> + constexpr const IgnoreLogs& operator<<(const T&) const { + return *this; + } +}; + +// Used to ignore a stream-style message in an assert, which returns. This uses +// a similar approach as upstream GoogleTest, but drops any messages. +class ReturnHelper { + public: + constexpr ReturnHelper() = default; + + // Return void so that assigning to ReturnHelper converts the log expression + // to void without blocking the stream-style log with a closing parenthesis. + // NOLINTNEXTLINE(misc-unconventional-assign-operator) + constexpr void operator=(const IgnoreLogs&) const {} +}; + +#define _PW_UNIT_TEST_LOG \ + ::pw::unit_test::internal::ReturnHelper() = \ + ::pw::unit_test::internal::IgnoreLogs() + } // namespace internal #if PW_CXX_STANDARD_IS_SUPPORTED(17) @@ -542,12 +574,13 @@ inline void SetTestSuitesToRun(span<std::string_view> test_suites) { \ void class_name::PigweedTestBody() -#define _PW_TEST_ASSERT(expectation) \ - do { \ - if (!(expectation)) { \ - return static_cast<void>(0); /* Prevent using ASSERT in constructors. */ \ - } \ - } while (0) +#define _PW_TEST_ASSERT(expectation) \ + if (!(expectation)) \ + return _PW_UNIT_TEST_LOG + +#define _PW_TEST_EXPECT(expectation) \ + if (!(expectation)) \ + _PW_UNIT_TEST_LOG #define _PW_TEST_BOOL(expr, value) \ ::pw::unit_test::internal::Framework::Get().CurrentTestExpect( \ |