Pointer comparisons

This commit is contained in:
2026-09-12 12:23:14 -05:00
parent fa5c39c83f
commit a8fb8f8f6b
+49 -40
View File
@@ -20,12 +20,13 @@
/** /**
* @struct microtest_suite
* @brief A structure to define a single test suite. * @brief A structure to define a single test suite.
* @details Tests suites are how microtest tracks what tests need execution. * @details Tests suites are how microtest tracks what tests need execution.
* That is, they are not ignored. It tracks the actual function that * That is, they are not ignored. It tracks the actual function that
* will be executed and the name of that test as defined by the user. * will be executed and the name of that test as defined by the user.
*/ */
typedef struct { define_struct(microtest_suite) {
/** /**
* @brief A pointer to a function which runs the test suite. * @brief A pointer to a function which runs the test suite.
* @details This should be populated by microtest to be the function which the * @details This should be populated by microtest to be the function which the
@@ -49,28 +50,15 @@ typedef struct {
* will be indicated in the output log of the runner. * will be indicated in the output log of the runner.
*/ */
malunal_bool_t ignored; malunal_bool_t ignored;
} microtest_suite_t; };
/**
* @brief Type defines a pointer to a mutable microtest test suite.
* @details This is provided to make function declarations simpler and align the
* naming conventions of other types within our libraries.
*/
typedef microtest_suite_t* microtest_suite_mptr_t;
/**
* @brief Type defines a pointer to an immutable microtest test suite.
* @details This is provided to make function declarations simpler and align the
* naming conventions of other types within our libraries.
*/
typedef const microtest_suite_t* microtest_suite_iptr_t;
/** /**
* @struct microtest_state
* @brief A structure to define the microtest state object. * @brief A structure to define the microtest state object.
* @details The state object is used to easily track what tests suites are * @details The state object is used to easily track what tests suites are
* contained and need execution. * contained and need execution.
*/ */
typedef struct { define_struct(microtest_state) {
/** /**
* @brief The list of tests to execute. * @brief The list of tests to execute.
* @details This will be automatically resized at startup by the registration * @details This will be automatically resized at startup by the registration
@@ -84,22 +72,7 @@ typedef struct {
* functions, to make sure that microtest knows how many there are. * functions, to make sure that microtest knows how many there are.
*/ */
malunal_size_t count; malunal_size_t count;
} microtest_state_t; };
/**
* @brief Type defines a pointer to a mutable microtest state.
* @details This is provided to make function declarations simpler and align the
* naming conventions of other types within our libraries.
*/
typedef microtest_state_t* microtest_state_mptr_t;
/**
* @brief Type defines a pointer to an immutable microtest state.
* @details This is provided to make function declarations simpler and align the
* naming conventions of other types within our libraries.
*/
typedef const microtest_state_t* microtest_state_iptr_t;
static malunal_size_t microtest_ran_count = 0; static malunal_size_t microtest_ran_count = 0;
static malunal_size_t microtest_failed_count = 0; static malunal_size_t microtest_failed_count = 0;
@@ -147,7 +120,12 @@ microtest_abort_inside_test() {
/** /**
* @brief Checks if we should decompose a macro. * @brief Checks if we should decompose a macro.
* @details This is for when we are inside of macro * @details This is for when we are inside of macro. It will help indicate what
* was passed and what will be done.
* @param actual The string of the actual argument.
* @param expected The string of the expected argument.
* @param strcmp Whether to compare the strings.
* @returns Whether we should decompose the macro usage or not.
*/ */
static static
malunal_bool_t malunal_bool_t
@@ -200,7 +178,6 @@ microtest_should_decompose_macro(
#define microtest_printf(...) \ #define microtest_printf(...) \
printf(__VA_ARGS__) printf(__VA_ARGS__)
// TODO: Add float, double, and long double to type.h
#define microtest_overload_printer(value) \ #define microtest_overload_printer(value) \
microtest_printf(_Generic( \ microtest_printf(_Generic( \
(value), \ (value), \
@@ -214,9 +191,8 @@ microtest_should_decompose_macro(
malunal_int16_t : "%hd", \ malunal_int16_t : "%hd", \
malunal_int32_t : "%d", \ malunal_int32_t : "%d", \
malunal_int64_t : "%lld", \ malunal_int64_t : "%lld", \
float : "%f", \ malunal_single_t : "%f", \
double : "%f", \ malunal_double_t : "%f", \
long double : "%Lf", \
malunal_mptr_t : "%p" \ malunal_mptr_t : "%p" \
), (value)) ), (value))
@@ -291,6 +267,31 @@ microtest_should_decompose_macro(
} \ } \
while(0) while(0)
#define MICROTEST_PTRCMP(actual, expected, condition, macro, handler, ...) \
do { \
if(!((malunal_mptr_t)(actual) condition (malunal_mptr_t)(expected))) { \
microtest_printf("%s:%u: ", __FILE__, __LINE__); \
microtest_printf(__VA_ARGS__); \
microtest_printf("\n"); \
if(microtest_should_decompose_macro(#actual, #expected, 0)) { \
microtest_printf(" In macro : "); \
microtest_printf("%s( %s, %s )\n", #macro, #actual, #expected); \
} \
microtest_printf(" Expected : %s", #actual); \
microtest_printf(" %s ", #condition); \
microtest_printf("%p", (malunal_mptr_t)expected); \
microtest_printf("\n"); \
microtest_printf(" Actual : %s", #actual); \
microtest_printf(" == "); \
microtest_printf("%p", (malunal_mptr_t)actual); \
microtest_printf("\n"); \
handler; \
if (microtest_should_abort_test) \
return; \
} \
} \
while(0)
#define MICROTEST_EXPECT_ASSERT(cond, handler, macro, ...) \ #define MICROTEST_EXPECT_ASSERT(cond, handler, macro, ...) \
do { \ do { \
if(!(cond)) { \ if(!(cond)) { \
@@ -317,6 +318,8 @@ microtest_should_decompose_macro(
#define MICROTEST_EXPECT_FALSE_(actual, ...) MICROTEST_COMPARE(actual, false, ==, MICROTEST_EXPECT_FALSE, MICROTEST_FAIL_INSIDE_TEST, __VA_ARGS__) #define MICROTEST_EXPECT_FALSE_(actual, ...) MICROTEST_COMPARE(actual, false, ==, MICROTEST_EXPECT_FALSE, MICROTEST_FAIL_INSIDE_TEST, __VA_ARGS__)
#define MICROTEST_EXPECT_NULL_(actual, ...) MICROTEST_EXPECT_(actual == null, __VA_ARGS__) #define MICROTEST_EXPECT_NULL_(actual, ...) MICROTEST_EXPECT_(actual == null, __VA_ARGS__)
#define MICROTEST_EXPECT_NOT_NULL_(actual, ...) MICROTEST_EXPECT_(actual != null, __VA_ARGS__) #define MICROTEST_EXPECT_NOT_NULL_(actual, ...) MICROTEST_EXPECT_(actual != null, __VA_ARGS__)
#define MICROTEST_EXPECT_PTR_EQ_(actual, expected, ...) MICROTEST_PTRCMP(actual, expected, ==, MICROTEST_EXPECT_PTR_EQ, MICROTEST_FAIL_INSIDE_TEST, __VA_ARGS__)
#define MICROTEST_EXPECT_PTR_NE_(actual, expected, ...) MICROTEST_PTRCMP(actual, expected, !=, MICROTEST_EXPECT_PTR_NE, MICROTEST_FAIL_INSIDE_TEST, __VA_ARGS__)
#define MICROTEST_ASSERT_(cond, ...) MICROTEST_EXPECT_ASSERT(cond, MICROTEST_ABORT_INSIDE_TEST, MICROTEST_ASSERT, __VA_ARGS__) #define MICROTEST_ASSERT_(cond, ...) MICROTEST_EXPECT_ASSERT(cond, MICROTEST_ABORT_INSIDE_TEST, MICROTEST_ASSERT, __VA_ARGS__)
#define MICROTEST_ASSERT_EQ_(actual, expected, ...) MICROTEST_COMPARE(actual, expected, ==, MICROTEST_ASSERT_EQ, MICROTEST_ABORT_INSIDE_TEST, __VA_ARGS__) #define MICROTEST_ASSERT_EQ_(actual, expected, ...) MICROTEST_COMPARE(actual, expected, ==, MICROTEST_ASSERT_EQ, MICROTEST_ABORT_INSIDE_TEST, __VA_ARGS__)
@@ -329,6 +332,8 @@ microtest_should_decompose_macro(
#define MICROTEST_ASSERT_FALSE_(actual, ...) MICROTEST_COMPARE(actual, false, ==, MICROTEST_ASSERT_FALSE, MICROTEST_ABORT_INSIDE_TEST, __VA_ARGS__) #define MICROTEST_ASSERT_FALSE_(actual, ...) MICROTEST_COMPARE(actual, false, ==, MICROTEST_ASSERT_FALSE, MICROTEST_ABORT_INSIDE_TEST, __VA_ARGS__)
#define MICROTEST_ASSERT_NULL_(actual, ...) MICROTEST_ASSERT_(actual == null, __VA_ARGS__) #define MICROTEST_ASSERT_NULL_(actual, ...) MICROTEST_ASSERT_(actual == null, __VA_ARGS__)
#define MICROTEST_ASSERT_NOT_NULL_(actual, ...) MICROTEST_ASSERT_(actual != null, __VA_ARGS__) #define MICROTEST_ASSERT_NOT_NULL_(actual, ...) MICROTEST_ASSERT_(actual != null, __VA_ARGS__)
#define MICROTEST_ASSERT_PTR_EQ_(actual, expected, ...) MICROTEST_PTRCMP(actual, expected, ==, MICROTEST_ASSERT_PTR_EQ, MICROTEST_ABORT_INSIDE_TEST, __VA_ARGS__)
#define MICROTEST_ASSERT_PTR_NE_(actual, expected, ...) MICROTEST_PTRCMP(actual, expected, !=, MICROTEST_ASSERT_PTR_NE, MICROTEST_ABORT_INSIDE_TEST, __VA_ARGS__)
#define MICROTEST_EXPECT(...) FIXED1_CHOOSER(__VA_ARGS__)(MICROTEST_EXPECT, __VA_ARGS__) #define MICROTEST_EXPECT(...) FIXED1_CHOOSER(__VA_ARGS__)(MICROTEST_EXPECT, __VA_ARGS__)
@@ -342,6 +347,8 @@ microtest_should_decompose_macro(
#define MICROTEST_EXPECT_FALSE(...) FIXED1_CHOOSER(__VA_ARGS__)(MICROTEST_EXPECT_FALSE, __VA_ARGS__) #define MICROTEST_EXPECT_FALSE(...) FIXED1_CHOOSER(__VA_ARGS__)(MICROTEST_EXPECT_FALSE, __VA_ARGS__)
#define MICROTEST_EXPECT_NULL(...) FIXED1_CHOOSER(__VA_ARGS__)(MICROTEST_EXPECT_NULL, __VA_ARGS__) #define MICROTEST_EXPECT_NULL(...) FIXED1_CHOOSER(__VA_ARGS__)(MICROTEST_EXPECT_NULL, __VA_ARGS__)
#define MICROTEST_EXPECT_NOT_NULL(...) FIXED1_CHOOSER(__VA_ARGS__)(MICROTEST_EXPECT_NOT_NULL, __VA_ARGS__) #define MICROTEST_EXPECT_NOT_NULL(...) FIXED1_CHOOSER(__VA_ARGS__)(MICROTEST_EXPECT_NOT_NULL, __VA_ARGS__)
#define MICROTEST_EXPECT_PTR_EQ(...) FIXED2_CHOOSER(__VA_ARGS__)(MICROTEST_EXPECT_PTR_EQ, __VA_ARGS__)
#define MICROTEST_EXPECT_PTR_NE(...) FIXED2_CHOOSER(__VA_ARGS__)(MICROTEST_EXPECT_PTR_NE, __VA_ARGS__)
#define MICROTEST_ASSERT(...) FIXED1_CHOOSER(__VA_ARGS__)(MICROTEST_ASSERT, __VA_ARGS__) #define MICROTEST_ASSERT(...) FIXED1_CHOOSER(__VA_ARGS__)(MICROTEST_ASSERT, __VA_ARGS__)
#define MICROTEST_ASSERT_EQ(...) FIXED2_CHOOSER(__VA_ARGS__)(MICROTEST_ASSERT_EQ, __VA_ARGS__) #define MICROTEST_ASSERT_EQ(...) FIXED2_CHOOSER(__VA_ARGS__)(MICROTEST_ASSERT_EQ, __VA_ARGS__)
@@ -354,6 +361,8 @@ microtest_should_decompose_macro(
#define MICROTEST_ASSERT_FALSE(...) FIXED1_CHOOSER(__VA_ARGS__)(MICROTEST_ASSERT_FALSE, __VA_ARGS__) #define MICROTEST_ASSERT_FALSE(...) FIXED1_CHOOSER(__VA_ARGS__)(MICROTEST_ASSERT_FALSE, __VA_ARGS__)
#define MICROTEST_ASSERT_NULL(...) FIXED1_CHOOSER(__VA_ARGS__)(MICROTEST_ASSERT_NULL, __VA_ARGS__) #define MICROTEST_ASSERT_NULL(...) FIXED1_CHOOSER(__VA_ARGS__)(MICROTEST_ASSERT_NULL, __VA_ARGS__)
#define MICROTEST_ASSERT_NOT_NULL(...) FIXED1_CHOOSER(__VA_ARGS__)(MICROTEST_ASSERT_NOT_NULL, __VA_ARGS__) #define MICROTEST_ASSERT_NOT_NULL(...) FIXED1_CHOOSER(__VA_ARGS__)(MICROTEST_ASSERT_NOT_NULL, __VA_ARGS__)
#define MICROTEST_ASSERT_PTR_EQ(...) FIXED2_CHOOSER(__VA_ARGS__)(MICROTEST_ASSERT_PTR_EQ, __VA_ARGS__)
#define MICROTEST_ASSERT_PTR_NE(...) FIXED2_CHOOSER(__VA_ARGS__)(MICROTEST_ASSERT_PTR_NE, __VA_ARGS__)
/** /**
@@ -503,11 +512,11 @@ microtest_run_tests() {
microtest_failed_suites[failed] = index; microtest_failed_suites[failed] = index;
microtest_failed_count++; microtest_failed_count++;
printf("[ FAILED ]"); printf("[ FAILED ] ");
printf("%s (", microtest_context.tests[index].name); printf("%s (", microtest_context.tests[index].name);
printf(")\n"); printf(")\n");
} else { } else {
printf("[ OK ]"); printf("[ OK ] ");
printf("%s (", microtest_context.tests[index].name); printf("%s (", microtest_context.tests[index].name);
printf(")\n"); printf(")\n");
} }