aboutsummaryrefslogtreecommitdiff
path: root/pw_unit_test
diff options
context:
space:
mode:
authorWyatt Hepler <hepler@google.com>2023-08-31 21:46:11 +0000
committerCQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-08-31 21:46:11 +0000
commit1961c9c8ef71c4fec09b34a96f86bf2b9456fe38 (patch)
tree59275a6ecf76adfd98fcc97ef6cdb90850cb9c39 /pw_unit_test
parentd87b6d5a00113bda15ad32595ba2bb55f2c1f9b9 (diff)
downloadpigweed-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.rst31
-rw-r--r--pw_unit_test/framework_test.cc31
-rw-r--r--pw_unit_test/public/pw_unit_test/internal/framework.h77
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( \