Skip to content

Commit b0ff200

Browse files
authored
Fix the lister when running in parallel (#2233)
It was not prepared for receiving updates from multiple files concurrently and some results were lost.
1 parent ed338a6 commit b0ff200

File tree

3 files changed

+86
-21
lines changed

3 files changed

+86
-21
lines changed

R/reporter-list.R

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,50 +11,52 @@ ListReporter <- R6::R6Class(
1111
"ListReporter",
1212
inherit = Reporter,
1313
public = list(
14-
current_start_time = NA,
15-
current_expectations = NULL,
16-
current_file = NULL,
17-
current_context = NULL,
18-
current_test = NULL,
14+
running = NULL,
15+
current_file = "", # so we can still subset with this
1916
results = NULL,
2017

2118
initialize = function() {
2219
super$initialize()
2320
self$capabilities$parallel_support <- TRUE
21+
self$capabilities$parallel_updates <- TRUE
2422
self$results <- Stack$new()
23+
self$running <- new.env(parent = emptyenv())
2524
},
2625

2726
start_test = function(context, test) {
27+
# is this a new test block?
2828
if (
29-
!identical(self$current_context, context) ||
30-
!identical(self$current_test, test)
29+
!identical(self$running[[self$current_file]]$context, context) ||
30+
!identical(self$running[[self$current_file]]$test, test)
3131
) {
32-
self$current_context <- context
33-
self$current_test <- test
34-
self$current_expectations <- Stack$new()
35-
self$current_start_time <- proc.time()
32+
self$running[[self$current_file]]$context <- context
33+
self$running[[self$current_file]]$test <- test
34+
self$running[[self$current_file]]$expectations <- Stack$new()
35+
self$running[[self$current_file]]$start_time <- proc.time()
3636
}
3737
},
3838

3939
add_result = function(context, test, result) {
40-
if (is.null(self$current_expectations)) {
40+
if (is.null(self$running[[self$current_file]]$expectations)) {
4141
# we received a result outside of a test:
4242
# could be a bare expectation or an exception/error
4343
if (!inherits(result, 'error')) {
4444
return()
4545
}
46-
self$current_expectations <- Stack$new()
46+
self$running[[self$current_file]]$expectations <- Stack$new()
4747
}
4848

49-
self$current_expectations$push(result)
49+
self$running[[self$current_file]]$expectations$push(result)
5050
},
5151

5252
end_test = function(context, test) {
53-
elapsed <- as.double(proc.time() - self$current_start_time)
53+
elapsed <- as.double(
54+
proc.time() - self$running[[self$current_file]]$start_time
55+
)
5456

5557
results <- list()
56-
if (!is.null(self$current_expectations)) {
57-
results <- self$current_expectations$as_list()
58+
if (!is.null(self$running[[self$current_file]]$expectations)) {
59+
results <- self$running[[self$current_file]]$expectations$as_list()
5860
}
5961

6062
self$results$push(list(
@@ -67,28 +69,39 @@ ListReporter <- R6::R6Class(
6769
results = results
6870
))
6971

70-
self$current_expectations <- NULL
72+
self$running[[self$current_file]]$expectations <- NULL
7173
},
7274

7375
start_file = function(name) {
76+
if (!name %in% names(self$running)) {
77+
newfile <- list(
78+
start_time = NA,
79+
expectations = NULL,
80+
context = NULL,
81+
test = NULL
82+
)
83+
assign(name, newfile, envir = self$running)
84+
}
7485
self$current_file <- name
7586
},
7687

7788
end_file = function() {
7889
# fallback in case we have errors but no expectations
7990
self$end_context(self$current_file)
91+
rm(list = self$current_file, envir = self$running)
8092
},
8193

8294
end_context = function(context) {
83-
results <- self$current_expectations
95+
results <- self$running[[self$current_file]]$expectations
8496
if (is.null(results)) {
8597
return()
8698
}
8799

88-
self$current_expectations <- NULL
100+
self$running[[self$current_file]]$expectations <- NULL
89101

90102
# look for exceptions raised outside of tests
91-
# they happened just before end_context since they interrupt the test_file execution
103+
# they happened just before end_context since they interrupt the test_
104+
# file execution
92105
results <- results$as_list()
93106
if (length(results) == 0) {
94107
return()
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# works in parallel
2+
3+
Code
4+
results[, c(1:8, 12:13)]
5+
Output
6+
file context test nb failed skipped error warning passed result
7+
1 f1 t11 2 0 FALSE FALSE 0 2 msg111, msg112
8+
2 f2 t21 2 0 FALSE FALSE 0 2 msg211, msg212
9+
3 f2 t22 1 0 TRUE FALSE 0 0 skip221
10+

tests/testthat/test-reporter-list.R

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,45 @@ test_that("ListReporter and bare expectations", {
7070
# 2 tests, "before" and "after". no result for the bare expectation
7171
expect_identical(df$test, c("before", "after"))
7272
})
73+
74+
test_that("works in parallel", {
75+
lr <- ListReporter$new()
76+
77+
lr$start_file("f1")
78+
lr$start_test(NULL, "t11")
79+
lr$add_result(NULL, "t11", new_expectation("success", "msg111"))
80+
81+
lr$start_file("f2")
82+
lr$start_test(NULL, "t21")
83+
lr$add_result(NULL, "t21", new_expectation("success", "msg211"))
84+
85+
lr$start_file("f1")
86+
lr$start_test(NULL, "t11")
87+
lr$add_result(NULL, "t11", new_expectation("success", "msg112"))
88+
lr$end_test(NULL, "t11")
89+
90+
lr$start_file("f2")
91+
lr$start_test(NULL, "t21")
92+
lr$add_result(NULL, "t21", new_expectation("success", "msg212"))
93+
lr$end_test(NULL, "t21")
94+
95+
lr$start_file("f2")
96+
lr$start_test(NULL, "t22")
97+
lr$add_result(NULL, "t22", new_expectation("skip", "skip221"))
98+
lr$end_test(NULL, "t22")
99+
100+
lr$start_file("f2")
101+
lr$end_file()
102+
103+
lr$start_file("f1")
104+
lr$end_file()
105+
106+
results <- as.data.frame(lr$get_results())
107+
expect_snapshot({
108+
results[, c(1:8, 12:13)]
109+
})
110+
111+
expect_true(all(!is.na(results$user)))
112+
expect_true(all(!is.na(results$system)))
113+
expect_true(all(!is.na(results$real)))
114+
})

0 commit comments

Comments
 (0)