From 4e828b7230d2d8dfebec87aa9d262ee10b8e45a4 Mon Sep 17 00:00:00 2001 From: James Y Knight Date: Mon, 22 Jul 2019 20:25:38 -0400 Subject: [PATCH] Add some basic tests for glob. --- src/functional/glob.c | 135 ++++++++++++++++++ src/functional/glob.data/basic/dir/file | 0 src/functional/glob.data/basic/file | 0 src/functional/glob.data/basic/symlink-dir | 1 + src/functional/glob.data/basic/symlink-file | 1 + .../glob.data/broken-links/broken-symlink | 1 + src/functional/glob.data/weird-chars/foo-[a] | 0 src/functional/glob.data/weird-chars/foo-a | 0 8 files changed, 138 insertions(+) create mode 100644 src/functional/glob.c create mode 100644 src/functional/glob.data/basic/dir/file create mode 100644 src/functional/glob.data/basic/file create mode 120000 src/functional/glob.data/basic/symlink-dir create mode 120000 src/functional/glob.data/basic/symlink-file create mode 120000 src/functional/glob.data/broken-links/broken-symlink create mode 100644 src/functional/glob.data/weird-chars/foo-[a] create mode 100644 src/functional/glob.data/weird-chars/foo-a diff --git a/src/functional/glob.c b/src/functional/glob.c new file mode 100644 index 0000000..69ffea5 --- /dev/null +++ b/src/functional/glob.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include + +#include "test.h" + +glob_t globbuf; + +int paths_match(int expected_num, const char **expected) { + if (globbuf.gl_pathc + globbuf.gl_offs != expected_num) + return 0; + for (int i = 0; i < expected_num; ++i) { + if ((globbuf.gl_pathv[i] == NULL) != (expected[i] == NULL)) + return 0; + if (expected[i] && strcmp(globbuf.gl_pathv[i], expected[i]) != 0) + return 0; + } + return 1; +} + +void print_mismatch(int expected_num, const char **expected) { + t_printf("Expected paths (%d):\n", expected_num); + for (int i = 0; i < expected_num; ++i) + t_printf(" %s\n", expected[i] ? expected[i] : "NULL"); + t_printf("Got paths (%d):\n", globbuf.gl_pathc + globbuf.gl_offs); + for (int i = 0; i < globbuf.gl_pathc + globbuf.gl_offs; ++i) + t_printf(" %s\n", globbuf.gl_pathv ? globbuf.gl_pathv[i] : "NULL"); +} + +#define TEST_NOFREE(pat, flags, expected_ret, ...) do { \ + int tflags = flags|extraflags; \ + int ret = glob(pat, tflags, NULL, &globbuf); \ + const char *e[] = __VA_ARGS__; \ + if (ret != expected_ret) \ + t_error("glob(\"%s\", %d) failed (return %d, expected %d)\n", \ + pat, tflags, ret, expected_ret); \ + if (!paths_match(sizeof(e)/sizeof(*e), e)) { \ + t_error("glob(\"%s\", %d) returned unexpected paths.\n", \ + pat, tflags); \ + print_mismatch(sizeof(e)/sizeof(*e), e); \ + } \ +} while(0) + +#define TEST(pat, flags, expected_ret, ...) do { \ + TEST_NOFREE(pat, flags, expected_ret, __VA_ARGS__); \ + globfree(&globbuf); \ +} while(0) + +#define TEST_UNMATCH(pat) do { \ + if (extraflags & GLOB_NOCHECK) \ + TEST(pat, extraflags, 0, {pat}); \ + else \ + TEST(pat, extraflags, GLOB_NOMATCH, {}); \ +} while(0) + +#define MARK(str) ((extraflags & GLOB_MARK) ? str "/" : str) + +static void do_tests(int extraflags) { + // Check basic functioning of paths + TEST("basic/file", 0, + 0, {"basic/file"}); + TEST("basic/symlink-file", 0, + 0, {"basic/symlink-file"}); + TEST("basic/dir", 0, + 0, {MARK("basic/dir")}); + TEST("basic/symlink-dir", 0, + 0, {MARK("basic/symlink-dir")}); + // With trailing slash input, always returns a trailing slash + TEST("basic/dir/", 0, + 0, {"basic/dir/"}); + + // And patterns... + TEST("basic/*", 0, + 0, {MARK("basic/dir"), "basic/file", MARK("basic/symlink-dir"), "basic/symlink-file"}); + TEST("basic/d?r", 0, + 0, {MARK("basic/dir")}); + TEST("basic/[df]??", 0, + 0, {MARK("basic/dir")}); + TEST("basic/fi[l]e", 0, + 0, {"basic/file"}); + TEST("basic/*/", 0, + 0, {"basic/dir/", "basic/symlink-dir/"}); + TEST("basic/*/*", 0, + 0, {"basic/dir/file", "basic/symlink-dir/file"}); + + TEST("weird-chars/foo-[a]", 0, + 0, {"weird-chars/foo-a"}); + TEST("weird-chars/foo-\\[a\\]", 0, + 0, {"weird-chars/foo-[a]"}); + + // Non-matching patterns + TEST_UNMATCH("basic/not-there"); + TEST_UNMATCH("basic/not-there*"); + TEST_UNMATCH("basic/not-there/*"); + // A file can't be specified with a trailing slash + TEST_UNMATCH("basic/file/"); + + // Check GLOB_APPEND, GLOB_DOOFFS, and both together + globbuf.gl_offs = 2; // should be ignored without GLOB_DOOFFS + TEST_NOFREE("basic/file", 0, + 0, {"basic/file"}); + TEST("basic/dir", GLOB_APPEND, + 0, {"basic/file", MARK("basic/dir")}); + + globbuf.gl_offs = 2; + TEST_NOFREE("basic/file", GLOB_DOOFFS, + 0, {NULL, NULL, "basic/file"}); + TEST("basic/dir", GLOB_APPEND|GLOB_DOOFFS, + 0, {NULL, NULL, "basic/file", MARK("basic/dir")}); + + // Check proper support for broken symlinks. Both completely-specified, + // and pattern matched. + TEST("broken-links/broken-symlink", 0, + 0, {"broken-links/broken-symlink"}); + + TEST("broken-links/*", 0, + 0, {"broken-links/broken-symlink"}); +} + + +int main(int argc, char **argv) +{ + char buf[512]; + if (!t_pathrel(buf, sizeof buf, argv[0], "glob.data")) { + t_error("failed to obtain relative path to glob data\n"); + return 1; + } + chdir(buf); + + do_tests(0); + do_tests(GLOB_MARK); + do_tests(GLOB_NOCHECK); + return t_status; +} diff --git a/src/functional/glob.data/basic/dir/file b/src/functional/glob.data/basic/dir/file new file mode 100644 index 0000000..e69de29 diff --git a/src/functional/glob.data/basic/file b/src/functional/glob.data/basic/file new file mode 100644 index 0000000..e69de29 diff --git a/src/functional/glob.data/basic/symlink-dir b/src/functional/glob.data/basic/symlink-dir new file mode 120000 index 0000000..8724519 --- /dev/null +++ b/src/functional/glob.data/basic/symlink-dir @@ -0,0 +1 @@ +dir \ No newline at end of file diff --git a/src/functional/glob.data/basic/symlink-file b/src/functional/glob.data/basic/symlink-file new file mode 120000 index 0000000..1a010b1 --- /dev/null +++ b/src/functional/glob.data/basic/symlink-file @@ -0,0 +1 @@ +file \ No newline at end of file diff --git a/src/functional/glob.data/broken-links/broken-symlink b/src/functional/glob.data/broken-links/broken-symlink new file mode 120000 index 0000000..456794e --- /dev/null +++ b/src/functional/glob.data/broken-links/broken-symlink @@ -0,0 +1 @@ +no-such-file \ No newline at end of file diff --git a/src/functional/glob.data/weird-chars/foo-[a] b/src/functional/glob.data/weird-chars/foo-[a] new file mode 100644 index 0000000..e69de29 diff --git a/src/functional/glob.data/weird-chars/foo-a b/src/functional/glob.data/weird-chars/foo-a new file mode 100644 index 0000000..e69de29 -- 2.22.0.657.g960e92d24f-goog