Skip to content

Commit e1bda60

Browse files
authored
Don't use snapshot reporter in parent thread (#1793)
* Don't use snapshot reporter in parent thread * Only delete files if not in main thread and changing working directory higher up * Remove outdated comment
1 parent 28482d0 commit e1bda60

14 files changed

+210
-63
lines changed

NEWS.md

-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
# testthat (development version)
22

3-
* All packages, regardless of whether or not they use rlang, now
4-
use the new snapshot display for errors, warnings, and messages.
5-
63
* `skip_on_cran()` no longer skips (errors) when run interactively.
74

85
* `testthat::teardown_env()` works in more cases.

R/edition.R

+30
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,33 @@ edition_get <- function() {
8181
find_edition(".")
8282
}
8383
}
84+
85+
86+
find_dep_version <- function(name, path, package = NULL) {
87+
desc <- find_description(path, package)
88+
if (is.null(desc)) {
89+
return(NULL)
90+
}
91+
92+
deps <- desc$get_deps()
93+
i <- match(name, deps[["package"]])
94+
if (is_na(i)) {
95+
return(NULL)
96+
}
97+
98+
dep <- deps[[i, "version"]]
99+
dep <- strsplit(dep, " ")[[1]]
100+
if (!is_character(dep, 2) && !is_string(dep[[1]], ">=")) {
101+
return(NULL)
102+
}
103+
104+
dep[[2]]
105+
}
106+
has_dep <- function(name, path, package = NULL) {
107+
!is.null(find_dep_version(name, path, package = package))
108+
}
109+
110+
use_rlang_1_0 <- function() {
111+
rlang::is_true(peek_option("testthat:::rlang_dep")) &&
112+
is_installed("rlang", version = "0.99.0.9001")
113+
}

R/local.R

