Testing for warnings emitted at macro expansion time

Hi all,

I’m working on some macros for PikaParser.jl grammars (very WIP!), and I had a question regarding their testing.

One thing I’m trying to do is build the grammar at macro-time; this allows us to return a lambda function applying the parser with rules into the caller, which should allow for precompilable parsers. Because the user may be calling helper functions, this requires an @eval into __module__.

However, this requires symbols to be resolvable at module top-level. If this errors (e.g. because helper functions were defined in a local scope), we recover by issuing a warning about the offending symbol, and defer the grammar build to runtime. That warning is line 74 of this file.

Now, this all works fairly well, and I am writing test-cases. Naively, I expected a @test_warn to work; after some digging, I also tried with @test_logs and by constructing a TestLogger directly.

The fundamental issue is that the @warn invoke happens at macro-time, where stdout/stderr is not captured by the test suite. That test happens here – specifically, at the @syntax macro invoke at line 54.

What are the options here? I would very much like to ensure that this warning is occurring as expected. Should I redirect output streams at macro-expansion time?

Thanks all in advance!

For the record, it’s always better to provide permanent links to files or code snippets (and it looks like the line number already change since you posted your message):

Ah, yes, probably :slight_smile: I don’t often collaborate with others on code, so my version-control practices are dubious at best!

I’ve just allowed turning off the warning at macro invoke; this solves the issue for me, while letting me test by inspecting the result of @macroexpand.

As it happens, the relevant test line is still at 54:

syntax_exprs = @macroexpand P.@syntax :top begin
    :ws     => many(satisfy(myisspace))
    :number => some(:digit => satisfy(myisdigit))
    :top    => seq(:ws, :number)
end true