Re: [PATCH 2/6] unit-tests: add TEST_RUN
- From
- phillip.wood123@gmail.com <phillip.wood123@gmail.com>
- Date
- Jul 8, 2024, 15:12 UTC
- Message-ID
- <9f63d125-b1ee-4b07-b0c7-a3c98dd31f90@gmail.com>
- In-Reply-To
- <6c83357a-825f-49d9-8cc2-e81415e8010d@web.de>
Hi René
On 05/07/2024 19:01, René Scharfe wrote:
Show 28 quoted lines
> Am 05.07.24 um 11:42 schrieb phillip.wood123@gmail.com: >> On 02/07/2024 21:55, René Scharfe wrote: >>> Am 02.07.24 um 17:13 schrieb phillip.wood123@gmail.com: >>> >>>> The changes in patch 6 to use TEST_RUN() mean that each test now has >>>> more boilerplate to initialize and free the strbuf. >>> >>> This makes them more similar to strbuf usage in the wild. Using >>> the API idiomatically just makes more sense to me. >> >> I see what you mean. I think it only looks idiomatic if you're >> already familiar with the api though as the test bodies call wrappers >> rather than using the strbuf api directly. I think that reduces its >> value as an example of idomatic usage for someone who is not familiar >> with the strbuf api. > > In early versions I used the original names by adding these just before > main(): > > #define strbuf_addch(x, y) t_addch(x, y) > #define strbuf_addstr(x, y) t_addstr(x, y) > #define strbuf_release(x) t_release(x) > > This allowed normal looking code to be used in tests, with checks > injected behind the scenes. Rejected it for v1 because it offers no > structural improvements, just optics. It does allow to forget the > checked versions when writing tests, though, so perhaps it's still > worth doing.
It also obscures what the test is doing though. It's nice if unit tests show how to use an API but I don't think we should let that be our overriding concern.
Show 28 quoted lines
>>> We could also let xstrvfmt() call vsnprintf(3) directly. The code
>>> duplication would be a bit grating, but perhaps there's some good
>>> base function hidden in there somewhere.
>>
>> Oh, interesting - maybe something like
>>
>> char* xstrvfmt(const char *fmt, ...)
>> {
>> va_list ap, aq;
>>
>> va_start(ap, fmt);
>> va_copy(aq, ap);
>> len = vnsprintf(NULL, 0, fmt, ap);
>> if (len < 0)
>> BUG(...)
>> buf = xmalloc(len + 1);
>> if (vnsprintf(buf, len + 1, fmt, aq) != len)
>> BUG(...)
>> va_end(aq);
>> va_end(ap);
>>
>> return buf;
>> }
>
> Yes. Though the current version allocates 65 bytes in the first try
> and only needs to call vnsprintf(3) once if the output fits in. No
> longer doing that might affect the performance of some callers in a
> noticeable way.Good point
Show 26 quoted lines
>>>> I'm not very enthusiastic about requiring the test author to wrap
>>>> TEST_RUN() in an if() statement rather than just doing that for them.
>>>> It makes it explicit but from the test author's point of view it just
>>>> feels like pointless boilerplate.
>>>
>>> Hmm. We can add more magic, but I suspect that it might confuse
>>> developers and editors.
>>
>> To me its confusing to have to wrap TEST_RUN() in an if() statement
>> until one realizes that the test might be skipped. If we document
>> that the test body should be enclosed in braces I don't think it
>> should confuse developers or editors and will keep the tests a bit
>> cleaner.
>
> You don't need braces in either case. I.e. something like
>
> if (TEST_RUN("foo"))
> foo();
>
> works fine. And
>
> #define IF_TEST_RUN(...) if (TEST_RUN(__VA_ARGS__))
> IF_TEST_RUN("foo")
> foo();
>
> works fine as well.Indeed. The reason I suggested requiring braces was to help editors indent the code correctly and because it gives a nice visual cue to see what is in each test.
Best Wishes
Phillip
Show 7 quoted lines
> The confusion that I'm afraid of is that we'd effectively invent a new > control flow keyword here, which is unusual. There are precedents, > though: foreach macros like for_each_string_list_item. We tell > clang-format about them using its option ForEachMacros. I see it also > has an option IfMacros since version 13 (unused by us so far). Hmm. > > René