Skip to content

Commit adc9f9d

Browse files
committed
filtering: add symbol (label) patterns
1 parent 29a8716 commit adc9f9d

File tree

4 files changed

+63
-9
lines changed

4 files changed

+63
-9
lines changed

src/ReTest.jl

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,15 @@ function delmark!(marks, subject, m::Symbol)
188188
nothing
189189
end
190190

191+
function hasmark(marks, subject, m::Symbol)
192+
ms = get(marks, subject, Symbol())
193+
if ms isa Symbol
194+
ms === m
195+
else
196+
m ms
197+
end
198+
end
199+
191200

192201
struct _Invalid
193202
global const invalid = _Invalid.instance
@@ -679,10 +688,11 @@ Moreover if a testset is run, its enclosing testset, if any, also has to run
679688
(although not necessarily exhaustively, i.e. other nested testsets
680689
might be filtered out).
681690
682-
A `pattern` can be a string, a `Regex`, an integer, an array or a tuple.
691+
A `pattern` can be a string, a `Regex`, an integer, a symbol, an array or a tuple.
683692
For a testset to "match" an array, it must match at least one of its elements (disjunction).
684693
To match a tuple, it must match all of its elements (conjunction).
685694
To match an integer, its ID must be equal to this integer (cf. the `id` keyword).
695+
To match a symbol, it must be tagged with that symbol (label).
686696
687697
A pattern can also be the "negation" of a pattern, via the [`not`](@ref) function,
688698
which allows to exclude testsets from being run.
@@ -811,6 +821,10 @@ function retest(@nospecialize(args::ArgType...);
811821
if !dry && !isempty(tag)
812822
@warn "tag keyword: labels can be added only in dry mode"
813823
end
824+
for label in tag
825+
startswith(String(label), '_') &&
826+
throw(ArgumentError("tag keyword: labels can't start with an underscore"))
827+
end
814828

815829
for imod in eachindex(modules)
816830
mod, pat = modules[imod]
@@ -1212,7 +1226,9 @@ function update_keywords(@nospecialize(args), dry, stats, shuffle, group, verbos
12121226
recursive, id, strict, dup, static, marks, spin)
12131227
for arg in args
12141228
if arg isa Symbol
1215-
for c in string(arg)
1229+
sarg = String(arg)
1230+
startswith(sarg, '_') || continue
1231+
for c in sarg[2:end]
12161232
c == 'v' && continue # "verbose" ignored, we care only about the value
12171233
val = islowercase(c)
12181234
c = lowercase(c)
@@ -1300,7 +1316,7 @@ function process_args(@nospecialize(args);
13001316
push!(pat.xs, make_pattern(last(arg)))
13011317
mod modules && push!(modules, mod)
13021318
load_testmod(mod)
1303-
elseif arg isa Symbol
1319+
elseif arg isa Symbol && startswith(String(arg), '_')
13041320
# ignored, already processed in update_keywords
13051321
else
13061322
push!(patterns, make_pattern(arg))

src/patterns.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const PatternX = Union{Pattern, Regex, Integer}
1+
const PatternX = Union{Pattern, Regex, Integer, Symbol}
22

33
## Patterns
44

@@ -89,6 +89,7 @@ alwaysmatches(::Not, _) = false
8989
alwaysmatches(::Interpolated, _) = false
9090
alwaysmatches(rx::Regex, _) = isempty(rx.pattern)
9191
alwaysmatches(id::Integer, _) = false
92+
alwaysmatches(label::Symbol, _) = false
9293
alwaysmatches(pat::Reachable, d) = alwaysmatches(pat.x, d)
9394
alwaysmatches(dep::Depth, d) = dep.d == d
9495
alwaysmatches(::Pass, _) = false
@@ -116,6 +117,11 @@ matches(pat::Integer, _, ts) =
116117
pat == ts.id :
117118
pat != -ts.id
118119

120+
matches(label::Symbol, subj::AbstractString, ts) = hasmark(ts.marks, subj, label)
121+
matches(label::Symbol, subj::Missing, ts) = missing
122+
# TODO: optimize by recording possible labels for missing, to allow returning false
123+
# in some cases
124+
119125
function matches(pat::Reachable, desc, ts)
120126
if desc !== missing
121127
desc = SubString(desc)

test/runtests.jl

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -948,14 +948,14 @@ module Marks
948948
using ReTest, ..Trace
949949

950950
@testset "a" begin
951-
@test true
951+
trace("a")
952952
@testset "b" begin end # no test, counts as pass
953953
@testset "c" begin
954-
@test true
954+
trace("c")
955955
end
956956
x = 1
957957
@testset "d$x" begin
958-
@test true
958+
trace("d$x")
959959
end
960960
@testset "e" begin
961961
@test false
@@ -1129,6 +1129,8 @@ x ⋯
11291129
retest(Marks, r"a$", dry=false)
11301130
retest(Marks, r"a$", dry=true, tag=[:a3 :a4])
11311131
retest(Marks, r"a$", dry=true, tag=(:a5, :a6))
1132+
@test_throws ArgumentError retest(Marks, r"a$", dry=true, tag=:_underscored)
1133+
11321134
check(Marks, "-l", -4, dry=true, verbose=9, id=false, marks=true, [], output="""
11331135
a a1 a2 a3 a4 a5 a6 ✔
11341136
b
@@ -1146,6 +1148,35 @@ x
11461148
z3
11471149
z4
11481150
""")
1151+
check(Marks, "a", "-l", -4, :a2, dry=true, verbose=9, id=false, marks=true, [],
1152+
output="a a1 a2 a3 a4 a5 a6 ✔")
1153+
check(Marks, "a", "-l", -4, :a2, dry=false, verbose=9, id=false, marks=true, ["a"])
1154+
if VERSION >= v"1.3"
1155+
check(Marks, "-l", -4, not(reachable(:a1)), dry=true, verbose=9, id=false,
1156+
marks=true, [], output="""
1157+
x
1158+
y1 ylabel
1159+
z1 ylabel
1160+
z2 ylabel
1161+
z3 ylabel
1162+
z4 ylabel
1163+
y2
1164+
z1
1165+
z2
1166+
z3
1167+
z4
1168+
""")
1169+
check(Marks, "-l", -4, reachable("x"), not(:ylabel), dry=true, verbose=9, id=false,
1170+
marks=true, [], output="""
1171+
x
1172+
y1 ylabel
1173+
y2
1174+
z1
1175+
z2
1176+
z3
1177+
z4
1178+
""")
1179+
end
11491180
end
11501181

11511182

test/test_patterns.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ end
1515

1616
ReTest.tsdepth(::MockTestset) = 1
1717

18-
const basic_patterns = [and(), or(), not(0), interpolated, 0, r"", depth(2), pass, fail, iter(1)]
18+
const basic_patterns = [and(), or(), not(0), interpolated, 0, r"", :label,
19+
depth(2), pass, fail, iter(1)]
1920
VERSION >= v"1.3" && push!(basic_patterns, reachable(1))
2021

2122
@testset "patterns: ==" begin
2223
for a = basic_patterns, b = basic_patterns
2324
if a === b
2425
@test a == b
25-
if !(a isa Regex || a isa Integer)
26+
if !(a isa Regex || a isa Integer || a isa Symbol)
2627
@test -a == not(a)
2728
end
2829
else

0 commit comments

Comments
 (0)