Re: [PATCH v2 3/7] unit-tests: do show relative file paths
Hi Johannes
On 18/09/2023 21:54, Johannes Schindelin via GitGitGadget wrote:
Show 7 quoted lines
> From: Johannes Schindelin <johannes.schindelin@gmx.de>
>
> Visual C interpolates `__FILE__` with the absolute _Windows_ path of
> the source file. GCC interpolates it with the relative path, and the
> tests even verify that.
>
> So let's make sure that the unit tests only emit such paths.
This looks good to me. Calling strlcpy() without checking the return value is a pet peeve of mine but the silent truncation doesn't matter here and the buffer ought to be long enough anyway.
Best Wishes
Phillip
Show 94 quoted lines
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
> t/unit-tests/test-lib.c | 52 +++++++++++++++++++++++++++++++++++++----
> 1 file changed, 48 insertions(+), 4 deletions(-)
>
> diff --git a/t/unit-tests/test-lib.c b/t/unit-tests/test-lib.c
> index 70030d587ff..744e223ee98 100644
> --- a/t/unit-tests/test-lib.c
> +++ b/t/unit-tests/test-lib.c
> @@ -21,6 +21,46 @@ static struct {
> .result = RESULT_NONE,
> };
>
> +#ifndef _MSC_VER
> +#define make_relative(location) location
> +#else
> +/*
> + * Visual C interpolates the absolute Windows path for `__FILE__`,
> + * but we want to see relative paths, as verified by t0080.
> + */
> +#include "dir.h"
> +
> +static const char *make_relative(const char *location)
> +{
> + static char prefix[] = __FILE__, buf[PATH_MAX], *p;
> + static size_t prefix_len;
> +
> + if (!prefix_len) {
> + size_t len = strlen(prefix);
> + const char *needle = "\\t\\unit-tests\\test-lib.c";
> + size_t needle_len = strlen(needle);
> +
> + if (len < needle_len || strcmp(needle, prefix + len - needle_len))
> + die("unexpected suffix of '%s'", prefix);
> +
> + /* let it end in a directory separator */
> + prefix_len = len - needle_len + 1;
> + }
> +
> + /* Does it not start with the expected prefix? */
> + if (fspathncmp(location, prefix, prefix_len))
> + return location;
> +
> + strlcpy(buf, location + prefix_len, sizeof(buf));
> + /* convert backslashes to forward slashes */
> + for (p = buf; *p; p++)
> + if (*p == '\\')
> + *p = '/';
> +
> + return buf;
> +}
> +#endif
> +
> static void msg_with_prefix(const char *prefix, const char *format, va_list ap)
> {
> fflush(stderr);
> @@ -147,7 +187,8 @@ int test__run_end(int was_run UNUSED, const char *location, const char *format,
> break;
>
> case RESULT_NONE:
> - test_msg("BUG: test has no checks at %s", location);
> + test_msg("BUG: test has no checks at %s",
> + make_relative(location));
> printf("not ok %d", ctx.count);
> print_description(format, ap);
> ctx.result = RESULT_FAILURE;
> @@ -193,13 +234,15 @@ int test_assert(const char *location, const char *check, int ok)
> assert(ctx.running);
>
> if (ctx.result == RESULT_SKIP) {
> - test_msg("skipping check '%s' at %s", check, location);
> + test_msg("skipping check '%s' at %s", check,
> + make_relative(location));
> return 0;
> } else if (!ctx.todo) {
> if (ok) {
> test_pass();
> } else {
> - test_msg("check \"%s\" failed at %s", check, location);
> + test_msg("check \"%s\" failed at %s", check,
> + make_relative(location));
> test_fail();
> }
> }
> @@ -224,7 +267,8 @@ int test__todo_end(const char *location, const char *check, int res)
> if (ctx.result == RESULT_SKIP)
> return 0;
> if (!res) {
> - test_msg("todo check '%s' succeeded at %s", check, location);
> + test_msg("todo check '%s' succeeded at %s", check,
> + make_relative(location));
> test_fail();
> } else {
> test_todo();