For use in unit-testing, @test_noalloc is implemented as a way to check that a given call is not allocating. To avoid extra dependencies, this is implemented as a package extension (loaded with Test). Since package extensions can not themselves export bindings, the macro is implemented in AllocCheck.jl, but emits an informative error when called without the extension loaded.
Demo
julia> using AllocCheck
julia> @test_noalloc 1 + 1
ERROR: LoadError: @test_noalloc is an extension to Test, but Test is not loaded.
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
[2] var"@test_noalloc"(__source__::LineNumberNode, __module__::Module, expr::Any, kws::Vararg{Any})
@ AllocCheck ~/.julia/dev/AllocCheck/src/AllocCheck.jl:235
in expression starting at REPL[2]:1
julia> using Test
julia> @test_noalloc 1 + 1
Test Passed
julia> @test_noalloc rand(2, 2) * rand(2, 2)
Test Failed at REPL[5]:1
Expression: rand(2, 2) * rand(2, 2)
Evaluated: @test_noalloc rand(2, 2) * rand(2, 2)
ERROR: There was an error during testing
It also behaves reasonably (I think) for invalid inputs, and other errors that may occur.
julia> @test_noalloc not_a_call
ERROR: LoadError: invalid test_noalloc macro call: must be applied to a function call
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
[2] _test_noalloc(::Module, ::LineNumberNode, ::Symbol)
@ TestAlloc ~/.julia/dev/AllocCheck/ext/TestAlloc.jl:22
[3] var"@test_noalloc"(__source__::LineNumberNode, __module__::Module, expr::Any, kws::Vararg{Any})
@ AllocCheck ~/.julia/dev/AllocCheck/src/AllocCheck.jl:237
in expression starting at REPL[5]:1
julia> @test_noalloc a * b
Error During Test at REPL[20]:1
Test threw exception
Expression: @test_noalloc a * b
UndefVarError: `a` not defined
Stacktrace:
[1] macro expansion
@ ~/.julia/dev/AllocCheck/src/macro.jl:189 [inlined]
[2] macro expansion
@ ~/.julia/dev/AllocCheck/ext/TestAlloc.jl:30 [inlined]
[3] top-level scope
@ REPL[6]:1
...
[15] _start()
@ Base ./client.jl:552
ERROR: There was an error during testing
For use in unit-testing,
@test_noalloc
is implemented as a way to check that a given call is not allocating. To avoid extra dependencies, this is implemented as a package extension (loaded withTest
). Since package extensions can not themselves export bindings, the macro is implemented inAllocCheck.jl
, but emits an informative error when called without the extension loaded.Demo
It also behaves reasonably (I think) for invalid inputs, and other errors that may occur.