122 lines
5.7 KiB
C
122 lines
5.7 KiB
C
/**
|
|
* @copyright (c) 2024-2025, MacRsh
|
|
*
|
|
* @license SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* @date 2024-09-06 MacRsh First version
|
|
*/
|
|
|
|
#ifndef __MR_TEST_CHECK_H__
|
|
#define __MR_TEST_CHECK_H__
|
|
|
|
#include <mr_config.h>
|
|
#if defined(MR_USE_TEST)
|
|
#include <mr-X/mr_printf.h>
|
|
#include <libc/mr_types.h>
|
|
#endif /* defined(MR_USE_TEST) */
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif /* __cplusplus */
|
|
|
|
/**
|
|
* @addtogroup Test
|
|
* @{
|
|
*/
|
|
|
|
#if defined(MR_USE_TEST)
|
|
/* External test status */
|
|
extern mr_uint32_t __mr_test_status;
|
|
|
|
/* Test pass magic number definition */
|
|
#define __MR_TEST_MAGIC_PASS (0x70617373U)
|
|
|
|
/* Test printf macro definition */
|
|
#define __MR_TEST_PRINTF(_desc, _a_str, _a, _b_str, _b, _fmt) \
|
|
do { \
|
|
mr_printf("%s:%d\n", __FILE__, __LINE__); \
|
|
mr_printf("Expectation failed: %s\n", _desc); \
|
|
mr_printf(" %s = "_fmt \
|
|
"\n", \
|
|
(_a_str), (_a)); \
|
|
mr_printf(" %s = "_fmt \
|
|
"\n", \
|
|
(_b_str), (_b)); \
|
|
} while (0)
|
|
|
|
/* Test check macro definition */
|
|
#define __MR_TEST_CHECK(_a, _cond, _b, _type, _fmt) \
|
|
do { \
|
|
_type __a = (_type)(_a); \
|
|
_type __b = (_type)(_b); \
|
|
if (!(__a _cond __b)) { \
|
|
__MR_TEST_PRINTF(#_a " " #_cond " " #_b, #_a, __a, #_b, __b, \
|
|
_fmt); \
|
|
__mr_test_status = ~__MR_TEST_MAGIC_PASS; \
|
|
} \
|
|
} while (0)
|
|
#define __MR_TEST_CHECK_NEAR(_a, _b, _e, _type, _fmt) \
|
|
do { \
|
|
_type __a = (_type)(_a); \
|
|
_type __b = (_type)(_b); \
|
|
_type __e = (_type)(_e); \
|
|
_type __c = (__a > __b) ? (__a - __b) : (__b - __a); \
|
|
if (!(__c <= __e)) { \
|
|
__MR_TEST_PRINTF("| " #_a " - " #_b " | <= " #_e, #_a, __a, #_b, \
|
|
__b, _fmt); \
|
|
__mr_test_status = ~__MR_TEST_MAGIC_PASS; \
|
|
} \
|
|
} while (0)
|
|
|
|
/* Test check macros definition */
|
|
#define __MR_TEST_EQ(_a, _b, _type, _fmt) \
|
|
__MR_TEST_CHECK(_a, ==, _b, _type, _fmt)
|
|
#define __MR_TEST_NE(_a, _b, _type, _fmt) \
|
|
__MR_TEST_CHECK(_a, !=, _b, _type, _fmt)
|
|
#define __MR_TEST_LT(_a, _b, _type, _fmt) \
|
|
__MR_TEST_CHECK(_a, <, _b, _type, _fmt)
|
|
#define __MR_TEST_LE(_a, _b, _type, _fmt) \
|
|
__MR_TEST_CHECK(_a, <=, _b, _type, _fmt)
|
|
#define __MR_TEST_GT(_a, _b, _type, _fmt) \
|
|
__MR_TEST_CHECK(_a, >, _b, _type, _fmt)
|
|
#define __MR_TEST_GE(_a, _b, _type, _fmt) \
|
|
__MR_TEST_CHECK(_a, >=, _b, _type, _fmt)
|
|
#define __MR_TEST_NEAR(_a, _b, _e, _type, _fmt) \
|
|
__MR_TEST_CHECK_NEAR(_a, _b, _e, _type, _fmt)
|
|
|
|
/* Test condition macros definition */
|
|
#define __MR_TEST_COND_INT(_a, _cond, _b) \
|
|
__MR_TEST_##_cond(_a, _b, mr_int64_t, "%lld")
|
|
#define __MR_TEST_COND_UINT(_a, _cond, _b) \
|
|
__MR_TEST_##_cond(_a, _b, mr_uint64_t, "%llu")
|
|
#define __MR_TEST_COND_PTR(_a, _cond, _b) \
|
|
__MR_TEST_##_cond(_a, _b, mr_ptr_t, "%p")
|
|
#define __MR_TEST_COND_FLOAT(_a, _cond, _b) \
|
|
__MR_TEST_##_cond(_a, _b, mr_f32_t, "%f")
|
|
#define __MR_TEST_COND_DOUBLE(_a, _cond, _b) \
|
|
__MR_TEST_##_cond(_a, _b, mr_f64_t, "%lf")
|
|
#define __MR_TEST_COND_NEAR(_a, _b, _e) \
|
|
__MR_TEST_NEAR(_a, _b, _e, mr_f64_t, "%lf")
|
|
|
|
/* Test expect and assert macros definition */
|
|
#define __MR_TEST_EXPECT(_check) _check
|
|
#define __MR_TEST_ASSERT(_check) \
|
|
do { \
|
|
mr_uint32_t __s = __mr_test_status; \
|
|
__mr_test_status = __MR_TEST_MAGIC_PASS; \
|
|
_check; \
|
|
if (__mr_test_status == (~__MR_TEST_MAGIC_PASS)) { \
|
|
return; \
|
|
} \
|
|
__mr_test_status = __s; \
|
|
} while (0)
|
|
#endif /* defined(MR_USE_TEST) */
|
|
|
|
/** @} */
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif /* __cplusplus */
|
|
|
|
#endif /* __MR_TEST_CHECK_H__ */
|