diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 655376c5..0f79ef5f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,9 +14,10 @@ - [4.3.3 The use of GNU extensions](#the-use-of-gnu-extensions) - [4.3.4 Naming Conventions](#naming-conventions) - [5. Commit Messages](#commit-messages) -- [6. Submitting Patches](#submitting-patches) -- [7. Native Language Support](#native-language-support) -- [8. Upversion](#upversion) +- [6. Unit Tests](#unit-tests) +- [7. Submitting Patches](#submitting-patches) +- [8. Native Language Support](#native-language-support) +- [9. Upversion](#upversion) # How to Contribute @@ -345,6 +346,29 @@ This first line should: And please wrap the commit message at max 74 characters, otherwise `git log` and similar look so weird. URLs and other references are exempt. +# Unit Tests + +## Introduction + +The tests live in the `t/` directory. + +In the bigger scheme of validating that the compositor meets users' needs, unit +tests do not contribute a great deal. However, they have a role to play in +providing some verification that stand-alone functions behave as expected. + +On this project, writing unit-tests is not compulsory nor do we measure +coverage. The inclusion of the t/ directory does not signifiy a move towards +test-driven development. We intend to use unit tests sparingly and only when +devs find them useful. + +## Usage + +From repo top level directory: + + meson setup -Dtest=enabled build + meson compile -C build/ + meson test --verbose -C build/ + # Submitting patches Base both bugfixes and new features on `master`. diff --git a/meson.build b/meson.build index 4761fbc9..8f9b5a97 100644 --- a/meson.build +++ b/meson.build @@ -130,6 +130,11 @@ subdir('include') subdir('src') subdir('docs') +dep_cmocka = dependency('cmocka', required: get_option('test')) +if dep_cmocka.found() + subdir('t') +endif + executable( meson.project_name(), labwc_sources, diff --git a/meson_options.txt b/meson_options.txt index d9cb73a8..4d6e8cd5 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -3,3 +3,4 @@ option('xwayland', type: 'feature', value: 'auto', description: 'Enable support option('svg', type: 'feature', value: 'enabled', description: 'Enable svg window buttons') option('nls', type: 'feature', value: 'auto', description: 'Enable native language support') option('static_analyzer', type: 'feature', value: 'disabled', description: 'Run gcc static analyzer') +option('test', type: 'feature', value: 'disabled', description: 'Run tests') diff --git a/t/.gitignore b/t/.gitignore new file mode 100644 index 00000000..a8d6b6c1 --- /dev/null +++ b/t/.gitignore @@ -0,0 +1 @@ +*.t diff --git a/t/buf-simple.c b/t/buf-simple.c new file mode 100644 index 00000000..47722116 --- /dev/null +++ b/t/buf-simple.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define _POSIX_C_SOURCE 200809L +#include +#include +#include +#include +#include +#include +#include "common/buf.h" +#include "common/mem.h" + +static void +test_expand_title(void **state) +{ + (void)state; + + struct buf s = BUF_INIT; + + char TEMPLATE[] = "foo ~/bar"; + char expect[4096]; + snprintf(expect, sizeof(expect), "foo %s/bar", getenv("HOME")); + + buf_add(&s, TEMPLATE); + assert_string_equal(s.data, TEMPLATE); + assert_int_equal(s.len, strlen(TEMPLATE)); + + // Resolve ~ + buf_expand_tilde(&s); + assert_string_equal(s.data, expect); + assert_int_equal(s.len, strlen(expect)); + + setenv("bar", "BAR", 1); + + // Resolve $bar and ${bar} + s.len = 0; + buf_add(&s, "foo $bar baz"); + buf_expand_shell_variables(&s); + assert_string_equal(s.data, "foo BAR baz"); + assert_int_equal(s.len, 11); + + s.len = 0; + buf_add(&s, "foo ${bar} baz"); + buf_expand_shell_variables(&s); + assert_string_equal(s.data, "foo BAR baz"); + assert_int_equal(s.len, 11); + + // Don't resolve $() + s.len = 0; + buf_add(&s, "foo $(bar) baz"); + buf_expand_shell_variables(&s); + assert_string_equal(s.data, "foo $(bar) baz"); + assert_int_equal(s.len, 14); + + unsetenv("bar"); + free(s.data); +} + +int main(int argc, char **argv) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_expand_title), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/t/meson.build b/t/meson.build new file mode 100644 index 00000000..5517b973 --- /dev/null +++ b/t/meson.build @@ -0,0 +1,27 @@ +test_lib = static_library( + 'test_lib', + sources: files( + '../src/common/buf.c', + '../src/common/mem.c', + '../src/common/string-helpers.c' + ), + include_directories: [labwc_inc], + dependencies: [dep_cmocka], +) + +tests = [ + 'buf-simple', +] + +foreach t : tests + test( + 'test_@0@'.format(t), + executable( + 'test_@0@'.format(t), + sources: '@0@.c'.format(t), + include_directories: [labwc_inc], + link_with: [test_lib], + ), + is_parallel: false, + ) +endforeach