diff --git a/.github/workflows/documenter.yml b/.github/workflows/documenter.yml index 22d59df..50f7b3d 100644 --- a/.github/workflows/documenter.yml +++ b/.github/workflows/documenter.yml @@ -28,7 +28,7 @@ jobs: - uses: actions/checkout@v2 - uses: julia-actions/setup-julia@v1 with: - version: 1.8 + version: 1 - uses: julia-actions/cache@v1 with: cache-compiled: "true" diff --git a/test/Project.toml b/test/Project.toml index 8d9efce..cfdfe2a 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -7,6 +7,8 @@ MixedModels = "ff71e718-51f3-5ec2-a782-8ffcbfa3c316" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +TestSetExtensions = "98d24dd4-01ad-11ea-1b02-c9a08f80db04" [compat] Aqua = "0.5, 0.6" +TestSetExtensions = "3" diff --git a/test/caterpillar.jl b/test/caterpillar.jl new file mode 100644 index 0000000..9ad5bf1 --- /dev/null +++ b/test/caterpillar.jl @@ -0,0 +1,42 @@ +f = caterpillar(m1; vline_at_zero=true) +@test save(joinpath(OUTDIR, "cat_sleepstudy.png"), f) + +f = caterpillar(m2, :subj) +@test save(joinpath(OUTDIR, "cat_kb07_subj.png"), f) + +f = caterpillar(m2, :item) +@test save(joinpath(OUTDIR, "cat_kb07_item.png"), f) + +f = caterpillar(m2, :subj; cols=[:("load: yes"), :("prec: maintain")], orderby=2) +@test save(joinpath(OUTDIR, "cat_kb07_subj_ordered_cols.png"), f) + +@test_throws ArgumentError caterpillar(m2, :subj; cols=[:("load: no")]) + +f = caterpillar(g1) +@test save(joinpath(OUTDIR, "cat_verbagg.png"), f) + +f = qqcaterpillar(m1; vline_at_zero=true) +@test save(joinpath(OUTDIR, "qqcat_sleepstudy.png"), f) + +f = qqcaterpillar(m2, :subj) +@test save(joinpath(OUTDIR, "qqcat_kb07_subj.png"), f) + +f = qqcaterpillar(m2, :item) +@test save(joinpath(OUTDIR, "qqcat_kb07_item.png"), f) + +f = qqcaterpillar(g1) +@test save(joinpath(OUTDIR, "qqcat_verbagg.png"), f) + +let f = Figure(; size=(1000, 600)) + gl = f[1, 1] = GridLayout() + re = ranefinfo(m2) + qqcaterpillar!(gl, re[:item]) + Label(gl[end + 1, :], "Item"; font=:bold) + gl = f[1, 2] = GridLayout() + qqcaterpillar!(gl, re[:subj]) + Label(gl[end + 1, :], "Subject"; font=:bold) + Label(f[0, :], "Conditional Modes") + colsize!(f.layout, 1, Auto(0.5)) + save(joinpath(OUTDIR, "qqcat_kb07_joint.png"), f) + f +end diff --git a/test/clevelandaxes.jl b/test/clevelandaxes.jl new file mode 100644 index 0000000..56a1885 --- /dev/null +++ b/test/clevelandaxes.jl @@ -0,0 +1,26 @@ +f = clevelandaxes!(Figure(), ["S$(lpad(i, 2))" for i in 1:16], (4, 4)) +n = 12 +# Hack to determine whether we're using Makie 0.19 by looking for a characteristic +# breaking change. This can be safely removed once the package requires Makie v0.19 +# at a minimum. +local text! +try + Makie.text!(Axis(Figure()[1, 1]), "test"; textsize=69) + text! = (args...; fontsize, kwargs...) -> Makie.text!(args...; + textsize=fontsize, + kwargs...) +catch err + if err isa ArgumentError && occursin("Makie v0.19", sprint(showerror, err)) + text! = Makie.text! + else + rethrow(err) + end +end +for i in 1:4, j in 1:4 + x = randn(MersenneTwister(i), n) + y = randn(MersenneTwister(j), n) + scatter!(f[i, j], x, y) + text!(f[i, j], 1.9, -1.9; + text="[$i, $j]", align=(:center, :center), fontsize=14) +end +@test save(joinpath(OUTDIR, "clevelandaxes.png"), f) diff --git a/test/coefplot.jl b/test/coefplot.jl new file mode 100644 index 0000000..273f1e2 --- /dev/null +++ b/test/coefplot.jl @@ -0,0 +1,5 @@ +f = coefplot(m1) +@test save(joinpath(OUTDIR, "coef_sleepstudy.png"), f) + +f = coefplot(b1) +@test save(joinpath(OUTDIR, "coef_sleepstudy_boot.png"), f) diff --git a/test/profile.jl b/test/profile.jl new file mode 100644 index 0000000..001f172 --- /dev/null +++ b/test/profile.jl @@ -0,0 +1,9 @@ +pr1 = profile(m1) +for ptyp in ['σ', 'θ', 'β'], toggle in [true, false] + local f + f = zetaplot(pr1; ptyp, absv=toggle) + save(joinpath(OUTDIR, "zetaplot_$(ptyp)_$(toggle).png"), f) + + f = profiledensity(pr1; ptyp, share_y_scale=toggle) + save(joinpath(OUTDIR, "profiledensity_$(ptyp)_$(toggle).png"), f) +end diff --git a/test/recipes.jl b/test/recipes.jl new file mode 100644 index 0000000..a78debd --- /dev/null +++ b/test/recipes.jl @@ -0,0 +1,7 @@ +@test_logs (:warn, "qqline=:R is a deprecated value, use qqline=:fitrobust instead.") match_mode = :any qqnorm(m1; + qqline=:R) +f = qqnorm(m1; qqline=:fitrobust) +@test save(joinpath(OUTDIR, "qqnorm_sleepstudy_fitrobust.png"), f) + +f = qqplot(Normal(0, m1.σ), m1) +@test save(joinpath(OUTDIR, "qqplot_sleepstud.png"), f) diff --git a/test/ridge2d.jl b/test/ridge2d.jl new file mode 100644 index 0000000..ef9be1d --- /dev/null +++ b/test/ridge2d.jl @@ -0,0 +1,6 @@ +@test_throws(ArgumentError("No parameters x found."), + ridge2d(b1; ptype=:x)) +@test_throws(ArgumentError("Only 1 ρ-parameter found: 2D plots require at least 2."), + ridge2d(b1; ptype=:ρ)) +@test save(joinpath(OUTDIR, "ridge2d_beta.png"), ridge2d(b1)) +@test save(joinpath(OUTDIR, "ridge2d_sigma.png"), ridge2d(b1; ptype=:σ)) diff --git a/test/ridgeplot.jl b/test/ridgeplot.jl new file mode 100644 index 0000000..5cc611a --- /dev/null +++ b/test/ridgeplot.jl @@ -0,0 +1,2 @@ +f = ridgeplot(b1) +@test save(joinpath(OUTDIR, "ridge_sleepstudy.png"), f) diff --git a/test/runtests.jl b/test/runtests.jl index f6d07db..99c45c6 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -6,20 +6,17 @@ using MixedModelsMakie using Random # we don't depend on exact PRNG vals, so no need for StableRNGs using Statistics using Test +using TestSetExtensions using MixedModelsMakie: confint_table const OUTDIR = joinpath(pkgdir(MixedModelsMakie), "test", "output") const progress = false -@testset "Aqua" begin - # we can't check for unbound type parameters - # because we actually need one at one point for _same_family() - Aqua.test_all(MixedModels; ambiguities=false, unbound_args=false) -end - -@testset "utilities, types and tables" begin - include("utils_and_types.jl") +function save(path, obj, args...; kwargs...) + isfile(path) && rm(path) + Makie.save(path, obj, args...; kwargs...) + return isfile(path) end m1 = fit(MixedModel, @@ -44,155 +41,30 @@ g1 = fit(MixedModel, MixedModels.dataset(:verbagg), Bernoulli(); progress) -@testset "[qq]caterpillar" begin - f = caterpillar(m1; vline_at_zero=true) - save(joinpath(OUTDIR, "cat_sleepstudy.png"), f) - - f = caterpillar(m2, :subj) - save(joinpath(OUTDIR, "cat_kb07_subj.png"), f) - - f = caterpillar(m2, :item) - save(joinpath(OUTDIR, "cat_kb07_item.png"), f) - - f = caterpillar(m2, :subj; cols=[:("load: yes"), :("prec: maintain")], orderby=2) - save(joinpath(OUTDIR, "cat_kb07_subj_ordered_cols.png"), f) - - @test_throws ArgumentError caterpillar(m2, :subj; cols=[:("load: no")]) - - f = caterpillar(g1) - save(joinpath(OUTDIR, "cat_verbagg.png"), f) - - f = qqcaterpillar(m1; vline_at_zero=true) - save(joinpath(OUTDIR, "qqcat_sleepstudy.png"), f) - - f = qqcaterpillar(m2, :subj) - save(joinpath(OUTDIR, "qqcat_kb07_subj.png"), f) - - f = qqcaterpillar(m2, :item) - save(joinpath(OUTDIR, "qqcat_kb07_item.png"), f) - - f = qqcaterpillar(g1) - save(joinpath(OUTDIR, "qqcat_verbagg.png"), f) - - let f = Figure(; size=(1000, 600)) - gl = f[1, 1] = GridLayout() - re = ranefinfo(m2) - qqcaterpillar!(gl, re[:item]) - Label(gl[end + 1, :], "Item"; font=:bold) - gl = f[1, 2] = GridLayout() - qqcaterpillar!(gl, re[:subj]) - Label(gl[end + 1, :], "Subject"; font=:bold) - Label(f[0, :], "Conditional Modes") - colsize!(f.layout, 1, Auto(0.5)) - save(joinpath(OUTDIR, "qqcat_kb07_joint.png"), f) - f - end -end - -@testset "clevelandaxes" begin - f = clevelandaxes!(Figure(), ["S$(lpad(i, 2))" for i in 1:16], (4, 4)) - n = 12 - # Hack to determine whether we're using Makie 0.19 by looking for a characteristic - # breaking change. This can be safely removed once the package requires Makie v0.19 - # at a minimum. - local text! - try - Makie.text!(Axis(Figure()[1, 1]), "test"; textsize=69) - text! = (args...; fontsize, kwargs...) -> Makie.text!(args...; - textsize=fontsize, - kwargs...) - catch err - if err isa ArgumentError && occursin("Makie v0.19", sprint(showerror, err)) - text! = Makie.text! - else - rethrow(err) - end - end - for i in 1:4, j in 1:4 - x = randn(MersenneTwister(i), n) - y = randn(MersenneTwister(j), n) - scatter!(f[i, j], x, y) - text!(f[i, j], 1.9, -1.9; - text="[$i, $j]", align=(:center, :center), fontsize=14) +@testset ExtendedTestSet "MixedModelsMakie.jl" begin + @testset "Aqua" begin + # we can't check for unbound type parameters + # because we actually need one at one point for _same_family() + Aqua.test_all(MixedModels; ambiguities=false, unbound_args=false) end - save(joinpath(OUTDIR, "clevelandaxes.png"), f) -end - -@testset "coefplot" begin - f = coefplot(m1) - save(joinpath(OUTDIR, "coef_sleepstudy.png"), f) - - f = coefplot(b1) - save(joinpath(OUTDIR, "coef_sleepstudy_boot.png"), f) -end - -@testset "recipes" begin - @test_logs (:warn, "qqline=:R is a deprecated value, use qqline=:fitrobust instead.") match_mode = :any qqnorm(m1; - qqline=:R) - f = qqnorm(m1; qqline=:fitrobust) - save(joinpath(OUTDIR, "qqnorm_sleepstudy_fitrobust.png"), f) - - f = qqplot(Normal(0, m1.σ), m1) - save(joinpath(OUTDIR, "qqplot_sleepstud.png"), f) -end - -@testset "ridgeplot" begin - f = ridgeplot(b1) - save(joinpath(OUTDIR, "ridge_sleepstudy.png"), f) -end - -@testset "ridge2d" begin - @test_throws(ArgumentError("No parameters x found."), - ridge2d(b1; ptype=:x)) - @test_throws(ArgumentError("Only 1 ρ-parameter found: 2D plots require at least 2."), - ridge2d(b1; ptype=:ρ)) - save(joinpath(OUTDIR, "ridge2d_beta.png"), ridge2d(b1)) - save(joinpath(OUTDIR, "ridge2d_sigma.png"), ridge2d(b1; ptype=:σ)) -end - -@testset "shrinkageplot" begin - f = shrinkageplot(m1) - save(joinpath(OUTDIR, "shrinkage_sleepstudy.png"), f) - f = shrinkageplot(m2, :item) - save(joinpath(OUTDIR, "shrinkage_kb07_item.png"), f) + @testset "utilities, types and tables" include("utils_and_types.jl") - f = shrinkageplot(m2, :subj) - save(joinpath(OUTDIR, "shrinkage_kb07_subj.png"), f) + @testset "[qq]caterpillar" include("caterpillar.jl") - f = shrinkageplot(m2; ellipse=true) - save(joinpath(OUTDIR, "shrinkage_kb07_subj_ellipse.png"), f) + @testset "clevelandaxes" include("clevelandaxes.jl") - f = shrinkageplot(m2; ellipse=true, cols=["spkr: old", "prec: maintain", "(Intercept)"]) - save(joinpath(OUTDIR, "shrinkage_kb07_subj_cols.png"), f) + @testset "coefplot" include("coefplot.jl") - @test_throws(ArgumentError("At least two columns must be specified."), - shrinkageplot(m2; ellipse=true, cols=["spkr: old"])) + @testset "recipes" include("recipes.jl") - f = shrinkageplot(m2; ellipse=true, ellipse_scale=2) - save(joinpath(OUTDIR, "shrinkage_kb07_subj_ellipse_scaled.png"), f) + @testset "ridgeplot" include("ridgeplot.jl") - f = shrinkageplot(g1, :item) - save(joinpath(OUTDIR, "shrinkage_verbagg.png"), f) + @testset "ridge2d" include("ridge2d.jl") - f = shrinkageplot(g1, :item; ellipse=true, n_ellipse=2) - save(joinpath(OUTDIR, "shrinkage_verbagg_ellipse.png"), f) -end - -@testset "splom!" begin - df = DataFrame(MixedModels.dataset(:mmec)) - splof = @test_logs (:info, - r"Ignoring 3 non-numeric columns") splom!(Figure(), df) - save(joinpath(OUTDIR, "splom_mmec.png"), splof) -end + @testset "shrinkageplot" include("shrinkageplot.jl") -@testset "profile" begin - pr1 = profile(m1) - for ptyp in ['σ', 'θ', 'β'], toggle in [true, false] - f = zetaplot(pr1; ptyp, absv=toggle) - save(joinpath(OUTDIR, "zetaplot_$(ptyp)_$(toggle).png"), f) + @testset "splom!" include("splom.jl") - f = profiledensity(pr1; ptyp, share_y_scale=toggle) - save(joinpath(OUTDIR, "profiledensity_$(ptyp)_$(toggle).png"), f) - end + @testset "profile" include("profile.jl") end diff --git a/test/shrinkageplot.jl b/test/shrinkageplot.jl new file mode 100644 index 0000000..827054f --- /dev/null +++ b/test/shrinkageplot.jl @@ -0,0 +1,26 @@ +f = shrinkageplot(m1) +@test save(joinpath(OUTDIR, "shrinkage_sleepstudy.png"), f) + +f = shrinkageplot(m2, :item) +@test save(joinpath(OUTDIR, "shrinkage_kb07_item.png"), f) + +f = shrinkageplot(m2, :subj) +@test save(joinpath(OUTDIR, "shrinkage_kb07_subj.png"), f) + +f = shrinkageplot(m2; ellipse=true) +@test save(joinpath(OUTDIR, "shrinkage_kb07_subj_ellipse.png"), f) + +f = shrinkageplot(m2; ellipse=true, cols=["spkr: old", "prec: maintain", "(Intercept)"]) +@test save(joinpath(OUTDIR, "shrinkage_kb07_subj_cols.png"), f) + +@test_throws(ArgumentError("At least two columns must be specified."), + shrinkageplot(m2; ellipse=true, cols=["spkr: old"])) + +f = shrinkageplot(m2; ellipse=true, ellipse_scale=2) +@test save(joinpath(OUTDIR, "shrinkage_kb07_subj_ellipse_scaled.png"), f) + +f = shrinkageplot(g1, :item) +@test save(joinpath(OUTDIR, "shrinkage_verbagg.png"), f) + +f = shrinkageplot(g1, :item; ellipse=true, n_ellipse=2) +@test save(joinpath(OUTDIR, "shrinkage_verbagg_ellipse.png"), f) diff --git a/test/splom.jl b/test/splom.jl new file mode 100644 index 0000000..613a7d6 --- /dev/null +++ b/test/splom.jl @@ -0,0 +1,4 @@ +df = DataFrame(MixedModels.dataset(:mmec)) +splof = @test_logs (:info, + r"Ignoring 3 non-numeric columns") splom!(Figure(), df) +@test save(joinpath(OUTDIR, "splom_mmec.png"), splof)