summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/.clang-tidy1
-rw-r--r--test/meson.build1
-rw-r--r--test/test_environment.c140
3 files changed, 142 insertions, 0 deletions
diff --git a/test/.clang-tidy b/test/.clang-tidy
index f869db0..401b1b0 100644
--- a/test/.clang-tidy
+++ b/test/.clang-tidy
@@ -9,6 +9,7 @@ Checks: >
-bugprone-multi-level-implicit-pointer-conversion,
-cert-err33-c,
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
+ -concurrency-mt-unsafe,
-cppcoreguidelines-avoid-non-const-global-variables,
-google-readability-casting,
-llvm-header-guard,
diff --git a/test/meson.build b/test/meson.build
index 6aa4e95..309551f 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -73,6 +73,7 @@ sequential_tests = {
},
'filesystem': {'': files('../README.md')},
'digest': {'': []},
+ 'environment': {'': []},
'hash': {'': []},
'path': {'': []},
'status': {'': []},
diff --git a/test/test_environment.c b/test/test_environment.c
new file mode 100644
index 0000000..dba7b90
--- /dev/null
+++ b/test/test_environment.c
@@ -0,0 +1,140 @@
+// Copyright 2012-2024 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
+#undef NDEBUG
+
+#include "failing_allocator.h"
+
+#include <zix/allocator.h>
+#include <zix/environment.h>
+#include <zix/path.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _WIN32
+
+# define HOME_NAME "USERPROFILE"
+# define HOME_VAR "%USERPROFILE%"
+
+#else
+
+# define HOME_NAME "HOME"
+# define HOME_VAR "$HOME"
+
+static char*
+concat(ZixAllocator* const allocator,
+ const char* const prefix,
+ const char* const suffix)
+{
+ const size_t prefix_len = strlen(prefix);
+ const size_t suffix_len = strlen(suffix);
+ const size_t result_len = prefix_len + suffix_len;
+
+ char* const result = (char*)zix_calloc(allocator, 1U, result_len + 1U);
+ assert(result);
+ memcpy(result, prefix, prefix_len + 1U);
+ memcpy(result + prefix_len, suffix, suffix_len + 1U);
+ return result;
+}
+
+#endif
+
+static void
+check_expansion(const char* const path, const char* const expected)
+{
+ char* const expanded = zix_expand_environment_strings(NULL, path);
+ assert(expanded);
+ assert(!strcmp(expanded, expected));
+ zix_free(NULL, expanded);
+}
+
+static void
+test_expansion(void)
+{
+ // Check non-expansion of hopefully unset variables
+ check_expansion("$ZIX_UNSET0", "$ZIX_UNSET0");
+ check_expansion("$ZIX_unset0", "$ZIX_unset0");
+ check_expansion("%ZIX_UNSET0%", "%ZIX_UNSET0%");
+ check_expansion("%ZIX_unset0%", "%ZIX_unset0%");
+
+ // Check non-expansion of invalid variable names
+ check_expansion("$%INVALID", "$%INVALID");
+ check_expansion("$<INVALID>", "$<INVALID>");
+ check_expansion("$[INVALID]", "$[INVALID]");
+ check_expansion("$invalid", "$invalid");
+ check_expansion("${INVALID}", "${INVALID}");
+
+ const char* const home = getenv(HOME_NAME);
+ if (home) {
+ char* const var_foo = zix_path_join(NULL, HOME_VAR, "foo");
+ char* const home_foo = zix_path_join(NULL, home, "foo");
+
+ check_expansion(var_foo, home_foo);
+
+#ifndef _WIN32
+ char* const tilde_foo = zix_path_join(NULL, "~", "foo");
+ char* const home_and_other = concat(NULL, home, ":/other");
+ char* const other_and_home = concat(NULL, "/other:", home);
+ check_expansion("~other", "~other");
+ check_expansion("~", home);
+ check_expansion("~/foo", home_foo);
+ check_expansion("~:/other", home_and_other);
+ check_expansion("/other:~", other_and_home);
+ check_expansion("$HO", "$HO");
+ check_expansion("$HOMEZIX", "$HOMEZIX");
+ zix_free(NULL, other_and_home);
+ zix_free(NULL, home_and_other);
+ zix_free(NULL, tilde_foo);
+#endif
+
+ zix_free(NULL, home_foo);
+ zix_free(NULL, var_foo);
+ }
+}
+
+static void
+test_failed_alloc(void)
+{
+ ZixFailingAllocator allocator = zix_failing_allocator();
+
+ zix_failing_allocator_reset(&allocator, 0U);
+ assert(!zix_expand_environment_strings(&allocator.base, "/one:~"));
+ assert(!zix_expand_environment_strings(&allocator.base, "/only"));
+ assert(!zix_expand_environment_strings(&allocator.base, "~"));
+
+#ifndef _WIN32
+ zix_failing_allocator_reset(&allocator, 1U);
+ assert(!zix_expand_environment_strings(&allocator.base, "/one:~"));
+ assert(!zix_expand_environment_strings(&allocator.base, "/one:$HOME/two"));
+
+ zix_failing_allocator_reset(&allocator, 2U);
+ assert(!zix_expand_environment_strings(&allocator.base, "/one:$HOME/two"));
+#endif
+}
+
+#ifndef _WIN32
+
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
+extern char** environ;
+
+static void
+test_null_environ(void)
+{
+ environ = NULL;
+ check_expansion(HOME_VAR, HOME_VAR);
+}
+
+#endif
+
+int
+main(void)
+{
+ test_expansion();
+ test_failed_alloc();
+#ifndef _WIN32
+ test_null_environ();
+#endif
+ return 0;
+}