Skip to content

Commit

Permalink
Refactor testsets, fixes #25
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelHatherly committed Feb 6, 2024
1 parent 7c65fd4 commit ae41143
Show file tree
Hide file tree
Showing 16 changed files with 608 additions and 572 deletions.
584 changes: 14 additions & 570 deletions test/runtests.jl

Large diffs are not rendered by default.

108 changes: 108 additions & 0 deletions test/testsets/cell_options.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
include("../utilities/prelude.jl")

# Julia 1.6 doesn't support testing error messages, yet
macro test_throws_message(message::String, exp)
quote
threw_exception = false
try
$(esc(exp))
catch e
threw_exception = true
@test occursin($message, e.msg) # Currently only works for ErrorException
end
@test threw_exception
end
end

@testset "cell options" begin
mktempdir() do dir
@testset "Invalid cell option" begin
text = """
```{julia}
#| valid: true
```
"""
@test QuartoNotebookRunner.extract_cell_options(
text;
file = "file.qmd",
line = 1,
) == Dict("valid" => true)

text = """
```{julia}
#| valid: true
#| invalid
```
"""
@test_throws_message "file.qmd:1" QuartoNotebookRunner.extract_cell_options(
text;
file = "file.qmd",
line = 1,
)

text = """
```{julia}
a = 1
```
"""
@test QuartoNotebookRunner.extract_cell_options(
text;
file = "file.qmd",
line = 1,
) == Dict()

notebook = joinpath(dir, "notebook.qmd")
write(
notebook,
"""
---
title: "Invalid cell option"
---
```{julia}
#| this is not yaml
```
""",
)

server = QuartoNotebookRunner.Server()

buffer = IOBuffer()
@test_throws_message "Error parsing cell attributes" QuartoNotebookRunner.run!(
server,
notebook;
output = buffer,
showprogress = false,
)

close!(server)
end
@testset "Invalid eval option" begin
notebook = joinpath(dir, "notebook.qmd")
write(
notebook,
"""
---
title: "Invalid eval option"
---
```{julia}
#| eval: 1
```
""",
)

server = QuartoNotebookRunner.Server()

buffer = IOBuffer()
@test_throws_message "Cannot handle an `eval` code cell option with value 1, only true or false." QuartoNotebookRunner.run!(
server,
notebook;
output = buffer,
showprogress = false,
)

close!(server)
end
end
end
104 changes: 104 additions & 0 deletions test/testsets/const_redefinition.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
include("../utilities/prelude.jl")

@testset "Const redefinition" begin
mktempdir() do dir
# Ensure that when we update a running notebook and try to re-evaluate
# cells that contain const definitions that have changed, e.g. structs
# or consts that we still get the correct output and not redefinition
# errors.
notebook = joinpath(dir, "notebook.qmd")
write(
notebook,
"""
---
title: "Const redefinition"
---
```{julia}
struct T
x::Int
end
```
```{julia}
const t = T(1)
```
""",
)

server = QuartoNotebookRunner.Server()

buffer = IOBuffer()
QuartoNotebookRunner.run!(server, notebook; output = buffer, showprogress = false)

seekstart(buffer)
json = JSON3.read(buffer, Any)

@test JSONSchema.validate(SCHEMA, json) === nothing

cells = json["cells"]

cell = cells[2]
@test only(cell["outputs"]) == Dict(
"output_type" => "execute_result",
"execution_count" => 1,
"data" => Dict(),
"metadata" => Dict(),
)

cell = cells[4]
@test only(cell["outputs"]) == Dict(
"output_type" => "execute_result",
"execution_count" => 1,
"data" => Dict("text/plain" => "T(1)"),
"metadata" => Dict(),
)

write(
notebook,
"""
---
title: "Const redefinition"
---
```{julia}
struct T
x::String
end
```
```{julia}
const t = T("")
```
""",
)

buffer = IOBuffer()
QuartoNotebookRunner.run!(server, notebook; output = buffer, showprogress = false)

seekstart(buffer)
json = JSON3.read(buffer, Any)

@test JSONSchema.validate(SCHEMA, json) === nothing

cells = json["cells"]

cell = cells[2]
@test only(cell["outputs"]) == Dict(
"output_type" => "execute_result",
"execution_count" => 1,
"data" => Dict(),
"metadata" => Dict(),
)

cell = cells[4]
@test only(cell["outputs"]) == Dict(
"output_type" => "execute_result",
"execution_count" => 1,
"data" => Dict("text/plain" => "T(\"\")"),
"metadata" => Dict(),
)

close!(server)
end
end
2 changes: 1 addition & 1 deletion test/testsets/error_configuration/01.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Logging, Test, QuartoNotebookRunner
include("../../utilities/prelude.jl")

