Skip to content

Commit 5ef7aa2

Browse files
authored
Merge branch 'main' into test-interrupt
2 parents 78b6e1d + 6099802 commit 5ef7aa2

File tree

11 files changed

+144
-5
lines changed

11 files changed

+144
-5
lines changed

β€ŽNEWS.mdβ€Ž

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
# testthat (development version)
22

33
* Interrupting a test now prints the test name. This makes it easier to tell where a very slow test might be hanging (#1464)
4+
* Parallel testthat now does not ignore test files with syntax errors (#1360).
5+
* `expect_lt()`, `expect_gt()`, and friends have a refined display that is more likely to display the correct number of digits and shows you the actual values compared.
46
* `describe()`, `it()`, and `test_that()` now have a shared stack of descriptions so that if you nest any inside of each other, any resulting failures will show you the full path.
57
* `describe()` now correctly scopes `skip()` (#2007).
68
* `ParallelProgressReporter` now respect `max_failures` (#1162).
79
* The last snapshot is no longer lost if the snapshot file is missing the final newline (#2092). It's easy to accidentally remove this because there are two trailing new lines in snapshot files and many editors will automatically remove if you touch the file.
810
* New `expect_r6_class()` (#2030).
9-
* `expect_*()` functions consistently and rigorously check their inputs (#1754).
11+
* `expect_*()` functions consistently and rigorously check their inputs (#1754).
1012
* `JunitReporter()` no longer fails with `"no applicable method for xml_add_child"` for warnings outside of tests (#1913). Additionally, warnings now save their backtraces.
1113
* `JunitReporter()` strips ANSI escapes in more placese (#1852, #2032).
1214
* `try_again()` is now publicised. The first argument is now the number of retries, not tries (#2050).

β€ŽR/expect-comparison.Rβ€Ž

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,31 @@ expect_compare_ <- function(
3131
msg <- c(
3232
"<" = "not strictly less than",
3333
"<=" = "not less than",
34-
">" = "not strictly more than",
35-
">=" = "not more than"
34+
">" = "not strictly greater than",
35+
">=" = "not greater than"
3636
)[[operator]]
3737

38+
negated_op <- switch(operator, "<" = ">=", "<=" = ">", ">" = "<=", ">=" = "<")
39+
3840
cmp <- op(act$val, exp$val)
3941
if (length(cmp) != 1 || !is.logical(cmp)) {
4042
abort("Result of comparison must be a single logical value")
4143
}
4244
if (!isTRUE(cmp)) {
45+
digits <- max(
46+
digits(act$val),
47+
digits(exp$val),
48+
min_digits(act$val, exp$val)
49+
)
4350
msg <- sprintf(
44-
"%s is %s %s. Difference: %.3g",
51+
"%s is %s %s.\n%s - %s = %s %s 0",
4552
act$lab,
4653
msg,
4754
exp$lab,
48-
act$val - exp$val
55+
num_exact(act$val, digits),
56+
num_exact(exp$val, digits),
57+
num_exact(act$val - exp$val, digits),
58+
negated_op
4959
)
5060
return(fail(msg, trace_env = trace_env))
5161
}
@@ -109,3 +119,39 @@ expect_more_than <- function(...) {
109119
warning("Deprecated: please use `expect_gt()` instead", call. = FALSE)
110120
expect_gt(...)
111121
}
122+
123+
124+
# Helpers -----------------------------------------------------------------
125+
126+
num_exact <- function(x, digits = 6) {
127+
sprintf(paste0("%0.", digits, "f"), x)
128+
}
129+
130+
min_digits <- function(x, y, tolerance = testthat_tolerance()) {
131+
if (is.integer(x) && is.integer(y)) {
132+
return(0L)
133+
}
134+
135+
attributes(x) <- NULL
136+
attributes(y) <- NULL
137+
138+
n <- digits(abs(x - y))
139+
if (!is.null(tolerance)) {
140+
n <- min(n, digits(tolerance))
141+
}
142+
143+
as.integer(n) + 1L
144+
}
145+
146+
digits <- function(x) {
147+
x <- x[!is.na(x) & x != 0]
148+
if (length(x) == 0) {
149+
return(0)
150+
}
151+
scale <- -log10(min(x))
152+
if (scale <= 0) {
153+
0L
154+
} else {
155+
ceiling(round(scale, digits = 2))
156+
}
157+
}

β€ŽR/parallel-taskq.Rβ€Ž

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ task_q <- R6::R6Class(
7878
private$tasks$state[[i]] <- "ready"
7979
msg <- NULL
8080
} else if (msg$code == PROCESS_DONE) {
81+
if (!is.null(msg$error)) {
82+
private$handle_error(msg, i)
83+
}
8184
private$tasks$state[[i]] <- "ready"
8285
} else if (msg$code %in% PROCESS_FAILURES) {
8386
private$handle_error(msg, i)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# useful output when numbers are very small
2+
3+
1.1 * x is not less than `x`.
4+
0.0000110 - 0.0000100 = 0.0000010 > 0
5+
6+
---
7+
8+
`x` is not strictly greater than 1.1 * x.
9+
0.0000100 - 0.0000110 = -0.0000010 <= 0
10+
11+
# useful output when difference is zero
12+
13+
`x` is not strictly less than 100.
14+
100.0 - 100.0 = 0.0 >= 0
15+
16+
# useful output when differnce is large
17+
18+
`x` is not strictly less than 0.001.
19+
100.000 - 0.001 = 99.999 >= 0
20+

β€Žtests/testthat/test-expect-comparison.Rβ€Ž

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,22 @@ test_that("basic comparisons work", {
88
expect_success(expect_gte(10, 10))
99
})
1010

11+
test_that("useful output when numbers are very small", {
12+
x <- 1e-5
13+
expect_snapshot_failure(expect_lte(1.1 * x, x))
14+
expect_snapshot_failure(expect_gt(x, 1.1 * x))
15+
})
16+
17+
test_that("useful output when difference is zero", {
18+
x <- 100
19+
expect_snapshot_failure(expect_lt(x, 100))
20+
})
21+
22+
test_that("useful output when differnce is large", {
23+
x <- 100
24+
expect_snapshot_failure(expect_lt(x, 0.001))
25+
})
26+
1127
test_that("comparison result object invisibly", {
1228
out <- expect_invisible(expect_lt(1, 10))
1329
expect_equal(out, 1)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
test_that("error in parallel setup code", {
2+
skip_on_covr()
3+
withr::local_envvar(TESTTHAT_PARALLEL = "TRUE")
4+
err <- tryCatch(
5+
capture.output(suppressMessages(testthat::test_local(
6+
test_path("test-parallel", "syntax-error"),
7+
reporter = "summary"
8+
))),
9+
error = function(e) e
10+
)
11+
expect_s3_class(err, "testthat_process_error")
12+
# contains test file's name
13+
expect_match(conditionMessage(err), "test-error-1.R")
14+
# contains original error message
15+
expect_match(conditionMessage(err), "unexpected symbol")
16+
# contains the text of the syntax error
17+
expect_match(conditionMessage(err), "but this")
18+
})
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Package: setup
2+
Title: What the Package Does (One Line, Title Case)
3+
Version: 0.0.0.9000
4+
Authors@R:
5+
person(given = "First",
6+
family = "Last",
7+
role = c("aut", "cre"),
8+
email = "[email protected]",
9+
comment = c(ORCID = "YOUR-ORCID-ID"))
10+
Description: What the package does (one paragraph).
11+
License: `use_mit_license()`, `use_gpl3_license()` or friends to
12+
pick a license
13+
Encoding: UTF-8
14+
LazyData: true
15+
Roxygen: list(markdown = TRUE)
16+
RoxygenNote: 7.1.1
17+
Suggests:
18+
testthat
19+
Config/testthat/parallel: true
20+
Config/testthat/edition: 3
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Generated by roxygen2: do not edit by hand
2+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
library(testthat)
2+
library(ok)
3+
4+
test_check("ok")
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
test_that("this is good", {
2+
expect_equal(2 * 2, 4)
3+
})
4+
5+
but this is a syntax error!

0 commit comments

Comments
Β (0)