Affix
view release on metacpan or search on metacpan
infix/src/common/double_tap.h view on Meta::CPAN
#define DBLTAP_NOINLINE __attribute__((noinline))
#elif defined(_MSC_VER)
#define DBLTAP_NOINLINE __declspec(noinline)
#else
#define DBLTAP_NOINLINE
#endif
// Compiler-specific attribute for printf-style format checking.
#if defined(__GNUC__) || defined(__clang__)
#define DBLTAP_PRINTF_FORMAT(fmt_index, arg_index) __attribute__((format(printf, fmt_index, arg_index)))
#else
#define DBLTAP_PRINTF_FORMAT(fmt_index, arg_index)
#endif
// Public Test Harness Functions (wrapped by macros for convenience)
void tap_init(void);
void tap_plan(size_t count);
int tap_done(void);
void tap_bail_out(const char * reason, ...) DBLTAP_PRINTF_FORMAT(1, 2);
bool tap_ok(bool condition, const char * file, int line, const char * func, const char * expr, const char * name, ...)
DBLTAP_PRINTF_FORMAT(6, 7);
bool tap_subtest_start(const char * name);
bool tap_subtest_end(void);
void tap_todo_start(const char * reason, ...) DBLTAP_PRINTF_FORMAT(1, 2);
void tap_todo_end(void);
void tap_skip(size_t count, const char * reason, ...) DBLTAP_PRINTF_FORMAT(2, 3);
void tap_skip_all(const char * reason, ...) DBLTAP_PRINTF_FORMAT(1, 2);
void diag(const char * fmt, ...) DBLTAP_PRINTF_FORMAT(1, 2);
void tap_note(const char * fmt, ...) DBLTAP_PRINTF_FORMAT(1, 2);
void test_body(void);
#ifdef __cplusplus
}
#endif
// Public Test Harness Macros
/** @brief Declares the total number of tests to be run in the current scope. Must be called before any tests. */
#define plan(count) tap_plan(count)
/** @brief Concludes testing, validates the plan, and returns an exit code based on success or failure. */
#define done() tap_done()
/** @brief Immediately terminates the entire test suite with a failure message. Useful for fatal setup errors. */
#define bail_out(...) tap_bail_out(__VA_ARGS__)
/** @brief The core assertion macro. Checks a condition and prints an "ok" or "not ok" TAP line with diagnostics on
* failure. */
#define ok(cond, ...) tap_ok(!!(cond), __FILE__, __LINE__, __func__, #cond, __VA_ARGS__)
/** @brief A convenience macro that always passes. Equivalent to `ok(true, ...)`. */
#define pass(...) ok(true, __VA_ARGS__)
/** @brief A convenience macro that always fails. Equivalent to `ok(false, ...)`. */
#define fail(...) ok(false, __VA_ARGS__)
/** @brief Defines a block of tests as a nested subtest, which gets its own plan and pass/fail status. */
#define subtest(name) \
for (bool _tap_subtest_once = tap_subtest_start(name); _tap_subtest_once; _tap_subtest_once = tap_subtest_end())
/** @brief Marks a specified number of subsequent tests as skipped with a given reason. */
#define skip(count, ...) tap_skip(count, __VA_ARGS__)
/** @brief Marks all subsequent tests in the current scope as skipped. */
#define skip_all(...) tap_skip_all(__VA_ARGS__)
/** @brief Defines a block of tests that are expected to fail. A failure in a TODO block does not fail the overall
* suite. */
#define TODO(reason) \
for (int _tap_todo_once = (tap_todo_start(reason), 1); _tap_todo_once; _tap_todo_once = (tap_todo_end(), 0))
/** @brief Prints a diagnostic message to stderr, prefixed with '#'. Standard TAP practice for auxiliary information. */
#define diag(...) diag(__VA_ARGS__)
/** @brief Prints a diagnostic message (a note) to stdout, prefixed with '#'. */
#ifndef note
#define note(...) tap_note(__VA_ARGS__)
#endif
/** @brief Defines the main test function body where all tests are written. */
#ifdef __cplusplus
#define TEST extern "C" void test_body(void)
#else
#define TEST void test_body(void)
#endif
#else // If DBLTAP_ENABLE is not defined, provide stub macros to allow code to compile without the harness.
#define plan(count) ((void)0)
#define done() (0)
#define bail_out(...) \
do { \
fprintf(stderr, "Bail out! "); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
exit(1); \
} while (0)
#define ok(cond, ...) (true)
#define pass(...) ((void)0)
#define fail(...) ((void)0)
#define subtest(name) if (0)
#define skip(count, ...) ((void)0)
#define skip_all(...) ((void)0)
#define TODO(reason, ...) if (0)
#define diag(...) ((void)0)
#ifndef note
#define note(...) ((void)0)
#endif
#define TEST \
int main(void) { return 0; }
#endif // DBLTAP_ENABLE
#if defined(DBLTAP_ENABLE) && defined(DBLTAP_IMPLEMENTATION)
// Internal Test State Management
/**
* @internal
* @brief Holds the complete state for a single test scope (main test or a subtest).
*
* A stack of these structs is maintained in thread-local storage to allow for
* nested subtests and concurrent test execution across threads.
*/
typedef struct {
size_t plan; /**< The number of planned tests for this scope. */
size_t count; /**< The number of tests executed so far. */
size_t failed; /**< The number of failed tests in this scope. */
size_t failed_todo; /**< The number of failed tests within a TODO block. */
int indent_level; /**< The nesting level for indented TAP output. */
bool has_plan; /**< `true` if a plan has been declared for this scope. */
bool skipping; /**< `true` if `skip_all` is active for this scope. */
bool todo; /**< `true` if inside a `TODO` block. */
char subtest_name[256]; /**< The name of the current subtest. */
char todo_reason[256]; /**< The reason for the current `TODO` block. */
char skip_reason[256]; /**< The reason for the current `skip_all`. */
} tap_state_t;
#define MAX_DEPTH 16 /**< Maximum nesting depth for subtests. */
#define NO_PLAN ((size_t)-1) /**< Sentinel value for an undeclared plan. */
/** @internal The thread-local stack of test states. */
static TAP_THREAD_LOCAL tap_state_t state_stack[MAX_DEPTH];
/** @internal A pointer to the current test state on the thread-local stack. */
static TAP_THREAD_LOCAL tap_state_t * current_state = NULL;
/** @internal A global, thread-safe counter for the total number of failed tests across all threads. */
static TAP_ATOMIC_SIZE_T g_total_failed TAP_ATOMIC_INIT(0);
// One-Time Initialization for TAP Header
#if defined(_WIN32) || defined(__CYGWIN__)
static INIT_ONCE g_tap_init_once = INIT_ONCE_STATIC_INIT;
static BOOL CALLBACK _tap_init_routine(PINIT_ONCE initOnce, PVOID param, PVOID * context) {
(void)initOnce;
(void)param;
(void)context;
printf("TAP version %d\n", TAP_VERSION);
fflush(stdout);
return TRUE;
infix/src/common/double_tap.h view on Meta::CPAN
fprintf(stdout, "# file: %s\n", file);
print_indent(stdout);
fprintf(stdout, "# line: %d\n", line);
print_indent(stdout);
fprintf(stdout, "# function: %s\n", func);
print_indent(stdout);
fprintf(stdout, "# expression: '%s'\n", expr);
print_indent(stdout);
fprintf(stdout, "# ...\n");
}
fflush(stdout);
return condition;
}
void tap_skip(size_t count, const char * reason, ...) {
_tap_ensure_initialized();
char buffer[256];
va_list args;
va_start(args, reason);
vsnprintf(buffer, sizeof(buffer), reason, args);
va_end(args);
for (size_t i = 0; i < count; ++i) {
current_state->count++;
print_indent(stdout);
printf("ok %llu # SKIP %s\n", (unsigned long long)current_state->count, buffer);
}
fflush(stdout);
}
void tap_skip_all(const char * reason, ...) {
_tap_ensure_initialized();
current_state->skipping = true;
va_list args;
va_start(args, reason);
vsnprintf(current_state->skip_reason, sizeof(current_state->skip_reason), reason, args);
va_end(args);
}
void tap_todo_start(const char * reason, ...) {
_tap_ensure_initialized();
current_state->todo = true;
va_list args;
va_start(args, reason);
vsnprintf(current_state->todo_reason, sizeof(current_state->todo_reason), reason, args);
va_end(args);
}
void tap_todo_end(void) {
_tap_ensure_initialized();
current_state->todo = false;
current_state->todo_reason[0] = '\0';
}
void diag(const char * fmt, ...) {
_tap_ensure_initialized();
char buffer[1024];
va_list args;
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
print_indent(stderr);
fprintf(stderr, "# %s\n", buffer);
fflush(stderr);
}
void tap_note(const char * fmt, ...) {
_tap_ensure_initialized();
char buffer[1024];
va_list args;
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
print_indent(stdout);
fprintf(stdout, "# %s\n", buffer);
fflush(stdout);
}
void tap_bail_out(const char * reason, ...) {
fprintf(stderr, "Bail out! ");
va_list args;
va_start(args, reason);
vfprintf(stderr, reason, args);
va_end(args);
fprintf(stderr, "\n");
fflush(stderr);
exit(1);
}
bool tap_subtest_start(const char * name) {
_tap_ensure_initialized();
print_indent(stdout);
fprintf(stdout, "# Subtest: %s\n", name);
fflush(stdout);
push_state();
snprintf(current_state->subtest_name, sizeof(current_state->subtest_name), "%s", name);
return true; // Enters the `for` loop body.
}
bool tap_subtest_end(void) {
_tap_ensure_initialized();
if (!current_state->has_plan) {
// If no plan was declared, implicitly plan for the number of tests that ran.
current_state->plan = current_state->count;
print_indent(stdout);
printf("1..%llu\n", (unsigned long long)current_state->plan);
}
bool plan_ok = (current_state->plan == current_state->count);
bool subtest_ok = (current_state->failed == 0) && plan_ok;
char name_buffer[256];
snprintf(name_buffer, sizeof(name_buffer), "%s", current_state->subtest_name);
pop_state(); // Return to the parent's state.
// Report the subtest's success or failure as a single test point in the parent scope.
ok(subtest_ok, "%s", name_buffer);
return false; // Exits the `for` loop.
}
int tap_done(void) {
_tap_ensure_initialized();
if (current_state != &state_stack[0])
tap_bail_out("tap_done() called inside a subtest");
if (!current_state->has_plan) {
current_state->plan = current_state->count;
print_indent(stdout);
printf("1..%llu\n", (unsigned long long)current_state->plan);
fflush(stdout);
}
if (current_state->skipping) {
print_indent(stdout);
printf("1..%llu # SKIP %s\n", (unsigned long long)current_state->plan, current_state->skip_reason);
fflush(stdout);
return 0;
}
if (current_state->plan != current_state->count)
fail("Test plan adherence (planned %llu, but ran %llu)",
(unsigned long long)current_state->plan,
(unsigned long long)current_state->count);
size_t final_failed_count = (size_t)TAP_ATOMIC_FETCH_ADD(&g_total_failed, 0);
if (final_failed_count > 0)
diag("Looks like you failed %llu out of %llu tests.",
(unsigned long long)final_failed_count,
(unsigned long long)current_state->plan);
return (int)final_failed_count;
}
// The main test runner that gets compiled into the test executable.
( run in 2.742 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )