Skip to content

Commit 2a0cd7c

Browse files
authored
tests - make theme tests run locally (#239)
* tests - make theme tests run locally * Add missing Suggests * don't try to keep stack trace in snapshot, just hide it
1 parent 6c13f0c commit 2a0cd7c

File tree

5 files changed

+97
-44
lines changed

5 files changed

+97
-44
lines changed

DESCRIPTION

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ Imports:
2929
utils,
3030
yaml
3131
Suggests:
32+
callr,
3233
curl,
34+
dplyr,
3335
flextable,
3436
ggiraph,
3537
ggplot2,
@@ -38,6 +40,7 @@ Suggests:
3840
knitr,
3941
palmerpenguins,
4042
patchwork,
43+
pkgload,
4144
plotly,
4245
rsconnect (>= 0.8.26),
4346
testthat (>= 3.1.7),

tests/testthat/_snaps/quarto.md

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,7 @@
2020
ERROR: Book chapter 'intro.qmd' not found
2121
2222
Stack trace:
23-
at throwInputNotFound (<quarto.js full path with location>)
24-
at findInputs (<quarto.js full path with location>)
25-
at eventLoopTick (ext:core/01_core.js:175:7)
26-
at async findChapters (<quarto.js full path with location>)
27-
at async bookRenderItems (<quarto.js full path with location>)
28-
at async Object.bookProjectConfig [as config] (<quarto.js full path with location>)
29-
at async projectContext (<quarto.js full path with location>)
30-
at async inspectConfig (<quarto.js full path with location>)
31-
at async Command.actionHandler (<quarto.js full path with location>)
32-
at async Command.execute (<quarto.js full path with location>)
23+
<stack trace>
3324
3425
Caused by error:
3526
! System command 'quarto' failed

tests/testthat/helper.R

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,13 @@ local_quarto_project <- function(
9191
return(file.path(path_tmp, name))
9292
}
9393

94-
.render <- function(input, output_file = NULL, ..., .env = parent.frame()) {
94+
.render <- function(
95+
input,
96+
output_file = NULL,
97+
...,
98+
.quiet = TRUE,
99+
.env = parent.frame()
100+
) {
95101
skip_if_no_quarto()
96102
skip_if_not_installed("withr")
97103
# work inside input directory
@@ -102,7 +108,12 @@ local_quarto_project <- function(
102108
.local_envir = .env
103109
))
104110
}
105-
quarto_render(basename(input), output_file = output_file, quiet = TRUE, ...)
111+
expect_no_error(quarto_render(
112+
basename(input),
113+
output_file = output_file,
114+
quiet = .quiet,
115+
...
116+
))
106117
expect_true(file.exists(output_file))
107118
normalizePath(output_file)
108119
}
@@ -134,7 +145,8 @@ expect_snapshot_qmd_output <- function(name, input, output_file = NULL, ...) {
134145
transform_quarto_cli_in_output <- function(
135146
full_path = FALSE,
136147
version = FALSE,
137-
dir_only = FALSE
148+
dir_only = FALSE,
149+
hide_stack = FALSE
138150
) {
139151
hide_path <- function(lines, real_path) {
140152
gsub(
@@ -147,6 +159,38 @@ transform_quarto_cli_in_output <- function(
147159

148160
return(
149161
function(lines) {
162+
if (hide_stack) {
163+
# Hide possible stack first
164+
stack_trace_index <- which(grepl("\\s*Stack trace\\:", lines))
165+
if (
166+
length(stack_trace_index) > 0 && stack_trace_index < length(lines)
167+
) {
168+
at_lines_indices <- which(grepl("^\\s*at ", lines))
169+
at_lines_after_stack <- at_lines_indices[
170+
at_lines_indices > stack_trace_index
171+
]
172+
if (length(at_lines_after_stack) > 0) {
173+
# Find the continuous sequence (no gaps)
174+
gaps <- diff(at_lines_after_stack) > 1
175+
end_pos <- if (any(gaps)) which(gaps)[1] else
176+
length(at_lines_after_stack)
177+
consecutive_indices <- at_lines_after_stack[1:end_pos]
178+
179+
stack_line <- lines[stack_trace_index]
180+
indentation <- regmatches(stack_line, regexpr("^\\s*", stack_line))
181+
lines[consecutive_indices[1]] <- paste0(
182+
indentation,
183+
"<stack trace>"
184+
)
185+
if (length(consecutive_indices) > 1) {
186+
lines <- lines[
187+
-consecutive_indices[2:length(consecutive_indices)]
188+
]
189+
}
190+
}
191+
}
192+
}
193+
150194
if (full_path) {
151195
quarto_found <- find_quarto()
152196
if (dir_only) {
@@ -207,3 +251,34 @@ local_quarto_run_echo_cmd <- function(.env = parent.frame()) {
207251
withr::local_options(quarto.echo_cmd = TRUE, .local_envir = .env)
208252
}
209253
}
254+
255+
quick_install <- function(package, lib, quiet = TRUE) {
256+
skip_if_not_installed("callr")
257+
opts <- c(
258+
"--data-compress=none",
259+
"--no-byte-compile",
260+
"--no-data",
261+
"--no-demo",
262+
"--no-docs",
263+
"--no-help",
264+
"--no-html",
265+
"--no-libs",
266+
"--use-vanilla",
267+
sprintf("--library=%s", lib),
268+
package
269+
)
270+
invisible(callr::rcmd("INSTALL", opts, show = !quiet, fail_on_status = TRUE))
271+
}
272+
273+
install_dev_package <- function(.local_envir = parent.frame()) {
274+
# if not inside of R CMD check, install dev version into temp directory
275+
if (Sys.getenv("_R_CHECK_TIMINGS_") == "") {
276+
skip_if_not_installed("pkgload")
277+
withr::local_temp_libpaths(.local_envir = .local_envir)
278+
quick_install(pkgload::pkg_path("."), lib = .libPaths()[1])
279+
withr::local_envvar(
280+
R_LIBS = paste0(.libPaths(), collapse = .Platform$path.sep),
281+
.local_envir = .local_envir
282+
)
283+
}
284+
}

tests/testthat/test-quarto.R

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ test_that("quarto_run report full quarto cli error message", {
2929
quarto_inspect(),
3030
transform = transform_quarto_cli_in_output(
3131
full_path = TRUE,
32-
dir_only = TRUE
32+
dir_only = TRUE,
33+
hide_stack = TRUE
3334
)
3435
)
3536
})

tests/testthat/test-theme.R

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,31 @@
1+
# don't run on CRAN - this require installed Quarto version with the right version of the quarto package.
2+
skip_on_cran()
3+
skip_if_no_quarto()
4+
skip_if_not_installed("withr")
5+
6+
# We need to install the package in a temporary library when we are in dev mode
7+
install_dev_package()
18

29
test_that("render flextable", {
3-
skip_if_no_quarto()
4-
quarto_render("theme/flextable.qmd", quiet = TRUE)
5-
expect_true(file.exists("theme/flextable.html"))
6-
unlink("theme/flextable.html")
10+
.render(test_path("theme/flextable.qmd"))
711
})
812

9-
1013
test_that("render ggiraph", {
11-
skip_if_no_quarto()
12-
quarto_render("theme/ggiraph.qmd", quiet = TRUE)
13-
expect_true(file.exists("theme/ggiraph.html"))
14-
unlink("theme/ggiraph.html")
14+
.render(test_path("theme/ggiraph.qmd"))
1515
})
1616

17-
1817
test_that("render ggplot", {
19-
skip_if_no_quarto()
20-
quarto_render("theme/ggplot.qmd", quiet = TRUE)
21-
expect_true(file.exists("theme/ggplot.html"))
22-
unlink("theme/ggplot.html")
18+
.render(test_path("theme/ggplot.qmd"))
2319
})
2420

25-
2621
test_that("render gt", {
27-
skip_if_no_quarto()
28-
quarto_render("theme/gt.qmd", quiet = TRUE)
29-
expect_true(file.exists("theme/gt.html"))
30-
unlink("theme/gt.html")
22+
.render(test_path("theme/gt.qmd"))
3123
})
3224

33-
3425
test_that("render plotly-r", {
35-
skip_if_no_quarto()
36-
quarto_render("theme/plotly-r.qmd", quiet = TRUE)
37-
expect_true(file.exists("theme/plotly-r.html"))
38-
unlink("theme/plotly-r.html")
26+
.render(test_path("theme/plotly-r.qmd"))
3927
})
4028

41-
4229
test_that("render thematic", {
43-
skip_if_no_quarto()
44-
quarto_render("theme/thematic.qmd", quiet = TRUE)
45-
expect_true(file.exists("theme/thematic.html"))
46-
unlink("theme/thematic.html")
30+
.render(test_path("theme/thematic.qmd"))
4731
})
48-

0 commit comments

Comments
 (0)