From 771f096f0bf1950306d36ac6bb9b8a2d185432b2 Mon Sep 17 00:00:00 2001 From: richardreeve Date: Tue, 21 Nov 2023 18:20:37 +0000 Subject: [PATCH] Update code to 1.9 extensions and dependencies --- Project.toml | 36 ++++-- src/rcall.jl => ext/PhyloRCallExt.jl | 24 +++- src/Phylo.jl | 13 ++- test/Project.toml | 6 - test/{test_rcall.jl => ext_PhyloRCallExt.jl} | 0 test/runtests.jl | 116 +++++++++++++++---- 6 files changed, 145 insertions(+), 50 deletions(-) rename src/rcall.jl => ext/PhyloRCallExt.jl (84%) delete mode 100644 test/Project.toml rename test/{test_rcall.jl => ext_PhyloRCallExt.jl} (100%) diff --git a/Project.toml b/Project.toml index 02396313..4c2a3cd2 100644 --- a/Project.toml +++ b/Project.toml @@ -7,6 +7,7 @@ version = "0.4.24" AxisArrays = "39de3d68-74b9-583c-8d2d-e117c070f3a9" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" IterableTables = "1c8ee90f-4401-5389-894e-7a04a3dc0f4d" @@ -20,17 +21,36 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" Tokenize = "0796e94c-ce3b-5d07-9a54-7f471281c624" Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" +[weakdeps] +RCall = "6f49c342-dc21-5d91-9882-a32aef131414" +Requires = "ae029012-a4dd-5104-9daa-d747884805df" + +[extensions] +PhyloRCallExt = "RCall" + [compat] AxisArrays = "0.4" -DataFrames = "^1" +DataFrames = "1" DataStructures = "0.17, 0.18" +Distances = "0.10" Distributions = "0.24, 0.25" -Graphs = "^1" -IterableTables = "^1" -Missings = "^1" -RecipesBase = "^1" -Requires = "^1" +Graphs = "1" +IterableTables = "1" +Missings = "1" +Printf = "1" +Random = "1" +RecipesBase = "1" +Requires = "1" SimpleTraits = "0.9" +Statistics = "1" Tokenize = "0.5" -Unitful = "^1" -julia = "^1" +Unitful = "1" +julia = "1" + +[extras] +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +RCall = "6f49c342-dc21-5d91-9882-a32aef131414" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["DataFrames", "RCall", "Test"] diff --git a/src/rcall.jl b/ext/PhyloRCallExt.jl similarity index 84% rename from src/rcall.jl rename to ext/PhyloRCallExt.jl index cb43527f..cf7c3851 100644 --- a/src/rcall.jl +++ b/ext/PhyloRCallExt.jl @@ -1,7 +1,20 @@ +module PhyloRCallExt + +if isdefined(Base, :get_extension) + using RCall + using RCall: protect, unprotect, rcall_p, RClass, isObject, isS4 + import RCall: rcopy + import RCall: rcopytype + import RCall: sexp +else + using ..RCall + using ..RCall: protect, unprotect, rcall_p, RClass, isObject, isS4 + import ..RCall: rcopy + import ..RCall: rcopytype + import ..RCall: sexp +end + using Phylo -using .RCall -using .RCall: protect, unprotect, rcall_p, RClass, isObject, isS4 -import .RCall: rcopy function rcopy(::Type{T}, rt::Ptr{VecSxp}) where T <: AbstractTree if !isObject(rt) || isS4(rt) || rcopy(String, rcall_p(:class, rt)) != "phylo" @@ -31,12 +44,9 @@ function rcopy(::Type{T}, rt::Ptr{VecSxp}) where T <: AbstractTree return tree end -import .RCall.rcopytype rcopytype(::Type{RClass{:phylo}}, s::Ptr{VecSxp}) = RootedTree -import .RCall.sexp - function sexp(tree::T) where T <: AbstractTree validate!(tree) || @warn "Tree does not internally validate" leafnames = getleafnames(tree) @@ -70,3 +80,5 @@ function sexp(tree::T) where T <: AbstractTree unprotect(1) return sobj end + +end diff --git a/src/Phylo.jl b/src/Phylo.jl index 8b5f21d1..503d1756 100644 --- a/src/Phylo.jl +++ b/src/Phylo.jl @@ -189,12 +189,15 @@ export distance, distances, heighttoroot, heightstoroot # Path into package path(path...; dir::String = "test") = joinpath(@__DIR__, "..", dir, path...) -using Requires +# This symbol is only defined on Julia versions that support extensions +if !isdefined(Base, :get_extension) + using Requires +end + +@static if !isdefined(Base, :get_extension) function __init__() - @require RCall="6f49c342-dc21-5d91-9882-a32aef131414" begin - println("Creating Phylo RCall interface...") - include("rcall.jl") - end + @require RCall="6f49c342-dc21-5d91-9882-a32aef131414" include("../ext/PhyloRCallExt.jl") +end end end # module diff --git a/test/Project.toml b/test/Project.toml deleted file mode 100644 index 8829214a..00000000 --- a/test/Project.toml +++ /dev/null @@ -1,6 +0,0 @@ -[deps] -DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -IterableTables = "1c8ee90f-4401-5389-894e-7a04a3dc0f4d" -RCall = "6f49c342-dc21-5d91-9882-a32aef131414" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/test/test_rcall.jl b/test/ext_PhyloRCallExt.jl similarity index 100% rename from test/test_rcall.jl rename to test/ext_PhyloRCallExt.jl diff --git a/test/runtests.jl b/test/runtests.jl index 7429e67c..315b67d4 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,24 +1,18 @@ +using Random using Test +using Phylo # Identify files in test/ that are testing matching files in src/ # - src/Source.jl will be matched by test/test_Source.jl - -filebase = map(file -> replace(file, r"(.*).jl$" => s"\1"), - filter(file -> occursin(r".*\.jl$", file), - readdir("../src"))) -testbase = map(file -> replace(file, r"test_(.*).jl$" => s"\1"), - filter(str -> occursin(r"^test_.*\.jl$", str), readdir())) - -println() -@info "Running tests for files:" -for t in testbase - println(" = $t.jl") +filebase = String[] +for (root, dirs, files) in walkdir("../src") + append!(filebase, + map(file -> replace(file, r"(.*).jl" => s"\1"), + filter(file -> occursin(r".*\.jl", file), files))) end -println() -@testset "* Testing $t.jl" for t in testbase - include("test_$t.jl") -end +testbase = map(file -> replace(file, r"test_(.*).jl" => s"\1"), + filter(str -> occursin(r"^test_.*\.jl$", str), readdir())) # Identify tests with no matching file superfluous = filter(f -> f ∉ filebase, testbase) @@ -32,16 +26,84 @@ if length(superfluous) > 0 end # Identify files with no matching test -missing = filter(f -> f ∉ testbase, filebase) -if length(missing) > 0 +notest = filter(f -> f ∉ testbase, filebase) +if length(notest) > 0 println() @info "Potentially missing tests:" - for f in missing + for f in notest println(" - $f.jl") end println() end +# Identify files in test/ that are testing matching files in ext/ +# - ext/SourceExt.jl will be matched by test/ext_SourceExt.jl +filebase = String[] +for (root, dirs, files) in walkdir("../ext") + append!(filebase, + map(file -> replace(file, r"(.*).jl" => s"\1"), + filter(file -> occursin(r".*\.jl", file), files))) +end + +extbase = map(file -> replace(file, r"ext_(.*).jl" => s"\1"), + filter(str -> occursin(r"^ext_.*\.jl$", str), readdir())) + +# Identify tests with no matching file +superfluous = filter(f -> f ∉ filebase, extbase) +if length(superfluous) > 0 + println() + @info "Potentially superfluous extension tests:" + for f in superfluous + println(" + $f.jl") + end + println() +end + +# Identify files with no matching test +notest = filter(f -> f ∉ extbase, filebase) +if length(notest) > 0 + println() + @info "Potentially missing extension tests:" + for f in notest + println(" - $f.jl") + end + println() +end + +# Seed RNG to make tests reproducible +Random.seed!(1234) + +@testset "Phylo.jl" begin + @test isfile(Phylo.path("runtests.jl")) + println() + @info "Running tests for files:" + for t in testbase + println(" = $t.jl") + end + println() + + @info "Running tests..." + @testset for t in testbase + fn = "test_$t.jl" + println(" * Testing $t.jl ...") + include(fn) + end + + println() + @info "Running tests for extensions:" + for t in extbase + println(" = $t.jl") + end + println() + + @info "Running extension tests..." + @testset for t in extbase + fn = "ext_$t.jl" + println(" * Testing $t.jl extension...") + include(fn) + end +end + # Identify files that are cross-validating results against other packages # test/pkg_Package.jl should validate results against the Package package @@ -50,13 +112,17 @@ pkgbase = map(file -> replace(file, r"pkg_(.*).jl$" => s"\1"), readdir())) if length(pkgbase) > 0 - @info "Running cross-validation against:" - for p in pkgbase - println(" = $p") - end - println() + @info "Cross validation packages:" + @testset begin + for p in pkgbase + println(" = $p") + end + println() - @testset " * Validating against $p" for p in pkgbase - include("pkg_$p.jl") + @testset for p in pkgbase + fn = "pkg_$p.jl" + println(" * Validating $p.jl ...") + include(fn) + end end end