From fb8eb22e569948b7b4fc0bf6a7c77e680e147ec3 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Thu, 25 Sep 2014 18:51:03 -0700 Subject: [PATCH] Refactor expand tests slightly to handle errors better If we get an error relating to our manipulation of the temporary directory or cwd, we don't want to run the rest of the tests that assume it worked. --- fish_tests.cpp | 117 ++++++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 55 deletions(-) diff --git a/fish_tests.cpp b/fish_tests.cpp index 85327cca4..156fdc049 100644 --- a/fish_tests.cpp +++ b/fish_tests.cpp @@ -1301,14 +1301,17 @@ static void test_lru(void) \param in the string to expand \param flags the flags to send to expand_string + \param ... A zero-terminated parameter list of values to test. + After the zero terminator comes one more arg, a string, which is the error + message to print if the test fails. */ -static int expand_test(const wchar_t *in, expand_flags_t flags, ...) +static bool expand_test(const wchar_t *in, expand_flags_t flags, ...) { std::vector output; va_list va; size_t i=0; - int res=1; + bool res=true; wchar_t *arg; if (expand_string(in, output, flags, NULL)) @@ -1329,25 +1332,41 @@ static int expand_test(const wchar_t *in, expand_flags_t flags, ...) { if (output.size() == i) { - res=0; + res=false; break; } if (output.at(i).completion != arg) { - res=0; + res=false; break; } i++; + + if (!res) + { + // empty the rest of the args + while(va_arg(va, wchar_t *) != 0); + break; + } } - va_end(va); - + if (output.size() != i) { res = false; } + if (!res) + { + if ((arg = va_arg(va, wchar_t *)) != 0) + { + err(arg); + } + } + + va_end(va); + return res; } @@ -1359,30 +1378,20 @@ static void test_expand() { say(L"Testing parameter expansion"); - if (!expand_test(L"foo", 0, L"foo", 0)) - { - err(L"Strings do not expand to themselves"); - } + expand_test(L"foo", 0, L"foo", 0, + L"Strings do not expand to themselves"); - if (!expand_test(L"a{b,c,d}e", 0, L"abe", L"ace", L"ade", 0)) - { - err(L"Bracket expansion is broken"); - } + expand_test(L"a{b,c,d}e", 0, L"abe", L"ace", L"ade", 0, + L"Bracket expansion is broken"); - if (!expand_test(L"a*", EXPAND_SKIP_WILDCARDS, L"a*", 0)) - { - err(L"Cannot skip wildcard expansion"); - } - - if (!expand_test(L"/bin/l\\0", ACCEPT_INCOMPLETE, 0)) - { - err(L"Failed to handle null escape in expansion"); - } + expand_test(L"a*", EXPAND_SKIP_WILDCARDS, L"a*", 0, + L"Cannot skip wildcard expansion"); - if (!expand_test(L"foo\\$bar", EXPAND_SKIP_VARIABLES, L"foo$bar", 0)) - { - err(L"Failed to handle dollar sign in variable-skipping expansion"); - } + expand_test(L"/bin/l\\0", ACCEPT_INCOMPLETE, 0, + L"Failed to handle null escape in expansion"); + + expand_test(L"foo\\$bar", EXPAND_SKIP_VARIABLES, L"foo$bar", 0, + L"Failed to handle dollar sign in variable-skipping expansion"); if (system("mkdir -p /tmp/fish_expand_test/")) err(L"mkdir failed"); if (system("touch /tmp/fish_expand_test/.foo")) err(L"touch failed"); @@ -1391,42 +1400,40 @@ static void test_expand() if (system("touch /tmp/fish_expand_test/--flag2")) err(L"touch failed"); // This is checking that .* does NOT match . and .. (https://github.com/fish-shell/fish-shell/issues/270). But it does have to match literal components (e.g. "./*" has to match the same as "*" - if (! expand_test(L"/tmp/fish_expand_test/.*", 0, L"/tmp/fish_expand_test/.foo", 0)) - { - err(L"Expansion not correctly handling dotfiles"); - } - if (! expand_test(L"/tmp/fish_expand_test/./.*", 0, L"/tmp/fish_expand_test/./.foo", 0)) - { - err(L"Expansion not correctly handling literal path components in dotfiles"); - } - if (! expand_test(L"/tmp/fish_expand_test/*flag?", 0, L"/tmp/fish_expand_test/--flag2", L"/tmp/fish_expand_test/-flag1", 0)) - { - err(L"Expansion not correctly handling flag-like files"); - } + expand_test(L"/tmp/fish_expand_test/.*", 0, L"/tmp/fish_expand_test/.foo", 0, + L"Expansion not correctly handling dotfiles"); + expand_test(L"/tmp/fish_expand_test/./.*", 0, L"/tmp/fish_expand_test/./.foo", 0, + L"Expansion not correctly handling literal path components in dotfiles"); + expand_test(L"/tmp/fish_expand_test/*flag?", 0, L"/tmp/fish_expand_test/--flag2", L"/tmp/fish_expand_test/-flag1", 0, + L"Expansion not correctly handling flag-like files"); // Verify that flag-like file expansions never expand to flags char saved_wd[PATH_MAX + 1] = {}; - getcwd(saved_wd, sizeof saved_wd); - if (chdir("/tmp/fish_expand_test/")) err(L"chdir failed"); - if (! expand_test(L"*flag?", 0, L"./--flag2", L"./-flag1", 0)) + if (getcwd(saved_wd, sizeof saved_wd) != NULL && !chdir("/tmp/fish_expand_test/")) { - err(L"Expansion not correctly handling flag-like files in cwd"); + expand_test(L"*flag?", 0, L"./--flag2", L"./-flag1", 0, + L"Expansion not correctly handling flag-like files in cwd"); + expand_test(L"*flag?", EXPAND_NO_SANITIZE_FLAGLIKE_FILES, L"--flag2", L"-flag1", 0, + L"Expansion (no sanitize) not correctly handling flag-like files in cwd"); + + // For suffix-only completions, we don't attempt any sanitization + expand_test(L"*flag", ACCEPT_INCOMPLETE, L"2", L"1", 0, + L"Expansion (accept incomplete) not correctly handling flag-like files in cwd"); + + if (!chdir(saved_wd)) + { + if (system("rm -Rf /tmp/fish_expand_test")) err(L"rm failed"); + } + else + { + err(L"chdir restoration failed"); + } } - if (! expand_test(L"*flag?", EXPAND_NO_SANITIZE_FLAGLIKE_FILES, L"--flag2", L"-flag1", 0)) + else { - err(L"Expansion not correctly handling flag-like files in cwd"); + err(L"chdir failed"); } - - // For suffix-only completions, we don't attempt any sanitization - if (! expand_test(L"*flag", ACCEPT_INCOMPLETE, L"2", L"1", 0)) - { - err(L"Expansion not correctly handling flag-like files in cwd"); - } - - if (chdir(saved_wd)) err(L"chdir restoration failed"); - - if (system("rm -Rf /tmp/fish_expand_test")) err(L"rm failed"); } static void test_fuzzy_match(void)