Skip to content

Commit 77cb2d1

Browse files
committed
Merge commit '690fdb87ed8db5411ef80c0d041a188853cd7050'
2 parents 33118d9 + 690fdb8 commit 77cb2d1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+708
-1387
lines changed

DESCRIPTION

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: testthat
22
Title: Unit Testing for R
3-
Version: 3.2.1.9000
3+
Version: 3.2.2.9000
44
Authors@R: c(
55
person("Hadley", "Wickham", , "[email protected]", role = c("aut", "cre")),
66
person("Posit Software, PBC", role = c("cph", "fnd")),
@@ -34,7 +34,7 @@ Imports:
3434
R6 (>= 2.5.1),
3535
rlang (>= 1.1.1),
3636
utils,
37-
waldo (>= 0.5.1),
37+
waldo (>= 0.6.0),
3838
withr (>= 3.0.2)
3939
Suggests:
4040
covr,
@@ -43,6 +43,7 @@ Suggests:
4343
knitr,
4444
rmarkdown,
4545
rstudioapi,
46+
S7,
4647
shiny,
4748
usethis,
4849
vctrs (>= 0.1.0),

NAMESPACE

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,19 +106,23 @@ export(expect_more_than)
106106
export(expect_named)
107107
export(expect_no_condition)
108108
export(expect_no_error)
109+
export(expect_no_failure)
109110
export(expect_no_match)
110111
export(expect_no_message)
112+
export(expect_no_success)
111113
export(expect_no_warning)
112114
export(expect_null)
113115
export(expect_output)
114116
export(expect_output_file)
115117
export(expect_reference)
116118
export(expect_s3_class)
117119
export(expect_s4_class)
120+
export(expect_s7_class)
118121
export(expect_setequal)
119122
export(expect_silent)
120123
export(expect_snapshot)
121124
export(expect_snapshot_error)
125+
export(expect_snapshot_failure)
122126
export(expect_snapshot_file)
123127
export(expect_snapshot_output)
124128
export(expect_snapshot_value)

NEWS.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,55 @@
3333

3434
* `expect_setequal()` correctly identifies what is missing where (#1962).
3535

36+
* `expect_snapshot()` now strips line breaks in test descriptions
37+
(@LDSamson, #1900), and errors when called from a `test_that()` that has an
38+
empty description (@kevinushey, #1980).
39+
40+
* `expect_true()` and `expect_false()` give better errors if `actual` isn't a
41+
vector (#1996).
42+
43+
* `expect_visible()` and `expect_invisible()` have clearer failure messages
44+
(#1966).
45+
* `local_reproducible_output()` (used in `test_that()` blocks) now sets
46+
`LANGUAGE` to `"C"` instead of `"en"` to disable translations,
47+
avoiding warnings on some platforms (#1925).
48+
49+
* `skip_if_not_installed()` generates a clearer message that sorts better
50+
(@MichaelChirico, #1959).
51+
52+
* `with_mock()` and `local_mock()` have been unconditionally deprecated as
53+
they will no longer work in future versions of R (#1999).
54+
* Fixed an issue where `expect_no_error(1)` was failing (#2037).
55+
56+
* Fixed an issue where calling `skip()` outside of an active test could
57+
cause an unexpected error (@kevinushey, #2039).
58+
59+
# testthat 3.2.2
60+
61+
## New expectations
62+
63+
* `expect_s7_class()` tests if an object is an S7 class (#1580).
64+
65+
* `expect_no_failure()`, `expect_no_success()` and `expect_snapshot_failure()`
66+
provide more options for testing expectations.
67+
68+
## Bug fixes and minor improvements
69+
70+
* testthat now requires waldo 0.6.0 or later to access the latest features
71+
(#1955).
72+
73+
* `expect_condition()` and related functions now include the `class` of the
74+
expected condition in the failure message, if provided (#1987).
75+
76+
* `expect_error()` and friends now error if you supply `...` but not `pattern`
77+
(#1932). They no longer give an uninformative error if they fail inside
78+
a magrittr pipe (#1994).
79+
80+
* `expect_no_*()` expectations no longer incorrectly emit a passing test result
81+
if they in fact fail (#1997).
82+
83+
* `expect_setequal()` correctly identifies what is missing where (#1962).
84+
3685
* `expect_snapshot()` now strips line breaks in test descriptions
3786
(@LDSamson, #1900), and errors when called from a `test_that()` that has an
3887
empty description (@kevinushey, #1980).

R/describe.R

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,14 @@ describe <- function(description, code) {
7676
}
7777

7878
describe_it <- function(description, code, env = parent.frame()) {
79+
reporter <- get_reporter() %||% local_interactive_reporter()
7980
local_test_context()
8081

8182
test_code(
8283
description,
8384
code,
8485
env = env,
85-
default_reporter = local_interactive_reporter(),
86+
reporter = reporter,
8687
skip_on_empty = FALSE
8788
)
8889
}

R/expect-condition.R

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,7 @@ expect_warning <- function(object,
163163
...,
164164
inherit = inherit,
165165
info = info,
166-
label = label,
167-
trace_env = caller_env()
166+
label = label
168167
)
169168
} else {
170169
act <- quasi_capture(enquo(object), label, capture_warnings, ignore_deprecation = identical(regexp, NA))
@@ -196,8 +195,7 @@ expect_message <- function(object,
196195
...,
197196
inherit = inherit,
198197
info = info,
199-
label = label,
200-
trace_env = caller_env()
198+
label = label
201199
)
202200
} else {
203201
act <- quasi_capture(enquo(object), label, capture_messages)
@@ -225,8 +223,7 @@ expect_condition <- function(object,
225223
...,
226224
inherit = inherit,
227225
info = info,
228-
label = label,
229-
trace_env = caller_env()
226+
label = label
230227
)
231228
} else {
232229

@@ -256,18 +253,14 @@ expect_condition_matching <- function(base_class,
256253
label = NULL,
257254
trace_env = caller_env(),
258255
error_call = caller_env()) {
259-
check_dots_used(error = function(cnd) {
260-
warn(conditionMessage(cnd), call = error_call)
261-
})
262-
263256
matcher <- cnd_matcher(
264257
base_class,
265258
class,
266259
regexp,
267260
...,
268261
inherit = inherit,
269262
ignore_deprecation = base_class == "warning" && identical(regexp, NA),
270-
error_call = trace_env
263+
error_call = error_call
271264
)
272265

273266
act <- quasi_capture(
@@ -301,6 +294,13 @@ cnd_matcher <- function(base_class,
301294
check_string(class, allow_null = TRUE, call = error_call)
302295
check_string(pattern, allow_null = TRUE, allow_na = TRUE, call = error_call)
303296

297+
if (is.null(pattern) && dots_n(...) > 0) {
298+
cli::cli_abort(
299+
"Can't specify {.arg ...} without {.arg pattern}.",
300+
call = error_call
301+
)
302+
}
303+
304304
function(cnd) {
305305
if (!inherit) {
306306
cnd$parent <- NULL
@@ -318,7 +318,17 @@ cnd_matcher <- function(base_class,
318318
return(FALSE)
319319
}
320320
if (!is.null(pattern) && !isNA(pattern)) {
321-
grepl(pattern, conditionMessage(x), ...)
321+
withCallingHandlers(
322+
grepl(pattern, conditionMessage(x), ...),
323+
error = function(e) {
324+
cli::cli_abort(
325+
"Failed to compare {base_class} to {.arg pattern}.",
326+
parent = e,
327+
call = error_call
328+
)
329+
}
330+
)
331+
322332
} else {
323333
TRUE
324334
}

R/expect-constant.R

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#' Does code return `TRUE` or `FALSE`?
22
#'
3+
#' @description
34
#' These are fall-back expectations that you can use when none of the other
45
#' more specific expectations apply. The disadvantage is that you may get
56
#' a less informative error message.
@@ -30,18 +31,14 @@ NULL
3031
#' @rdname logical-expectations
3132
expect_true <- function(object, info = NULL, label = NULL) {
3233
act <- quasi_label(enquo(object), label, arg = "object")
33-
act$val <- as.vector(act$val)
34-
35-
expect_waldo_constant(act, TRUE, info = info)
34+
expect_waldo_constant(act, TRUE, info = info, ignore_attr = TRUE)
3635
}
3736

3837
#' @export
3938
#' @rdname logical-expectations
4039
expect_false <- function(object, info = NULL, label = NULL) {
4140
act <- quasi_label(enquo(object), label, arg = "object")
42-
act$val <- as.vector(act$val)
43-
44-
expect_waldo_constant(act, FALSE, info = info)
41+
expect_waldo_constant(act, FALSE, info = info, ignore_attr = TRUE)
4542
}
4643

4744
#' Does code return `NULL`?
@@ -66,11 +63,17 @@ expect_null <- function(object, info = NULL, label = NULL) {
6663

6764
# helpers -----------------------------------------------------------------
6865

69-
expect_waldo_constant <- function(act, constant, info) {
70-
comp <- waldo_compare(act$val, constant, x_arg = "actual", y_arg = "expected")
66+
expect_waldo_constant <- function(act, constant, info, ...) {
67+
comp <- waldo_compare(
68+
act$val,
69+
constant,
70+
x_arg = "actual",
71+
y_arg = "expected",
72+
...
73+
)
7174

7275
expect(
73-
identical(act$val, constant),
76+
length(comp) == 0,
7477
sprintf(
7578
"%s is not %s\n\n%s",
7679
act$lab, deparse(constant),

R/expect-inheritance.R

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#' * `expect_s4_class(x, class)` checks that `x` is an S4 object that
1313
#' [is()] `class`.
1414
#' * `expect_s4_class(x, NA)` checks that `x` isn't an S4 object.
15+
#' * `expect_s7_class(x, Class)` checks that `x` is an S7 object that
16+
#' [S7::S7_inherits()] from `Class`
1517
#'
1618
#' See [expect_vector()] for testing properties of objects created by vctrs.
1719
#'
@@ -92,6 +94,33 @@ expect_s3_class <- function(object, class, exact = FALSE) {
9294
invisible(act$val)
9395
}
9496

97+
#' @export
98+
#' @rdname inheritance-expectations
99+
expect_s7_class <- function(object, class) {
100+
check_installed("S7")
101+
if (!inherits(class, "S7_class")) {
102+
stop_input_type(class, "an S7 class object")
103+
}
104+
105+
act <- quasi_label(enquo(object), arg = "object")
106+
107+
if (!S7::S7_inherits(object)) {
108+
fail(sprintf("%s is not an S7 object", act$lab))
109+
} else {
110+
expect(
111+
S7::S7_inherits(object, class),
112+
sprintf(
113+
"%s inherits from %s not <%s>.",
114+
act$lab,
115+
paste0("<", setdiff(base::class(object), "S7_object"), ">", collapse = "/"),
116+
attr(class, "name", TRUE)
117+
)
118+
)
119+
}
120+
121+
invisible(act$val)
122+
}
123+
95124
#' @export
96125
#' @rdname inheritance-expectations
97126
expect_s4_class <- function(object, class) {

R/expect-invisible.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ expect_invisible <- function(call, label = NULL) {
2626

2727
expect(
2828
identical(vis$visible, FALSE),
29-
sprintf("%s does not return invisibly", lab)
29+
sprintf("%s returns visibly, not invisibly.", lab)
3030
)
3131
invisible(vis$value)
3232
}
@@ -39,7 +39,7 @@ expect_visible <- function(call, label = NULL) {
3939

4040
expect(
4141
identical(vis$visible, TRUE),
42-
sprintf("%s does not invisibly", lab)
42+
sprintf("%s returns invisibly, not visibly.", lab)
4343
)
4444
invisible(vis$value)
4545
}

R/expect-no-condition.R

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ expect_no_condition <- function(object,
8282

8383

8484
expect_no_ <- function(base_class,
85-
object,
86-
regexp = NULL,
87-
class = NULL,
88-
error_call = caller_env()) {
85+
object,
86+
regexp = NULL,
87+
class = NULL,
88+
trace_env = caller_env()) {
8989

9090
matcher <- cnd_matcher(
9191
base_class,
@@ -96,7 +96,12 @@ expect_no_ <- function(base_class,
9696

9797
capture <- function(code) {
9898
try_fetch(
99-
code,
99+
{
100+
code
101+
# We can't call succeed() here because that generates a condition
102+
# that causes `expect_no_condition()` to always fail
103+
NULL
104+
},
100105
!!base_class := function(cnd) {
101106
if (!matcher(cnd)) {
102107
return(zap())
@@ -113,13 +118,15 @@ expect_no_ <- function(base_class,
113118
indent_lines(rlang::cnd_message(cnd))
114119
)
115120
message <- format_error_bullets(c(expected, i = actual))
116-
fail(message, trace_env = error_call)
121+
fail(message, trace_env = trace_env)
117122
}
118123
)
119124
}
120125

121126
act <- quasi_capture(enquo(object), NULL, capture)
122-
succeed()
127+
if (is.null(act$cap)) {
128+
succeed()
129+
}
123130
invisible(act$val)
124131
}
125132

0 commit comments

Comments
 (0)