#include <limits>
#include "lib/stdcompat/type_traits.h"
#include "pw_preprocessor/boolean.h"
#include "pw_preprocessor/concat.h"
Go to the source code of this file.
Namespaces | |
namespace | pw |
Provides basic helpers for reading and writing UTF-8 encoded strings. | |
Macros | |
#define | PW_CONSTEXPR_TEST(test_suite, test_name, ...) |
#define | PW_TEST_EXPECT_TRUE(expr) _PW_CEXPECT(TRUE, expr) |
#define | PW_TEST_EXPECT_FALSE(expr) _PW_CEXPECT(FALSE, expr) |
#define | PW_TEST_EXPECT_EQ(lhs, rhs) _PW_CEXPECT(EQ, lhs, rhs) |
#define | PW_TEST_EXPECT_NE(lhs, rhs) _PW_CEXPECT(NE, lhs, rhs) |
#define | PW_TEST_EXPECT_GT(lhs, rhs) _PW_CEXPECT(GT, lhs, rhs) |
#define | PW_TEST_EXPECT_GE(lhs, rhs) _PW_CEXPECT(GE, lhs, rhs) |
#define | PW_TEST_EXPECT_LT(lhs, rhs) _PW_CEXPECT(LT, lhs, rhs) |
#define | PW_TEST_EXPECT_LE(lhs, rhs) _PW_CEXPECT(LE, lhs, rhs) |
#define | PW_TEST_EXPECT_NEAR(lhs, rhs, error) _PW_CEXPECT(NEAR, lhs, rhs, error) |
#define | PW_TEST_EXPECT_FLOAT_EQ(lhs, rhs) _PW_CEXPECT(FLOAT_EQ, lhs, rhs) |
#define | PW_TEST_EXPECT_DOUBLE_EQ(lhs, rhs) _PW_CEXPECT(DOUBLE_EQ, lhs, rhs) |
#define | PW_TEST_EXPECT_STREQ(lhs, rhs) _PW_CEXPECT(STREQ, lhs, rhs) |
#define | PW_TEST_EXPECT_STRNE(lhs, rhs) _PW_CEXPECT(STRNE, lhs, rhs) |
#define | PW_TEST_ASSERT_TRUE(expr) _PW_CASSERT(TRUE, expr) |
#define | PW_TEST_ASSERT_FALSE(expr) _PW_CASSERT(FALSE, expr) |
#define | PW_TEST_ASSERT_EQ(lhs, rhs) _PW_CASSERT(EQ, lhs, rhs) |
#define | PW_TEST_ASSERT_NE(lhs, rhs) _PW_CASSERT(NE, lhs, rhs) |
#define | PW_TEST_ASSERT_GT(lhs, rhs) _PW_CASSERT(GT, lhs, rhs) |
#define | PW_TEST_ASSERT_GE(lhs, rhs) _PW_CASSERT(GE, lhs, rhs) |
#define | PW_TEST_ASSERT_LT(lhs, rhs) _PW_CASSERT(LT, lhs, rhs) |
#define | PW_TEST_ASSERT_LE(lhs, rhs) _PW_CASSERT(LE, lhs, rhs) |
#define | PW_TEST_ASSERT_NEAR(lhs, rhs, error) _PW_CASSERT(NEAR, lhs, rhs, error) |
#define | PW_TEST_ASSERT_FLOAT_EQ(lhs, rhs) _PW_CASSERT(FLOAT_EQ, lhs, rhs) |
#define | PW_TEST_ASSERT_DOUBLE_EQ(lhs, rhs) _PW_CASSERT(DOUBLE_EQ, lhs, rhs) |
#define | PW_TEST_ASSERT_STREQ(lhs, rhs) _PW_CASSERT(STREQ, lhs, rhs) |
#define | PW_TEST_ASSERT_STRNE(lhs, rhs) _PW_CASSERT(STRNE, lhs, rhs) |
#define | _PW_CEXPECT(macro, ...) |
#define | _PW_CASSERT(macro, ...) |
#define | _PW_IF_CONSTEXPR_TEST(a) |
#define | _PW_IF_CONSTEXPR_TEST_0(a) |
#define | _PW_IF_CONSTEXPR_TEST_1(a) a |
#define | _PW_CONSTEXPR_TEST_ENABLED(a) _PW_CONSTEXPR_TEST_ENABLED2(a) |
#define | _PW_CONSTEXPR_TEST_ENABLED2(a) _PW_CONSTEXPR_TEST_##a |
#define | _PW_CONSTEXPR_TEST_SKIP_CONSTEXPR_TESTS_DONT_SUBMIT 1 |
#define | _PW_CONSTEXPR_TEST_ 0 |
#define | _PW_CONSTEXPR_TEST_1 0 |
#define | _PW_CONSTEXPR_TEST_0 _Do_not_define_SKIP_CONSTEXPR_TESTS_DONT_SUBMIT_to_0_remove_it_instead |
The
embed:rst:inline :c:macro:`PW_CONSTEXPR_TEST`
macro defines a test that is executed both at compile time in a static_assert
and as a regular GoogleTest-style TEST()
. This offers the advantages of compile-time testing in a structured, familiar API, without sacrificing anything from GoogleTest-style tests. The framework uses the standard GoogleTest macros at run time, and is compatible with GoogleTest or Pigweed's pw_unit_test:light
framework.
To create a constexpr
test:
"pw_unit_test/constexpr.h"
alongside the test framework ("pw_unit_test/framework.h"
or "gtest/gtest.h"
).embed:rst:inline :c:macro:`PW_CONSTEXPR_TEST`instead of
TEST
. Note that the function body passed as the third argument to the macro.PW_TEST_
prefix. For example:EXPECT_TRUE
→ embed:rst:inline :c:macro:`PW_TEST_EXPECT_TRUE`
EXPECT_EQ
→ embed:rst:inline :c:macro:`PW_TEST_EXPECT_EQ`
ASSERT_STREQ
→ embed:rst:inline :c:macro:`PW_TEST_ASSERT_STREQ`
The result is a familiar-looking unit test that executes both at compile time and run time.
embed:rst:leading-asterisk * .. literalinclude:: constexpr_test.cc * :language: cpp * :start-after: [pw_unit_test-constexpr] * :end-before: [pw_unit_test-constexpr] * *
Why should I run tests at compile time?
constexpr
functions can actually be evaluated at compile time. For example, function templates may be marked as constexpr
, even if they do not support constant evaluation when instantiated.If compile-time testing is so great, why execute the tests are run time at all?
std::is_constant_evaluated
or if consteval
are used.embed:rst:inline :c:macro:`PW_CONSTEXPR_TEST`makes it simple to temporarily disable compile-time tests and see the rich GoogleTest-like output (see
embed:rst:inline :c:macro:`SKIP_CONSTEXPR_TESTS_DONT_SUBMIT`).
embed:rst:inline :c:macro:`PW_CONSTEXPR_TEST`
uses stdcompat
's cpp20::is_constant_evaluated()
. If the compiler does not support is_constant_evaluated
, only the regular GoogleTest version will run. Note that compiler support is independent of the C++ standard in use.
#define _PW_CASSERT | ( | macro, | |
... | |||
) |
#define _PW_CEXPECT | ( | macro, | |
... | |||
) |
#define _PW_IF_CONSTEXPR_TEST | ( | a | ) |
#define PW_CONSTEXPR_TEST | ( | test_suite, | |
test_name, | |||
... | |||
) |
Defines a test that is executed both at compile time in a static_assert
and as a regular GoogleTest-style TEST()
.
PW_CONSTEXPR_TEST
works similarly to the GoogleTest TEST()
macro, but has some differences.
constexpr
.PW_TEST_*
prefixed versions of GoogleTest's EXPECT_*
and ASSERT_*
macros.#define
. If these are needed, move them to a separate function that is called from the test.PW_CONSTEXPR_TEST
macro must be terminated with );
after the test body argument.test_suite | GoogleTest test suite name |
test_name | GoogleTest test name |
... | test function body surrounded by { } . |