From e1c3bdc6f2658e5c0f3bf128000f3dc1dc7f88bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 27 Nov 2021 17:23:33 +0100 Subject: [PATCH] =?UTF-8?q?test:=20initial=20external=20unit=20test=20suit?= =?UTF-8?q?e=20for=20=E2=80=98config.c=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds a separate (external) test binary with unit tests for config.c This is achieved by having the test’s source file include config.c (yes, the C file, not the header file). This allows us to call e.g. parse_section_*() directly, without having to go through config_load() (which requires having a readable file at “path”). --- meson.build | 1 + tests/meson.build | 8 ++++ tests/test-config.c | 93 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 tests/meson.build create mode 100644 tests/test-config.c diff --git a/meson.build b/meson.build index 9faaf44b..39237a33 100644 --- a/meson.build +++ b/meson.build @@ -272,6 +272,7 @@ endif subdir('completions') subdir('icons') +subdir('tests') summary( { diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 00000000..8618bf04 --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,8 @@ +config_test = executable( + 'test-config', + 'test-config.c', '../tokenize.c', + wl_proto_headers, + link_with: [common], + dependencies: [pixman, xkb, fcft]) + +test('config', config_test) diff --git a/tests/test-config.c b/tests/test-config.c new file mode 100644 index 00000000..d8ef32f1 --- /dev/null +++ b/tests/test-config.c @@ -0,0 +1,93 @@ +#if !defined(_DEBUG) + #define _DEBUG +#endif +#undef NDEBUG + +#include "../log.h" + +#include "../config.c" + +#define ALEN(v) (sizeof(v) / sizeof((v)[0])) + +/* + * Stubs + */ + +void +user_notification_add_fmt(user_notifications_t *notifications, + enum user_notification_kind kind, + const char *fmt, ...) +{ +} + +static void +test_boolean(struct context *ctx, bool (*parse_fun)(struct context *ctx), + const char *key, bool *conf_ptr) +{ + ctx->key = key; + + static const struct { + const char *option_string; + bool value; + bool invalid; + } input[] = { + {"1", true}, {"0", false}, + {"on", true}, {"off", false}, + {"true", true}, {"false", false}, + {"unittest-invalid-boolean-value", false, true}, + }; + + for (size_t i = 0; i < ALEN(input); i++) { + ctx->value = input[i].option_string; + + if (input[i].invalid) { + if (parse_fun(ctx)) { + BUG("[%s].%s=%s: did not fail to parse as expected", + ctx->section, ctx->key, ctx->value); + } + } else { + if (!parse_fun(ctx)) { + BUG("[%s].%s=%s: failed to parse", + ctx->section, ctx->key, ctx->value); + } + if (*conf_ptr != input[i].value) + BUG("[%s].%s=%s: set value (%s) not the expected one (%s)", + ctx->section, ctx->key, ctx->value, + *conf_ptr ? "true" : "false", + input[i].value ? "true" : "false"); + } + } +} + +static void +test_section_main(void) +{ +#define CTX(_key, _value) \ + (struct context){ \ + .conf = &conf, .section = "main", .key = _key, .value = _value, .path = "unittest"} + + struct config conf = {0}; + struct context ctx; + + ctx = CTX("shell", "/bin/bash"); + xassert(parse_section_main(&ctx)); + xassert(strcmp(conf.shell, "/bin/bash") == 0); + + ctx = CTX("term", "foot-unittest"); + xassert(parse_section_main(&ctx)); + xassert(strcmp(conf.term, "foot-unittest") == 0); + + test_boolean(&ctx, &parse_section_main, "login-shell", &conf.login_shell); + + config_free(conf); +#undef CTX +} + +int +main(int argc, const char *const *argv) +{ + log_init(LOG_COLORIZE_AUTO, false, 0, LOG_CLASS_ERROR); + test_section_main(); + log_deinit(); + return 0; +}