18#include "lib/stdcompat/type_traits.h"
19#include "pw_preprocessor/boolean.h"
20#include "pw_preprocessor/concat.h"
43#define PW_CONSTEXPR_TEST(test_suite, test_name, ...) \
44 _PW_IF_CONSTEXPR_TEST(constexpr) \
45 void PwConstexprTest_##test_suite##_##test_name() __VA_ARGS__ \
47 TEST(test_suite, test_name) { \
48 PwConstexprTest_##test_suite##_##test_name(); \
52 _PW_IF_CONSTEXPR_TEST(PwConstexprTest_##test_suite##_##test_name();) \
63#define PW_CONSTEXPR_TEST_IF_CLANG PW_CONSTEXPR_TEST
65#define PW_CONSTEXPR_TEST_IF_CLANG(test_suite, test_case, ...) \
66 TEST(test_suite, test_case) \
76#if !defined(__clang__) && defined(__GNUC__)
77#define PW_CONSTEXPR_TEST_IF_GCC PW_CONSTEXPR_TEST
79#define PW_CONSTEXPR_TEST_IF_GCC(test_suite, test_case, ...) \
80 TEST(test_suite, test_case) \
87#define PW_TEST_EXPECT_TRUE(expr) _PW_CEXPECT(TRUE, expr)
88#define PW_TEST_EXPECT_FALSE(expr) _PW_CEXPECT(FALSE, expr)
90#define PW_TEST_EXPECT_EQ(lhs, rhs) _PW_CEXPECT(EQ, lhs, rhs)
91#define PW_TEST_EXPECT_NE(lhs, rhs) _PW_CEXPECT(NE, lhs, rhs)
92#define PW_TEST_EXPECT_GT(lhs, rhs) _PW_CEXPECT(GT, lhs, rhs)
93#define PW_TEST_EXPECT_GE(lhs, rhs) _PW_CEXPECT(GE, lhs, rhs)
94#define PW_TEST_EXPECT_LT(lhs, rhs) _PW_CEXPECT(LT, lhs, rhs)
95#define PW_TEST_EXPECT_LE(lhs, rhs) _PW_CEXPECT(LE, lhs, rhs)
97#define PW_TEST_EXPECT_NEAR(lhs, rhs, error) _PW_CEXPECT(NEAR, lhs, rhs, error)
98#define PW_TEST_EXPECT_FLOAT_EQ(lhs, rhs) _PW_CEXPECT(FLOAT_EQ, lhs, rhs)
99#define PW_TEST_EXPECT_DOUBLE_EQ(lhs, rhs) _PW_CEXPECT(DOUBLE_EQ, lhs, rhs)
101#define PW_TEST_EXPECT_STREQ(lhs, rhs) _PW_CEXPECT(STREQ, lhs, rhs)
102#define PW_TEST_EXPECT_STRNE(lhs, rhs) _PW_CEXPECT(STRNE, lhs, rhs)
104#define PW_TEST_ASSERT_TRUE(expr) _PW_CASSERT(TRUE, expr)
105#define PW_TEST_ASSERT_FALSE(expr) _PW_CASSERT(FALSE, expr)
107#define PW_TEST_ASSERT_EQ(lhs, rhs) _PW_CASSERT(EQ, lhs, rhs)
108#define PW_TEST_ASSERT_NE(lhs, rhs) _PW_CASSERT(NE, lhs, rhs)
109#define PW_TEST_ASSERT_GT(lhs, rhs) _PW_CASSERT(GT, lhs, rhs)
110#define PW_TEST_ASSERT_GE(lhs, rhs) _PW_CASSERT(GE, lhs, rhs)
111#define PW_TEST_ASSERT_LT(lhs, rhs) _PW_CASSERT(LT, lhs, rhs)
112#define PW_TEST_ASSERT_LE(lhs, rhs) _PW_CASSERT(LE, lhs, rhs)
114#define PW_TEST_ASSERT_NEAR(lhs, rhs, error) _PW_CASSERT(NEAR, lhs, rhs, error)
115#define PW_TEST_ASSERT_FLOAT_EQ(lhs, rhs) _PW_CASSERT(FLOAT_EQ, lhs, rhs)
116#define PW_TEST_ASSERT_DOUBLE_EQ(lhs, rhs) _PW_CASSERT(DOUBLE_EQ, lhs, rhs)
118#define PW_TEST_ASSERT_STREQ(lhs, rhs) _PW_CASSERT(STREQ, lhs, rhs)
119#define PW_TEST_ASSERT_STRNE(lhs, rhs) _PW_CASSERT(STRNE, lhs, rhs)
125#define _PW_CEXPECT(macro, ...) \
126 if (cpp20::is_constant_evaluated()) { \
127 ::pw::unit_test::internal::Constexpr_EXPECT_##macro(__VA_ARGS__); \
129 EXPECT_##macro(__VA_ARGS__)
131#define _PW_CASSERT(macro, ...) \
132 if (cpp20::is_constant_evaluated()) { \
133 if (!::pw::unit_test::internal::Constexpr_EXPECT_##macro(__VA_ARGS__)) { \
137 ASSERT_##macro(__VA_ARGS__)
141#define _PW_IF_CONSTEXPR_TEST(a) \
143 _PW_IF_CONSTEXPR_TEST_, \
144 PW_AND(LIB_STDCOMPAT_CONSTEVAL_SUPPORT, \
145 _PW_CONSTEXPR_TEST_ENABLED(SKIP_CONSTEXPR_TESTS_DONT_SUBMIT)))(a)
147#define _PW_IF_CONSTEXPR_TEST_0(a)
148#define _PW_IF_CONSTEXPR_TEST_1(a) a
150#define _PW_CONSTEXPR_TEST_ENABLED(a) _PW_CONSTEXPR_TEST_ENABLED2(a)
151#define _PW_CONSTEXPR_TEST_ENABLED2(a) _PW_CONSTEXPR_TEST_##a
155#define _PW_CONSTEXPR_TEST_SKIP_CONSTEXPR_TESTS_DONT_SUBMIT 1
156#define _PW_CONSTEXPR_TEST_ 0
157#define _PW_CONSTEXPR_TEST_1 0
158#define _PW_CONSTEXPR_TEST_0 \
159 _Do_not_define_SKIP_CONSTEXPR_TESTS_DONT_SUBMIT_to_0_remove_it_instead
162namespace pw::unit_test::internal {
166bool EXPECT_TRUE_FAILED();
167bool EXPECT_FALSE_FAILED();
168bool EXPECT_EQ_FAILED();
169bool EXPECT_NE_FAILED();
170bool EXPECT_GT_FAILED();
171bool EXPECT_GE_FAILED();
172bool EXPECT_LT_FAILED();
173bool EXPECT_LE_FAILED();
174bool EXPECT_NEAR_FAILED();
175bool EXPECT_STREQ_FAILED();
176bool EXPECT_STRNE_FAILED();
179constexpr bool Constexpr_EXPECT_TRUE(
const T& expr) {
180 return (expr) ? true : EXPECT_TRUE_FAILED();
184constexpr bool Constexpr_EXPECT_FALSE(
const T& expr) {
185 return !(expr) ?
true : EXPECT_FALSE_FAILED();
188template <
typename Lhs,
typename Rhs>
189constexpr bool Constexpr_EXPECT_EQ(
const Lhs& lhs,
const Rhs& rhs) {
190 return (lhs == rhs) ? true : EXPECT_EQ_FAILED();
193template <
typename Lhs,
typename Rhs>
194constexpr bool Constexpr_EXPECT_NE(
const Lhs& lhs,
const Rhs& rhs) {
195 return (lhs != rhs) ? true : EXPECT_NE_FAILED();
198template <
typename Lhs,
typename Rhs>
199constexpr bool Constexpr_EXPECT_GT(
const Lhs& lhs,
const Rhs& rhs) {
200 return (lhs > rhs) ? true : EXPECT_GT_FAILED();
203template <
typename Lhs,
typename Rhs>
204constexpr bool Constexpr_EXPECT_GE(
const Lhs& lhs,
const Rhs& rhs) {
205 return (lhs >= rhs) ? true : EXPECT_GE_FAILED();
208template <
typename Lhs,
typename Rhs>
209constexpr bool Constexpr_EXPECT_LT(
const Lhs& lhs,
const Rhs& rhs) {
210 return (lhs < rhs) ? true : EXPECT_LT_FAILED();
213template <
typename Lhs,
typename Rhs>
214constexpr bool Constexpr_EXPECT_LE(
const Lhs& lhs,
const Rhs& rhs) {
215 return (lhs <= rhs) ? true : EXPECT_LE_FAILED();
219constexpr bool Constexpr_EXPECT_NEAR(T lhs, T rhs, T error) {
224 return (diff <= error) ? true : EXPECT_NEAR_FAILED();
227constexpr bool Constexpr_EXPECT_FLOAT_EQ(
float lhs,
float rhs) {
229 return Constexpr_EXPECT_NEAR(
230 lhs, rhs, 4 * std::numeric_limits<float>::epsilon());
233constexpr bool Constexpr_EXPECT_DOUBLE_EQ(
double lhs,
double rhs) {
235 return Constexpr_EXPECT_NEAR(
236 lhs, rhs, 4 * std::numeric_limits<double>::epsilon());
239[[nodiscard]]
constexpr bool StringsAreEqual(
const char* lhs,
const char* rhs) {
240 if (lhs ==
nullptr || rhs ==
nullptr) {
244 while (*lhs == *rhs && *lhs !=
'\0') {
249 return *lhs ==
'\0' && *rhs ==
'\0';
252constexpr bool Constexpr_EXPECT_STREQ(
const char* lhs,
const char* rhs) {
253 return StringsAreEqual(lhs, rhs) ? true : EXPECT_STREQ_FAILED();
256constexpr bool Constexpr_EXPECT_STRNE(
const char* lhs,
const char* rhs) {
257 return !StringsAreEqual(lhs, rhs) ? true : EXPECT_STRNE_FAILED();