Skip to content

filtering: enable disjunction of patterns (via arrays) #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions src/ReTest.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,24 @@ struct And <: Pattern
xs::AbstractArray
end

struct Or <: Pattern
xs::AbstractArray
end

alwaysmatches(pat::And) = all(alwaysmatches, pat.xs)
alwaysmatches(pat::Or) = any(alwaysmatches, pat.xs)
alwaysmatches(rx::Regex) = isempty(rx.pattern)

matches(pat::And, x) = all(p -> matches(p, x), pat.xs)
matches(pat::Or, x) = any(p -> matches(p, x), pat.xs)
matches(rx::Regex, x) = occursin(rx, x)

make_pattern(rx::Regex) = rx
make_pattern(str::AbstractString) = VERSION >= v"1.3" ? r""i * str :
Regex(str, "i")

make_pattern(pat::AbstractArray) = Or(make_pattern.(pat))


# * TestsetExpr

Expand Down Expand Up @@ -420,11 +432,14 @@ or within all currently loaded modules otherwise.
### Filtering

It's possible to filter run testsets by specifying one or multiple `pattern`s.
A testset is guaranteed to run only if it "matches" all passed patterns.
A testset is guaranteed to run only if it "matches" all passed patterns (conjunction).
Moreover if a testset is run, its enclosing testset, if any, also has to run
(although not necessarily exhaustively, i.e. other nested testsets
might be filtered out).

A `pattern` can be a string, a `Regex`, or an array.
For a testset to "match" an array, it must match at least one of its elements (disjunction).

### `Regex` filtering

The "subject" of a testset is the concatenation of the subject of its parent `@testset`,
Expand Down Expand Up @@ -455,7 +470,7 @@ the regex is simply created as `Regex(pattern, "i")`).
this function executes each (top-level) `@testset` block using `eval` *within* the
module in which it was written (e.g. `m`, when specified).
"""
function retest(args::Union{Module,AbstractString,Regex}...;
function retest(args::Union{Module,AbstractString,Regex,AbstractArray}...;
dry::Bool=false,
stats::Bool=false,
shuffle::Bool=false,
Expand Down Expand Up @@ -851,13 +866,10 @@ function process_args(args, verbose, shuffle, recursive)
patterns = []
modules = Module[]
for arg in args
if arg isa Regex
push!(patterns, arg)
elseif arg isa AbstractString
push!(patterns, VERSION >= v"1.3" ? r""i * arg :
Regex(arg, "i"))
else
if arg isa Module
push!(modules, arg)
else
push!(patterns, make_pattern(arg))
end
end

Expand Down
8 changes: 6 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,8 @@ end
push!(RUN, "c")
end

@testset "d" begin
push!(RUN, "d")
@testset "d$i" for i=1:2
push!(RUN, "d$i")
end

end # MultiPat
Expand All @@ -245,6 +245,10 @@ check(MultiPat, ["a", "b"], "a", "b")
check(MultiPat, ["a", "b"], "b", r"a")
check(MultiPat, [], "b", "d")
check(MultiPat, [], "a", "e")
check(MultiPat, ["aa", "d2"], ["aa", "2"])
check(MultiPat, ["d1", "d2"], ["1", "2"])
check(MultiPat, ["d2"], ["aa", "2"], "d")
check(MultiPat, ["d1", "d2"], ["aa", "2", ["2", "1"]], "d")


### toplevel #################################################################
Expand Down