Message ID | f0b804129e8a21449cbb6f346473d3570182ddfa.1695070468.git.gitgitgadget@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | CMake(Visual C) support for js/doc-unit-tests | expand |
Hi Johannes On 18/09/2023 21:54, Johannes Schindelin via GitGitGadget wrote: > 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 > 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();
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();