JuliaLang / AllocCheck.jl

AllocCheck
Other
209 stars 8 forks source link

Add @test_noalloc convenience #55

Open tecosaur opened 8 months ago

tecosaur commented 8 months ago

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
tecosaur commented 8 months ago

NB: This requires #54 to be merged in for the callsite checking functionality.