feat(list): update test and pipeline
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing

This commit is contained in:
Rick Barenthin 2022-05-20 13:41:15 +02:00
parent 8b1e56a25d
commit 629435626e
4 changed files with 206 additions and 47 deletions

View File

@ -35,10 +35,10 @@ steps:
- name: Run tests - name: Run tests
image: registry.riba-interactive.de/alpine-build:1 image: registry.riba-interactive.de/alpine-build:1
commands: commands:
- cmake -S. -Bbuild - cmake -S. -Bcmake-build-ci -DCMAKE_BUILD_TYPE=Debug -DENABLE_TEST_COVERAGE=on
- cd build - cd cmake-build-ci
- cmake --build . - cmake --build .
- ctest - ctest -T Test -T Coverage
trigger: trigger:
branch: branch:

164
tests/bdd-for-c-ext.h Normal file
View File

@ -0,0 +1,164 @@
//
// 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

View File

@ -664,7 +664,7 @@ for(\
#define __BDD_CHECK_ONE__(condition) __BDD_CHECK__(condition, #condition) #define __BDD_CHECK_ONE__(condition) __BDD_CHECK__(condition, #condition)
#define check(...) __BDD_MACRO__(__BDD_CHECK_, __VA_ARGS__) #define check(...) do { __BDD_MACRO__(__BDD_CHECK_, __VA_ARGS__) } while (0)
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)

View File

@ -7,7 +7,7 @@
#include "waitui/list.h" #include "waitui/list.h"
#include "../../bdd-for-c.h" #include "../../bdd-for-c-ext.h"
typedef struct value { typedef struct value {
int count; int count;
@ -31,54 +31,49 @@ CREATE_LIST_TYPE(INTERFACE, value)
CREATE_LIST_TYPE(IMPLEMENTATION, value) CREATE_LIST_TYPE(IMPLEMENTATION, value)
spec("list") { spec("list") {
context("use as a stack") { context("use as a normal list") {
static value_list *stack = NULL; static value_list *list = NULL;
before() { stack = value_list_new(); } before_each() {
list = value_list_new();
after() { value_list_destroy(&stack); } check(list != NULL, "list should not be NULL");
it("should have a stack") {
check(stack != NULL, "stack should not be NULL");
} }
it("should allow to push a value onto the stack") { after_each() {
value *value1 = value_new(1); value_list_destroy(&list);
check(value1 != NULL, "value1 should not be NULL"); check(list == NULL, "list should be NULL");
check(value_list_push(stack, value1) == true,
"value1 should be added to the stack");
} }
it("should allow to push a second value onto the stack") { describe("value_list_push()") {
value *value2 = value_new(2); for_it(
check(value2 != NULL, "value2 should not be NULL"); "should push values onto the end list and it should be there",
check(value_list_push(stack, value2) == true, params_format(2, "start: %d", "elements: %d"),
"value1 should be added to the stack"); format_args(test_param.start, test_param.count),
} {
int start;
int count;
},
test_params(
{0, 0},
{0, 1},
{1, 1},
{4, 20},
)
) {
for (int i = test_param.start; i < test_param.start + test_param.count; ++i) {
check(value_list_push(list, value_new(i)) == 1);
value *value = value_list_peek(list);
check(value->i == i, "value should be %d but is %d", i, value->i);
}
it("should return the last added element on pop") { for (int i = test_param.start + test_param.count - 1; i >= test_param.start; --i) {
value *test = value_list_pop(stack); value *value = value_list_pop(list);
check(test != NULL, "value_list_pop should not return NULL"); check(value != NULL, "value should not be NULL");
check(test->i == 2, "test should be 2"); check(value->i == i, "value should be %d but is %d", i, value->i);
value_destroy(&test); value_destroy(&value);
} }
}
it("should be able to peek the top element") { for_it_end();
value *test = value_list_peek(stack);
check(test != NULL, "value_list_peek should not return NULL");
check(test->i == 1, "test should be 1");
}
it("should return the first added element on pop") {
value *test = value_list_pop(stack);
check(test != NULL, "value_list_pop should not return NULL");
check(test->i == 1, "test should be 1");
value_destroy(&test);
}
it("should return NULL if peek with an empty stack") {
value *test = value_list_peek(stack);
check(test == NULL, "value_list_peek should return NULL");
} }
} }
} }