+4
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ local_test_directory <- function(path, package = NULL, .env = parent.frame()) {
174174
# Set edition before changing working directory in case path is relative
175175
local_edition(find_edition(path, package), .env = .env)
176176

177+
withr::local_options(
178+
"testthat:::rlang_dep" = has_dep("rlang", path, package),
179+
.local_envir = .env
180+
)
177181
withr::local_dir(
178182
path,
179183
.local_envir = .env

R/parallel.R

+10-8
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ test_files_parallel <- function(
4646
) {
4747

4848

49-
reporters <- test_files_reporter(reporter)
49+
reporters <- test_files_reporter(reporter, parallel = TRUE)
5050

5151
# TODO: support timeouts. 20-30s for each file by default?
5252

@@ -70,13 +70,15 @@ test_files_parallel <- function(
7070
load_package = load_package
7171
)
7272

73-
with_reporter(reporters$multi, {
74-
parallel_updates <- reporter$capabilities$parallel_updates
75-
if (parallel_updates) {
76-
parallel_event_loop_smooth(queue, reporters, test_dir)
77-
} else {
78-
parallel_event_loop_chunky(queue, reporters, test_dir)
79-
}
73+
withr::with_dir(test_dir, {
74+
with_reporter(reporters$multi, {
75+
parallel_updates <- reporter$capabilities$parallel_updates
76+
if (parallel_updates) {
77+
parallel_event_loop_smooth(queue, reporters, ".")
78+
} else {
79+
parallel_event_loop_chunky(queue, reporters, ".")
80+
}
81+
})
8082
})
8183

8284
test_files_check(reporters$list$get_results(),

R/snapshot-reporter.R

+14-3
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@ SnapshotReporter <- R6::R6Class("SnapshotReporter",
99
snap_file_seen = character(),
1010
variants_changed = FALSE,
1111
fail_on_new = FALSE,
12+
parallel = FALSE,
1213

1314
old_snaps = NULL,
1415
cur_snaps = NULL,
1516
new_snaps = NULL,
1617

17-
initialize = function(snap_dir = "_snaps", fail_on_new = FALSE) {
18+
initialize = function(snap_dir = "_snaps", fail_on_new = FALSE, parallel = FALSE) {
1819
self$snap_dir <- normalizePath(snap_dir, mustWork = FALSE)
1920
self$fail_on_new <- fail_on_new
21+
self$parallel <- parallel
2022
},
2123

2224
start_file = function(path, test = NULL) {
@@ -127,6 +129,11 @@ SnapshotReporter <- R6::R6Class("SnapshotReporter",
127129
},
128130

129131
end_file = function() {
132+
if (self$parallel) {
133+
# This is only needs to be done in the child threads.
134+
return()
135+
}
136+
130137
dir.create(self$snap_dir, showWarnings = FALSE)
131138

132139
self$cur_snaps$write()
@@ -193,9 +200,13 @@ get_snapshotter <- function() {
193200
#'
194201
#' @export
195202
#' @keywords internal
196-
local_snapshotter <- function(snap_dir = NULL, cleanup = FALSE, fail_on_new = FALSE, .env = parent.frame()) {
203+
local_snapshotter <- function(snap_dir = NULL, cleanup = FALSE, fail_on_new = FALSE, parallel = FALSE, .env = parent.frame()) {
197204
snap_dir <- snap_dir %||% withr::local_tempdir(.local_envir = .env)
198-
reporter <- SnapshotReporter$new(snap_dir = snap_dir, fail_on_new = fail_on_new)
205+
reporter <- SnapshotReporter$new(
206+
snap_dir = snap_dir,
207+
fail_on_new = fail_on_new,
208+
parallel = parallel
209+
)
199210
if (!identical(cleanup, FALSE)) {
200211
warn("`cleanup` is deprecated")
201212
}

R/snapshot.R

+29
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,14 @@ snapshot_replay.condition <- function(x,
123123
...,
124124
transform = NULL,
125125
cnd_class = FALSE) {
126+
if (!use_rlang_1_0()) {
127+
return(snapshot_replay_condition_legacy(
128+
x,
129+
state,
130+
transform = transform
131+
))
132+
}
133+
126134
cnd_message <- env_get(ns_env("rlang"), "cnd_message")
127135

128136
if (inherits(x, "message")) {
@@ -143,6 +151,27 @@ snapshot_replay.condition <- function(x,
143151
c(snap_header(state, type), snapshot_lines(msg, transform))
144152
}
145153

154+
snapshot_replay_condition_legacy <- function(x, state = env(), transform = NULL) {
155+
msg <- cnd_message(x)
156+
157+
if (inherits(x, "error")) {
158+
state$error <- x
159+
type <- "Error"
160+
msg <- add_implicit_nl(msg)
161+
} else if (inherits(x, "warning")) {
162+
type <- "Warning"
163+
msg <- paste0(msg, "\n")
164+
} else if (inherits(x, "message")) {
165+
type <- "Message"
166+
} else {
167+
type <- "Condition"
168+
}
169+
170+
class <- paste0(type, " <", class(x)[[1]], ">")
171+
172+
c(snap_header(state, class), snapshot_lines(msg, transform))
173+
}
174+
146175
snapshot_lines <- function(x, transform = NULL) {
147176
x <- split_lines(x)
148177
if (!is.null(transform)) {

R/test-files.R

+7-2
Original file line numberDiff line numberDiff line change
@@ -277,12 +277,17 @@ test_files_setup_state <- function(
277277
withr::defer(source_test_teardown(".", env), frame) # old school
278278
}
279279

280-
test_files_reporter <- function(reporter, .env = parent.frame()) {
280+
test_files_reporter <- function(reporter, .env = parent.frame(), parallel = FALSE) {
281281
lister <- ListReporter$new()
282282
reporters <- list(
283283
find_reporter(reporter),
284284
lister, # track data
285-
local_snapshotter("_snaps", fail_on_new = FALSE, .env = .env) # for snapshots
285+
local_snapshotter(
286+
"_snaps",
287+
fail_on_new = FALSE,
288+
parallel = parallel,
289+
.env = .env
290+
)
286291
)
287292
list(
288293
multi = MultiReporter$new(reporters = compact(reporters)),

man/local_snapshotter.Rd

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# full condition message is printed with rlang
2+
3+
Code
4+
foo <- error_cnd("foo", message = "Title parent.")
5+
abort("Title.", parent = foo)
6+
Condition
7+
Error:
8+
! Title.
9+
Caused by error:
10+
! Title parent.
11+
12+
# can print with and without condition classes
13+
14+
Code
15+
f()
16+
Message <simpleMessage>
17+
foo
18+
Condition <simpleWarning>
19+
Warning in `f()`:
20+
bar
21+
Condition <simpleError>
22+
Error in `f()`:
23+
! baz
24+
25+
---
26+
27+
Code
28+
f()
29+
Message
30+
foo
31+
Condition
32+
Warning in `f()`:
33+
bar
34+
Error in `f()`:
35+
! baz
36+
37+
# errors and warnings are folded
38+
39+
Code
40+
f()
41+
Condition
42+
Warning in `f()`:
43+
foo
44+
Error in `f()`:
45+
! bar
46+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# full condition message is printed with rlang
2+
3+
Code
4+
foo <- error_cnd("foo", message = "Title parent.")
5+
abort("Title.", parent = foo)
6+
Error <rlang_error>
7+
Title.
8+
9+
# can print with and without condition classes
10+
11+
Code
12+
f()
13+
Message <simpleMessage>
14+
foo
15+
Warning <simpleWarning>
16+
bar
17+
Error <simpleError>
18+
baz
19+
20+
---
21+
22+
Code
23+
f()
24+
Message <simpleMessage>
25+
foo
26+
Warning <simpleWarning>
27+
bar
28+
Error <simpleError>
29+
baz
30+
31+
# errors and warnings are folded
32+
33+
Code
34+
f()
35+
Warning <simpleWarning>
36+
foo
37+
Error <simpleError>
38+
bar
39+

tests/testthat/_snaps/snapshot.md

-46
Original file line numberDiff line numberDiff line change
@@ -254,52 +254,6 @@
254254
x <- quote(!!foo)
255255
expect_equal(x, call("!", call("!", quote(foo))))
256256

257-
# full condition message is printed with rlang
258-
259-
Code
260-
foo <- error_cnd("foo", message = "Title parent.")
261-
abort("Title.", parent = foo)
262-
Condition
263-
Error:
264-
! Title.
265-
Caused by error:
266-
! Title parent.
267-
268-
# can print with and without condition classes
269-
270-
Code
271-
f()
272-
Message <simpleMessage>
273-
foo
274-
Condition <simpleWarning>
275-
Warning in `f()`:
276-
bar
277-
Condition <simpleError>
278-
Error in `f()`:
279-
! baz
280-
281-
---
282-
283-
Code
284-
f()
285-
Message
286-
foo
287-
Condition
288-
Warning in `f()`:
289-
bar
290-
Error in `f()`:
291-
! baz
292-
293-
# errors and warnings are folded
294-
295-
Code
296-
f()
297-
Condition
298-
Warning in `f()`:
299-
foo
300-
Error in `f()`:
301-
! bar
302-
303257
# hint is informative
304258

305259
Code

tests/testthat/helper-testthat.R

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
rlang_version <- function() {
2+
if (use_rlang_1_0()) "rlang-1.0" else "rlang-pre-1.0"
3+
}
4+
5+
local_use_rlang_1_0 <- function(frame = caller_env()) {
6+
local_options("testthat:::rlang_dep" = TRUE, .frame = frame)
7+
}

0 commit comments

Comments
 (0)