Skip to content

Commit 3409203

Browse files
Replace relpath with cheaper function
Since we call `relpath` for every directory and file in the directory tree before any tests start, we want this to be as cheap as possible (to minimise latency). Hopefully this new function is valid on Windows, but I've no machine to test that :/
1 parent f9cf56c commit 3409203

File tree

3 files changed

+45
-6
lines changed

3 files changed

+45
-6
lines changed

src/ReTestItems.jl

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,20 @@ function is_testsetup_file(filepath)
633633
)
634634
end
635635

636+
# like `relpath` but assumes `path` is nested under `startdir`, else just returns `path`
637+
function nestedrelpath(path, startdir)
638+
path == startdir && return "."
639+
relp = chopprefix(path, startdir)
640+
sep = Base.Filesystem.path_separator
641+
if endswith(startdir, sep)
642+
return relp
643+
elseif startswith(relp, sep)
644+
return chopprefix(relp, sep)
645+
else
646+
return path
647+
end
648+
end
649+
636650
# is `dir` the root of a subproject inside the current project?
637651
function _is_subproject(dir, current_projectfile)
638652
projectfile = _project_file(dir)
@@ -642,7 +656,7 @@ function _is_subproject(dir, current_projectfile)
642656
projectfile == current_projectfile && return false
643657
# a `test/Project.toml` is special and doesn't indicate a subproject
644658
current_project_dir = dirname(current_projectfile)
645-
rel_projectfile = relpath(projectfile, current_project_dir)
659+
rel_projectfile = nestedrelpath(projectfile, current_project_dir)
646660
rel_projectfile == joinpath("test", "Project.toml") && return false
647661
return true
648662
end
@@ -675,7 +689,7 @@ function include_testfiles!(project_name, projectfile, paths, ti_filter::TestIte
675689
subproject_root = root
676690
continue
677691
end
678-
rpath = relpath(root, project_root)
692+
rpath = nestedrelpath(root, project_root)
679693
startswith(rpath, hidden_re) && continue # skip hidden directories
680694
dir_node = DirNode(rpath; report, verbose=verbose_results)
681695
dir_nodes[rpath] = dir_node
@@ -693,7 +707,7 @@ function include_testfiles!(project_name, projectfile, paths, ti_filter::TestIte
693707
if !(is_testsetup_file(filepath) || (is_test_file(filepath) && is_requested(filepath, paths)))
694708
continue
695709
end
696-
fpath = relpath(filepath, project_root)
710+
fpath = nestedrelpath(filepath, project_root)
697711
file_node = FileNode(fpath, ti_filter; report, verbose=verbose_results)
698712
testitem_names = Set{String}() # to enforce that names in the same file are unique
699713
push!(dir_node, file_node)
@@ -745,7 +759,7 @@ function _throw_duplicate_ids(testitems)
745759
seen = Dict{String,String}()
746760
for ti in testitems
747761
id = ti.id
748-
source = string(relpath(ti.file, ti.project_root), ":", ti.line)
762+
source = string(nestedrelpath(ti.file, ti.project_root), ":", ti.line)
749763
name = string(repr(ti.name), " at ", source)
750764
if haskey(seen, id)
751765
name1 = seen[id]

src/junit_xml.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,15 @@ mutable struct JUnitTestSuite # File
9898
counts::JUnitCounts
9999
testcases::Vector{JUnitTestCase}
100100
end
101-
JUnitTestSuite(name::String) = JUnitTestSuite(name, JUnitCounts(), JUnitTestCase[])
101+
JUnitTestSuite(name::AbstractString) = JUnitTestSuite(name, JUnitCounts(), JUnitTestCase[])
102102

103103
mutable struct JUnitTestSuites
104104
const name::String
105105
counts::JUnitCounts
106106
testsuites::Vector{JUnitTestSuite}
107107
end
108108

109-
JUnitTestSuites(name::String) = JUnitTestSuites(name, JUnitCounts(), JUnitTestSuite[])
109+
JUnitTestSuites(name::AbstractString) = JUnitTestSuites(name, JUnitCounts(), JUnitTestSuite[])
110110

111111
function junit_record!(suites1::JUnitTestSuites, suites2::JUnitTestSuites)
112112
update!(suites1.counts, suites2.counts)

test/internals.jl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,4 +378,29 @@ end
378378
end
379379
end
380380

381+
@testset "nestedrelpath" begin
382+
using ReTestItems: nestedrelpath
383+
@assert Base.Filesystem.path_separator == "/"
384+
path = "test/dir/foo_test.jl"
385+
@test nestedrelpath(path, "test") == relpath(path, "test") == "dir/foo_test.jl"
386+
@test nestedrelpath(path, "test/") == relpath(path, "test/") == "dir/foo_test.jl"
387+
@test nestedrelpath(path, "test/dir") == relpath(path, "test/dir") == "foo_test.jl"
388+
@test nestedrelpath(path, "test/dir/") == relpath(path, "test/dir/") == "foo_test.jl"
389+
@test nestedrelpath(path, "test/dir/foo_test.jl") == relpath(path, "test/dir/foo_test.jl") == "."
390+
391+
# unlike `relpath`: if `startdir` is not a prefix of `path`, the assumption is violated,
392+
# and `path` is just returned as-is
393+
@test nestedrelpath(path, "test/dir/foo_") == "test/dir/foo_test.jl"
394+
@test nestedrelpath(path, "test/dir/other") == "test/dir/foo_test.jl"
395+
@test nestedrelpath(path, "test/dir/other/bar_test.jl") == "test/dir/foo_test.jl"
396+
397+
@static if isdefined(Base, Symbol("@allocations")) # added in Julia v1.9
398+
@test 2 >= @allocations(nestedrelpath(path, "test"))
399+
@test 2 >= @allocations(nestedrelpath(path, "test/dir"))
400+
@test 1 >= @allocations(nestedrelpath(path, "test/dir/foo_test.jl"))
401+
@test 1 >= @allocations(nestedrelpath(path, "test/dir/other"))
402+
@test 1 >= @allocations(nestedrelpath(path, "test/dir/other/bar_test.jl"))
403+
end
404+
end
405+
381406
end # internals.jl testset

0 commit comments

Comments
 (0)