All checks were successful
continuous-integration/drone/push Build is passing
This pull request adds a list implementation that can be used in a generic way and adds everything that might be needed in later implementation of other data structurs. Reviewed-on: #1 PR #1
165 lines
5.9 KiB
C
165 lines
5.9 KiB
C
//
|
|
// Created by Rick Barenthin on 09.02.22.
|
|
//
|
|
|
|
#ifndef WAITUI_BDD_FOR_C_EXT_H
|
|
#define WAITUI_BDD_FOR_C_EXT_H
|
|
|
|
#include "bdd-for-c.h"
|
|
|
|
#define __BDD_EXT_1ST_PARAM_FMT__ "'%s'"
|
|
#define __BDD_EXT_OTHER_PARAM_FMT__ ", '%s'"
|
|
|
|
/**
|
|
* Create the format based on the count passed.
|
|
* @param num The number of format string parameters
|
|
* @return
|
|
*/
|
|
static inline char *__bdd_ext_build_format__(int num) {
|
|
size_t length = (sizeof(__BDD_EXT_1ST_PARAM_FMT__) - 1) +
|
|
(num - 1) * (sizeof(__BDD_EXT_OTHER_PARAM_FMT__) - 1) + 1;
|
|
char *fmt = calloc(length, sizeof(*fmt));
|
|
if (!fmt) {
|
|
perror("calloc(__bdd_ext_build_format__)");
|
|
abort();
|
|
}
|
|
|
|
for (int i = 0; i < num; i++) {
|
|
if (i != 0) {
|
|
strcat(fmt, __BDD_EXT_OTHER_PARAM_FMT__);
|
|
} else {
|
|
strcat(fmt, __BDD_EXT_1ST_PARAM_FMT__);
|
|
}
|
|
}
|
|
|
|
return fmt;
|
|
}
|
|
|
|
/**
|
|
* Create a format string from a test description and format parameters.
|
|
*
|
|
* @param description The description of the test case
|
|
* @param num The number of format string parameters
|
|
* @param ... The format string parameters a comma
|
|
* separated arguments
|
|
* @return The created format string
|
|
*/
|
|
static inline char *__bdd_ext_format_string_params__(const char *description,
|
|
int num, ...) {
|
|
va_list args;
|
|
va_list copy;
|
|
|
|
int length = 1;
|
|
int written = 0;
|
|
char *fmt_string = NULL;
|
|
char *fmt = __bdd_ext_build_format__(num);
|
|
|
|
va_start(args, num);
|
|
va_copy(copy, args);
|
|
length += snprintf(NULL, 0, "%s [", description);
|
|
length += vsnprintf(NULL, 0, fmt, copy);
|
|
length += snprintf(NULL, 0, "]");
|
|
fmt_string = calloc(length, sizeof(*fmt_string));
|
|
if (!fmt_string) {
|
|
perror("calloc(__bdd_ext_format_string_params__)");
|
|
abort();
|
|
}
|
|
va_end(copy);
|
|
written += snprintf(fmt_string, length, "%s [", description);
|
|
written += vsnprintf(fmt_string + written, length - written, fmt, args);
|
|
written += snprintf(fmt_string + written, length - written, "]");
|
|
va_end(args);
|
|
|
|
free(fmt);
|
|
|
|
return fmt_string;
|
|
}
|
|
|
|
|
|
/**
|
|
* Create an array of `#test_param` structs.
|
|
*
|
|
* @note This macro must be used for passing test parameters to `for_it()`.
|
|
* @example: test_params({"input", "expected"}, {"input1", "expected1"})
|
|
*/
|
|
#define test_params(...) \
|
|
{ __VA_ARGS__ }
|
|
|
|
/**
|
|
* Define arguments for a format string as one macro argument.
|
|
*
|
|
* @note This macro must be used for passing test parameters to `for_it()`.
|
|
* @example: format_args(STR_FMT(&string), STR_FMT(&string1));
|
|
*/
|
|
#define format_args(...) __VA_ARGS__
|
|
|
|
/**
|
|
* Define arguments for a format string as one macro argument.
|
|
*
|
|
* The first argument must be the number of format string parameters.
|
|
*
|
|
* @example: params_format(1, "%s", "%d");
|
|
*/
|
|
#define params_format(...) __VA_ARGS__
|
|
|
|
/**
|
|
* Create a parametrized test case.
|
|
*
|
|
* Each test parameter results in an isolated test case which is
|
|
* executed independently and has its own output showing the test
|
|
* description followed by the given test parameters.
|
|
*
|
|
* @note: The given test parameters can be accessed by `#test_param`.
|
|
* @note: You must call `for_it_end()` after the test code to free
|
|
* allocated memory.
|
|
*
|
|
* @example: for_it("returns 1 and sets claim on existing claim",
|
|
* params_format(2, "%s", "%d"),
|
|
* format_args(test_param.input, test_param.expected),
|
|
* { char *input; int expected; },
|
|
* test_params(
|
|
* {"test input 1", 0},
|
|
* {"test input 2", 1},
|
|
* {"test input 4", 2},
|
|
* {"test input 5", 3}
|
|
* )
|
|
* )
|
|
*
|
|
* @param description: The description of the test
|
|
* @param params_format: A format string for printing the parameters
|
|
* of a test. Use `params_format()` macro for
|
|
* format creation.
|
|
* @param format_args: The arguments for the parameter format. Use
|
|
* `format_args()` macro for arguments creation.
|
|
* @param param_struct_body: The struct to be created holding the test
|
|
* parameters.
|
|
* @param params: The test parameters to be used
|
|
*/
|
|
#define for_it(description, params_format, format_args, param_struct_body, \
|
|
params) \
|
|
do { \
|
|
struct __bdd_ext_test_param__ param_struct_body \
|
|
__bdd_ext_test_params__[] = params; \
|
|
int __bdd_ext_input_size__ = sizeof(__bdd_ext_test_params__) / \
|
|
sizeof(__bdd_ext_test_params__[0]); \
|
|
for (int __bdd_ext_i__ = 0; __bdd_ext_i__ < __bdd_ext_input_size__; \
|
|
__bdd_ext_i__++) { \
|
|
struct __bdd_ext_test_param__ test_param = \
|
|
__bdd_ext_test_params__[__bdd_ext_i__]; \
|
|
char *__bdd_ext_param_format_string__ = \
|
|
__bdd_ext_format_string_params__(description, \
|
|
params_format); \
|
|
it(__bdd_ext_param_format_string__, format_args) {
|
|
|
|
/**
|
|
* End a parametrized test and free all resources allocated in #for_it.
|
|
*/
|
|
#define for_it_end() \
|
|
} \
|
|
free(__bdd_ext_param_format_string__); \
|
|
} \
|
|
} \
|
|
while (0)
|
|
|
|
#endif//WAITUI_BDD_FOR_C_EXT_H
|