@testset "error_configuration/01" begin
server = Server()
Expand Down
2 changes: 1 addition & 1 deletion test/testsets/error_configuration/02.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Logging, Test, QuartoNotebookRunner
include("../../utilities/prelude.jl")

@testset "error_configuration/02" begin
server = Server()
Expand Down
54 changes: 54 additions & 0 deletions test/testsets/non_standard_mimetypes.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
include("../utilities/prelude.jl")

@testset "non-standard mime types" begin
mktempdir() do dir
server = QuartoNotebookRunner.Server()
expected = Dict("typst" => "```{=typst}", "docx" => "```{=openxml}")

env = joinpath(dir, "integrations", "CairoMakie")
mkpath(env)
cp(joinpath(@__DIR__, "../examples/integrations/CairoMakie"), env; force = true)

for (format, ext) in ("typst" => "pdf", "docx" => "docx")
cd(dir) do
source = joinpath(@__DIR__, "../examples/$(format)_mimetypes.qmd")
content = read(source, String)
write("$(format)_mimetypes.qmd", content)
ipynb = "$(format)_mimetypes.ipynb"
QuartoNotebookRunner.run!(
server,
"$(format)_mimetypes.qmd";
output = ipynb,
showprogress = false,
options = Dict{String,Any}(
"format" => Dict("pandoc" => Dict("to" => format)),
),
)

json = JSON3.read(ipynb)
markdown = json.cells[end].outputs[1].data["text/markdown"]
@test contains(markdown, expected[format])

if !Sys.iswindows()
# No macOS ARM build, so just look for a local version that the dev
# should have installed. This avoids having to use rosetta2 to run
# the x86_64 version of Julia to get access to the x86_64 version of
# Quarto artifact.
quarto_bin =
quarto_jll.is_available() ? quarto_jll.quarto() : setenv(`quarto`)
# Just a smoke test to make sure it runs. Use docx since it doesn't
# output a bunch of folders (html), or require a tinytex install
# (pdf). All we are doing here at the moment is ensuring quarto doesn't
# break on our notebook outputs.
if success(`$quarto_bin --version`)
@test success(`$quarto_bin render $ipynb --to $format`)
else
@error "quarto not found, skipping smoke test."
end
@test isfile("$(format)_mimetypes.$ext")
end
end
end
close!(server)
end
end
78 changes: 78 additions & 0 deletions test/testsets/package_integration_hooks.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
include("../utilities/prelude.jl")

@testset "package integration hooks" begin
mktempdir() do dir
env_dir = joinpath(@__DIR__, "../examples/integrations/CairoMakie")
content =
read(joinpath(@__DIR__, "../examples/integrations/CairoMakie.qmd"), String)
cd(dir) do
server = QuartoNotebookRunner.Server()

cp(env_dir, joinpath(dir, "CairoMakie"))

function png_metadata(preamble = nothing)
# handle Windows
content_unified = replace(content, "\r\n" => "\n")
_content =
preamble === nothing ? content_unified :
replace(content_unified, """
fig-width: 4
fig-height: 3
fig-dpi: 150""" => preamble)

write("CairoMakie.qmd", _content)
json = QuartoNotebookRunner.run!(
server,
"CairoMakie.qmd";
showprogress = false,
)
return json.cells[end].outputs[1].metadata["image/png"]
end

metadata = png_metadata()
@test metadata.width == 4 * 150
@test metadata.height == 3 * 150

metadata = png_metadata("""
fig-width: 8
fig-height: 6
fig-dpi: 300""")
@test metadata.width == 8 * 300
@test metadata.height == 6 * 300

metadata = png_metadata("""
fig-width: 5
fig-dpi: 100""")
@test metadata.width == 5 * 100
@test metadata.height == round(5 / 4 * 3 * 100)

metadata = png_metadata("""
fig-height: 5
fig-dpi: 100""")
@test metadata.height == 5 * 100
@test metadata.width == round(5 / 3 * 4 * 100)

# we don't want to rely on hardcoding Makie's own default size for our tests
# but for the dpi-only test we can check that doubling the
# dpi doubles image dimensions, whatever they are
metadata_100dpi = png_metadata("""
fig-dpi: 96""")
metadata_200dpi = png_metadata("""
fig-dpi: 192""")
@test 2 * metadata_100dpi.height == metadata_200dpi.height
@test 2 * metadata_100dpi.width == metadata_200dpi.width

# same logic for width and height only
metadata_single = png_metadata("""
fig-width: 3
fig-height: 2""")
metadata_double = png_metadata("""
fig-width: 6
fig-height: 4""")
@test 2 * metadata_single.height == metadata_double.height
@test 2 * metadata_single.width == metadata_double.width

close!(server)
end
end
end
Loading

0 comments on commit ae41143

Please sign in to comment.