Skip to content

Commit 1cdd17e

Browse files
committed
add hijack
1 parent b46f779 commit 1cdd17e

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,13 @@ function recursive_includet(filename)
174174
end
175175
end
176176
```
177+
178+
### Working with test files which use Test
179+
180+
It's sometimes possible to use `ReTest` features on a test code base which uses `Test`:
181+
- if you have a package `Package`, you can try `ReTest.hijack(Package)`, which will define
182+
a `PackageTests` module when successful, on which you can call `retest`.
183+
- if you have a test file `"testfile.jl"`, try `ReTest.hijack("testfile.jl")`
184+
(this will define a fresh module like above).
185+
186+
Check out the docstring of `ReTest.hijack` for more details.

src/ReTest.jl

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,70 @@ function dryrun(mod::Module, ts::TestsetExpr, rx::Regex, align::Int=0, parentsub
789789
end
790790
end
791791

792+
## hijack ####################################################################
793+
794+
"""
795+
ReTest.hijack(source, [modname]; parentmodule::Module=Main)
796+
797+
Given test files defined in `source` using the `Test` package,
798+
try to load them by replacing `Test` with `ReTest`, wrapping them in a module `modname`
799+
defined withing `parentmodule`. If successful, the newly created module `modname` is
800+
returned and `modname.runtests()` should be callable.
801+
802+
If `source::AbstractString`, then it's interpreted as the top level test file
803+
(possibly including other files).
804+
If `source::Module`, then it's interpreted as the name of a package, and the
805+
"test/runtests.jl" file from this package is loaded. In this case, `modname`
806+
defaults to `Symbol(source, :Tests)`.
807+
"""
808+
function hijack end
809+
810+
function hijack(path::AbstractString, modname=nothing; parentmodule::Module=Main)
811+
if modname === nothing
812+
modname = :TestMod
813+
i = 1
814+
while hasproperty(parentmodule, modname)
815+
modname = Symbol(:TestMod, i)
816+
i += 1
817+
end
818+
end
819+
modname = Symbol(modname)
820+
821+
newmod = @eval parentmodule module $modname
822+
using ReTest # for files which don't have `using Test`
823+
include($substitue_retest!, $path)
824+
end
825+
newmod
826+
end
827+
828+
function hijack(packagemod::Module, modname=nothing; parentmodule::Module=Main)
829+
path = joinpath(dirname(dirname(pathof(packagemod))), "test", "runtests.jl")
830+
if modname === nothing
831+
modname = Symbol(packagemod, :Tests)
832+
end
833+
hijack(path, modname, parentmodule=parentmodule)
834+
end
835+
836+
function substitue_retest!(ex)
837+
if Meta.isexpr(ex, :using)
838+
for used in ex.args
839+
if Meta.isexpr(used, :., 1) && used.args[1] == :ReTest
840+
throw(ArgumentError("ReTest is already used"))
841+
elseif Meta.isexpr(used, :., 1) && used.args[1] == :Test
842+
used.args[1] = :ReTest
843+
end
844+
end
845+
elseif Meta.isexpr(ex, :call) && ex.args[1] == :include
846+
if length(ex.args) > 2
847+
throw(ArgumentError("cannot handle include with two arguments"))
848+
else
849+
insert!(ex.args, 2, substitue_retest!)
850+
end
851+
end
852+
ex
853+
end
854+
855+
792856
module ReTestTest
793857

794858
using ..ReTest

0 commit comments

Comments
 (0)