From 974da16b52e1798325d47d79795e8c29654c0369 Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Sun, 28 Feb 2021 09:21:44 +0100 Subject: [PATCH] fix `include` path within testsets --- docs/src/index.md | 23 +++++++++++++++++++++++ src/ReTest.jl | 7 +++++++ test/FakePackage/test/included.jl | 2 ++ test/FakePackage/test/runtests.jl | 17 +++++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 test/FakePackage/test/included.jl diff --git a/docs/src/index.md b/docs/src/index.md index 0408b5b..495522c 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -92,6 +92,29 @@ should be fixable: is the current implemented heuristic to allow `Revise` do its magic. +#### Including files from within testsets + +TLDR: don't use `include(file)` within testsets when `file` defines +other testsets. + +There is limited support for `include(path)` expressions within testsets: all +what `ReTest` does is to adjust the `path` according to the location of the +containing file `parentfile`. This is necessary, because `include` is not run +immediately when that file is evaluated; when the given testset is triggered +(via a `retest` call), `include` doesn't have the same "context" as +`parentfile`, which would lead to `path` being interpreted as non-existing +(unless `path` is an absolute path). So when parsing testsets, `ReTest` +prepends the directory name of `parentfile` to `path`. + +The important point is that `include` is executed at `retest`-time; if the +included file defines other `@testset` expressions, this will define new +testsets in the enclosing module, but these won't be run immediately; upon a +new `retest()` invocation, these new testsets will be run, but the old one too +(the one containing `include`), which will redefine included testsets. This is +brittle, and it's recommended to not include, within testsets, files defining +other testsets. + + ## Switching from `Test` to `ReTest` When used in a package `MyPackage`, the test code can be organized as follows: diff --git a/src/ReTest.jl b/src/ReTest.jl index a649b69..3c402a0 100644 --- a/src/ReTest.jl +++ b/src/ReTest.jl @@ -80,6 +80,13 @@ function replace_ts(source, mod, x::Expr, parent) ts, false # hasbroken counts only "proper" @test_broken, not recursive ones elseif x.head === :macrocall && x.args[1] === Symbol("@test_broken") x, true + elseif x.head == :call && x.args[1] == :include + path = x.args[end] + sourcepath = dirname(string(source.file)) + x.args[end] = path isa AbstractString ? + joinpath(sourcepath, path) : + :(joinpath($sourcepath, $path)) + x, false else body_br = map(z -> replace_ts(source, mod, z, parent), x.args) Expr(x.head, first.(body_br)...), any(last.(body_br)) diff --git a/test/FakePackage/test/included.jl b/test/FakePackage/test/included.jl new file mode 100644 index 0000000..3d85de6 --- /dev/null +++ b/test/FakePackage/test/included.jl @@ -0,0 +1,2 @@ +@test true +push!(RUN, 0) diff --git a/test/FakePackage/test/runtests.jl b/test/FakePackage/test/runtests.jl index 1260f52..6492ed4 100644 --- a/test/FakePackage/test/runtests.jl +++ b/test/FakePackage/test/runtests.jl @@ -16,3 +16,20 @@ retest(FakePackage, recursive=true) @test FakePackage.RUN == [1, 2, 1, 2, 1, 2, 3, 4] retest(FakePackage) # equivalent to recursive=true @test FakePackage.RUN == [1, 2, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4] + +module Included +using ReTest +RUN = [] + +@testset "include parent" begin + include("included.jl") + include(joinpath(@__DIR__, "included.jl")) + if VERSION >= v"1.5" + include(identity, "included.jl") + include(identity, joinpath(@__DIR__, "included.jl")) + end +end +end + +retest(Included) +@test Included.RUN == (VERSION >= v"1.5" ? [0, 0, 0, 0] : [0, 0])