From e3cc126bfc2ff8670c08a1549430bd55605beb8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 23 Aug 2023 16:30:04 -0400 Subject: [PATCH 1/3] improve pkg extensions tests - add tests for `DashBasePlotlyBaseExt` and `DashBasePlotlyJSExt` - all `DashBase.to_dash` method should return the same object after one call as `to_dash` is not called recursively. See - these new tests currently fail for both the `Plots`'s `plotly()` and `plotlyjs()` renderers. --- test/test_ext.jl | 51 +++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/test/test_ext.jl b/test/test_ext.jl index 4e5e889..7ebca1d 100644 --- a/test/test_ext.jl +++ b/test/test_ext.jl @@ -1,25 +1,36 @@ -using DashBase using Test -using Plots -plotlyjs() +using DashBase +import PlotlyBase +import PlotlyJS +import Plots + +function run_assertions(pl) + obj = @test_nowarn DashBase.to_dash(pl) + @test obj isa Dict{Symbol, Any} + @test obj[:data][1][:y] == [1, 2, 3, 4, 5] + @test haskey(obj, :layout) + @test haskey(obj, :frames) + @test !haskey(obj, :config) +end + +@testset "DashBasePlotlyBaseExt" begin + pl = PlotlyBase.Plot(1:5) + run_assertions(pl) +end + +@testset "DashBasePlotsJSExt" begin + pl = PlotlyJS.plot(1:5) + run_assertions(pl) +end -@testset "PlotlyJS" begin - pl = @test_nowarn DashBase.to_dash(plot(1:5)) - @test pl isa PlotlyJS.SyncPlot - pl = @test_nowarn DashBase.to_dash(pl) - @test haskey(pl, :layout) - @test haskey(pl, :data) - @test haskey(pl, :frames) - @test !haskey(pl, :config) +@testset "DashBasePlotsExt + plotlyjs()" begin + Plots.plotlyjs() + pl = Plots.plot(1:5) + run_assertions(pl) end -plotly() -@testset "PlotlyBase" begin - pl = @test_nowarn DashBase.to_dash(plot(1:5)) - @test pl isa PlotlyBase.Plot - pl = @test_nowarn DashBase.to_dash(pl) - @test haskey(pl, :layout) - @test haskey(pl, :data) - @test haskey(pl, :frames) - @test !haskey(pl, :config) +@testset "DashBasePlotsExt + plotly()" begin + Plots.plotly() + pl = Plots.plot(1:5) + run_assertions(pl) end From 5fd38d7e965a19c9440952837b9a68ab104521cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 23 Aug 2023 16:36:25 -0400 Subject: [PATCH 2/3] fix `to_dash` in `DashBasePlotsExt` so that they return `Dict`s, fixing potential infinite loop within `JSON3.write` calls --- ext/DashBasePlotsExt.jl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ext/DashBasePlotsExt.jl b/ext/DashBasePlotsExt.jl index a3a8ee0..4f56532 100644 --- a/ext/DashBasePlotsExt.jl +++ b/ext/DashBasePlotsExt.jl @@ -8,11 +8,16 @@ function DashBase.to_dash(p::Plots.Plot{Plots.PlotlyBackend}) return if haskey(Base.loaded_modules, Base.PkgId(Base.UUID("a03496cd-edff-5a9b-9e67-9cda94a718b5"), "PlotlyBase")) && haskey(Base.loaded_modules, Base.PkgId(Base.UUID("f2990250-8cf9-495f-b13a-cce12b45703c"), "PlotlyKaleido")) # Note: technically it would be sufficient if PlotlyBase is loaded, but thats how it is currently handled by Plots.jl - Plots.plotlybase_syncplot(p) + sp = Plots.plotlybase_syncplot(p) + DashBase.to_dash(sp) else - (data = Plots.plotly_series(p), layout = Plots.plotly_layout(p)) + Dict(:data => Plots.plotly_series(p), :layout => Plots.plotly_layout(p)) end end -DashBase.to_dash(p::Plots.Plot{Plots.PlotlyJSBackend}) = Plots.plotlyjs_syncplot(p) + +function DashBase.to_dash(p::Plots.Plot{Plots.PlotlyJSBackend}) + sp = Plots.plotlyjs_syncplot(p) + return DashBase.to_dash(sp) +end end From fce43fb5a65d5cb0e3e785f5bd088885db83ce30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Thu, 24 Aug 2023 12:02:45 -0400 Subject: [PATCH 3/3] replace with `PackageExtensionCompat` using `Requires` dance as suggested by https://pkgdocs.julialang.org/v1.9/creating-packages/#Requires.jl --- Project.toml | 26 +++++++++++++------------- ext/DashBasePlotlyBaseExt.jl | 8 +++++--- ext/DashBasePlotlyJSExt.jl | 5 +++-- ext/DashBasePlotsExt.jl | 4 ++-- src/DashBase.jl | 11 +++++++++-- 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/Project.toml b/Project.toml index 51efcbe..44ce0cf 100644 --- a/Project.toml +++ b/Project.toml @@ -5,26 +5,21 @@ version = "0.2.0" [deps] JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" -PackageExtensionCompat = "65ce6f38-6b18-4e1d-a461-8949797d7930" +Requires = "ae029012-a4dd-5104-9daa-d747884805df" -[weakdeps] -PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5" -PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" -Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +[compat] +JSON3 = "1" +PlotlyBase = "0.8" +PlotlyJS = "0.18" +Plots = "1" +Requires = "1.3" +julia = "1.6" [extensions] DashBasePlotlyBaseExt = "PlotlyBase" DashBasePlotlyJSExt = "PlotlyJS" DashBasePlotsExt = "Plots" -[compat] -JSON3 = "1" -Plots = "1" -julia = "1.6" -PlotlyBase = "0.8" -PlotlyJS = "0.18" -PackageExtensionCompat = "1" - [extras] PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5" PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" @@ -34,3 +29,8 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] test = ["Test", "Plots", "PlotlyBase", "PlotlyJS", "PlotlyKaleido"] + +[weakdeps] +PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5" +PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" diff --git a/ext/DashBasePlotlyBaseExt.jl b/ext/DashBasePlotlyBaseExt.jl index 2a7e243..903af3a 100644 --- a/ext/DashBasePlotlyBaseExt.jl +++ b/ext/DashBasePlotlyBaseExt.jl @@ -1,8 +1,10 @@ module DashBasePlotlyBaseExt -import DashBase -import PlotlyBase -import PlotlyBase.JSON +using DashBase + +isdefined(Base, :get_extension) ? (using PlotlyBase) : (using ..PlotlyBase) + +const JSON = PlotlyBase.JSON function DashBase.to_dash(p::PlotlyBase.Plot) data = JSON.lower(p) diff --git a/ext/DashBasePlotlyJSExt.jl b/ext/DashBasePlotlyJSExt.jl index ff0e012..985fcd5 100644 --- a/ext/DashBasePlotlyJSExt.jl +++ b/ext/DashBasePlotlyJSExt.jl @@ -1,7 +1,8 @@ module DashBasePlotlyJSExt -import PlotlyJS -import DashBase +using DashBase + +isdefined(Base, :get_extension) ? (using PlotlyJS) : (using ..PlotlyJS) function DashBase.to_dash(p::PlotlyJS.SyncPlot) DashBase.to_dash(p.plot) diff --git a/ext/DashBasePlotsExt.jl b/ext/DashBasePlotsExt.jl index 4f56532..56fc08b 100644 --- a/ext/DashBasePlotsExt.jl +++ b/ext/DashBasePlotsExt.jl @@ -1,8 +1,8 @@ module DashBasePlotsExt -import Plots -import DashBase +using DashBase +isdefined(Base, :get_extension) ? (using Plots) : (using ..Plots) function DashBase.to_dash(p::Plots.Plot{Plots.PlotlyBackend}) return if haskey(Base.loaded_modules, Base.PkgId(Base.UUID("a03496cd-edff-5a9b-9e67-9cda94a718b5"), "PlotlyBase")) && diff --git a/src/DashBase.jl b/src/DashBase.jl index 88ac6ce..7833e7f 100644 --- a/src/DashBase.jl +++ b/src/DashBase.jl @@ -1,6 +1,5 @@ module DashBase import JSON3 -import PackageExtensionCompat include("components.jl") include("registry.jl") export Component, push_prop!, get_name, get_type, get_namespace, @@ -9,8 +8,16 @@ get_dash_dependencies, get_dash_renderer_pkg, get_componens_pkgs, has_relative_path, has_dev_path, has_external_url, get_type, get_external_url, get_dev_path, get_relative_path +@static if !isdefined(Base, :get_extension) +using Requires +end + function __init__() - PackageExtensionCompat.@require_extensions + @static if !isdefined(Base, :get_extension) + @require PlotlyBase = "a03496cd-edff-5a9b-9e67-9cda94a718b5" include("../ext/DashBasePlotlyBaseExt.jl") + @require PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" include("../ext/DashBasePlotlyJSExt.jl") + @require Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" include("../ext/DashBasePlotsExt.jl") + end end end # module