From 47116d0d8dd34d7e435398886d01cac2bcc4ae9d Mon Sep 17 00:00:00 2001 From: Nick Robinson Date: Mon, 16 Sep 2024 12:14:25 +0100 Subject: [PATCH] Reintroduce `activate(f)` and `deactivate()` These were dropped in the initial v0.8 release (see PR#119) but were being used in the wild so this PR brings them back, but with documentation warning about the downsides of their usage. --- src/Mocking.jl | 41 +++++++++++++++++++++++++++++++++++++++++ test/activate.jl | 28 ++++++++++++++++++++++++++++ test/runtests.jl | 1 + 3 files changed, 70 insertions(+) create mode 100644 test/activate.jl diff --git a/src/Mocking.jl b/src/Mocking.jl index 5e7ffd2..e10c195 100644 --- a/src/Mocking.jl +++ b/src/Mocking.jl @@ -50,6 +50,47 @@ function activate() return nothing end +""" + Mocking.activate(f) + + +Activate `@mock` call sites for the duration of the function `f`. + +!!! warning + This function redefines Mocking.jl internals and so can produce warnings about + method redefinitions. You may see the warning: + `WARNING: Method definition _activated($Int) at ... overwritten at ...` + This is expected behavior and can be safely ignored. + To avoid these warnings, instead use `Mocking.activate()` to activate `@mock` call + sites for the duration of the test suite. Alternatively, start Julia with + `--warn-overwrite=no` to suppress these warnings. +""" +function activate(f) + started_deactivated = !activated() + try + activate() + Base.invokelatest(f) + finally + started_deactivated && deactivate() + end +end + +""" + Mocking.deactivate() -> Nothing + +Disable `@mock` call sites to only call the original function. + +!!! note + It is not usually necessary to call this function directly. + Instead it is recommended to simply call `Mocking.activate()` in `test/runtests.jl` to + activate `@mock` call sites for the duration of the test suite. +""" +function deactivate() + # Avoid redefining `_activated` when it's already set appropriately + Base.invokelatest(activated) && @eval _activated(::Int) = false + return nothing +end + const NULLIFIED = Ref{Bool}(false) """ diff --git a/test/activate.jl b/test/activate.jl new file mode 100644 index 0000000..a782cab --- /dev/null +++ b/test/activate.jl @@ -0,0 +1,28 @@ +@testset "activate(func) / deactivate" begin + add1(x) = x + 1 + patch = @patch add1(x) = x + 42 + + # Starting with Mocking enabled. + @assert Mocking.activated() + Mocking.activate() do + apply(patch) do + @test (@mock add1(2)) == 44 + end + end + @test Mocking.activated() + + # Starting with Mocking disabled. + # Make sure to leave it enabled for the rest of the tests. + try + Mocking.deactivate() + @test !Mocking.activated() + Mocking.activate() do + apply(patch) do + @test (@mock add1(2)) == 44 + end + end + @test !Mocking.activated() + finally + Mocking.activate() + end +end diff --git a/test/runtests.jl b/test/runtests.jl index 1e98a93..93e41cf 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -39,4 +39,5 @@ Mocking.activate() include("async-scope.jl") include("issues.jl") include("async-world-ages.jl") + include("activate.jl") end