Skip to content

Commit ce394a5

Browse files
Improve error about ... in expect_condition() (et al) (#2055)
Fixes #2054. Fixes #2053.
1 parent cc79388 commit ce394a5

File tree

9 files changed

+78
-19
lines changed

9 files changed

+78
-19
lines changed

R/expect-condition.R

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ expect_condition_matching <- function(
280280
trace_env = caller_env(),
281281
error_call = caller_env()
282282
) {
283+
check_condition_dots(regexp, ..., error_call = error_call)
283284
matcher <- cnd_matcher(
284285
base_class,
285286
class,
@@ -320,21 +321,14 @@ expect_condition_matching <- function(
320321
cnd_matcher <- function(
321322
base_class,
322323
class = NULL,
323-
pattern = NULL,
324+
regexp = NULL,
324325
...,
325326
inherit = TRUE,
326327
ignore_deprecation = FALSE,
327328
error_call = caller_env()
328329
) {
329330
check_string(class, allow_null = TRUE, call = error_call)
330-
check_string(pattern, allow_null = TRUE, allow_na = TRUE, call = error_call)
331-
332-
if (is.null(pattern) && dots_n(...) > 0) {
333-
cli::cli_abort(
334-
"Can't specify {.arg ...} without {.arg pattern}.",
335-
call = error_call
336-
)
337-
}
331+
check_string(regexp, allow_null = TRUE, allow_na = TRUE, call = error_call)
338332

339333
function(cnd) {
340334
if (!inherit) {
@@ -352,12 +346,12 @@ cnd_matcher <- function(
352346
if (!is.null(class) && !inherits(x, class)) {
353347
return(FALSE)
354348
}
355-
if (!is.null(pattern) && !isNA(pattern)) {
349+
if (!is.null(regexp) && !isNA(regexp)) {
356350
withCallingHandlers(
357-
grepl(pattern, conditionMessage(x), ...),
351+
grepl(regexp, conditionMessage(x), ...),
358352
error = function(e) {
359353
cli::cli_abort(
360-
"Failed to compare {base_class} to {.arg pattern}.",
354+
"Failed to compare {base_class} to {.arg regexp}.",
361355
parent = e,
362356
call = error_call
363357
)
@@ -582,3 +576,29 @@ cnd_message <- function(x) {
582576
withr::local_options(rlang_backtrace_on_error = "none")
583577
conditionMessage(x)
584578
}
579+
580+
check_condition_dots <- function(
581+
regexp = NULL,
582+
...,
583+
error_call = caller_env()
584+
) {
585+
if (!is.null(regexp) || missing(...)) {
586+
return()
587+
}
588+
589+
dot_names <- ...names()
590+
if (is.null(dot_names)) {
591+
dot_names <- rep("", ...length())
592+
}
593+
unnamed <- dot_names == ""
594+
dot_names[unnamed] <- paste0("..", seq_along(dot_names)[unnamed])
595+
596+
cli::cli_abort(
597+
c(
598+
"Can't supply {.arg ...} unless {.arg regexp} is set.",
599+
"*" = "Unused arguments: {.arg {dot_names}}.",
600+
i = "Did you mean to use {.arg regexp} so {.arg ...} is passed to {.fn grepl}?"
601+
),
602+
call = error_call
603+
)
604+
}

R/expect-no-condition.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ expect_no_ <- function(
7676
matcher <- cnd_matcher(
7777
base_class,
7878
class,
79-
pattern = regexp,
79+
regexp = regexp,
8080
ignore_deprecation = base_class == "warning" &&
8181
is.null(regexp) &&
8282
is.null(class)

R/test-compiled-code.R

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,11 @@ run_cpp_tests <- function(package) {
143143
c(line, line, 1, 1)
144144
)
145145

146-
exp <- new_expectation("error", exception_text, srcref = exception_srcref)
146+
exp <- new_expectation(
147+
"error",
148+
exception_text,
149+
srcref = exception_srcref
150+
)
147151
exp$test <- test_name
148152

149153
get_reporter()$add_result(

tests/testthat/_snaps/expect-condition.md

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
expect_error(stop("!"), regexp = 1)
1313
Condition
1414
Error in `expect_error()`:
15-
! `pattern` must be a single string, `NA`, or `NULL`, not the number 1.
15+
! `regexp` must be a single string, `NA`, or `NULL`, not the number 1.
1616
Code
1717
expect_error(stop("!"), class = 1)
1818
Condition
@@ -35,12 +35,35 @@
3535
expect_condition(stop("Hi!"), foo = "bar")
3636
Condition
3737
Error in `expect_condition()`:
38-
! Can't specify `...` without `pattern`.
38+
! Can't supply `...` unless `regexp` is set.
39+
* Unused arguments: `foo`.
40+
i Did you mean to use `regexp` so `...` is passed to `grepl()`?
41+
Code
42+
expect_condition(stop("Hi!"), , , "bar")
43+
Condition
44+
Error in `expect_condition()`:
45+
! Can't supply `...` unless `regexp` is set.
46+
* Unused arguments: `..1`.
47+
i Did you mean to use `regexp` so `...` is passed to `grepl()`?
48+
Code
49+
expect_condition(stop("Hi!"), , , "bar", fixed = TRUE)
50+
Condition
51+
Error in `expect_condition()`:
52+
! Can't supply `...` unless `regexp` is set.
53+
* Unused arguments: `..1` and `fixed`.
54+
i Did you mean to use `regexp` so `...` is passed to `grepl()`?
3955
Code
4056
expect_condition(stop("Hi!"), "x", foo = "bar")
4157
Condition
4258
Error in `expect_condition()`:
43-
! Failed to compare condition to `pattern`.
59+
! Failed to compare condition to `regexp`.
4460
Caused by error in `grepl()`:
4561
! unused argument (foo = "bar")
62+
Code
63+
expect_condition(stop("Hi!"), pattern = "bar", fixed = TRUE)
64+
Condition
65+
Error in `expect_condition()`:
66+
! Can't supply `...` unless `regexp` is set.
67+
* Unused arguments: `pattern` and `fixed`.
68+
i Did you mean to use `regexp` so `...` is passed to `grepl()`?
4669

tests/testthat/test-catch.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ test_that("get_routine() fails when no routine exists", {
77
expect_error(get_routine("utils", "no_such_routine"))
88
})
99

10+
skip_if_not_installed("xml2")
1011
run_cpp_tests("testthat")

tests/testthat/test-compare.R

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,14 @@ test_that("base lengths must be identical", {
196196
})
197197

198198
test_that("tzones must be identical", {
199-
t1 <- ISOdatetime(2016, 2, 29, 12, 13, 14, "EST")
200-
t2 <- ISOdatetime(2016, 2, 29, 12, 13, 14, "US/Eastern")
199+
# skip on minimal setups
200+
tryCatch(
201+
{
202+
t1 <- ISOdatetime(2016, 2, 29, 12, 13, 14, "EST")
203+
t2 <- ISOdatetime(2016, 2, 29, 12, 13, 14, "US/Eastern")
204+
},
205+
warning = function(w) skip(conditionMessage(w))
206+
)
201207

202208
expect_match(compare(t1, t2)$message, '"tzone": 1 string mismatch')
203209
})

tests/testthat/test-expect-condition.R

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,10 @@ test_that("can match parent conditions (#1493)", {
252252
test_that("unused arguments generate an error", {
253253
expect_snapshot(error = TRUE, {
254254
expect_condition(stop("Hi!"), foo = "bar")
255+
expect_condition(stop("Hi!"), , , "bar")
256+
expect_condition(stop("Hi!"), , , "bar", fixed = TRUE)
255257
expect_condition(stop("Hi!"), "x", foo = "bar")
258+
expect_condition(stop("Hi!"), pattern = "bar", fixed = TRUE)
256259
})
257260
})
258261

tests/testthat/test-expect-inheritance.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ test_that("checks its inputs", {
7575
})
7676

7777
test_that("can check with actual class", {
78+
skip_if_not_installed("S7")
7879
Foo <- S7::new_class("Foo", package = NULL)
7980
Bar <- S7::new_class("Bar", package = NULL)
8081
expect_success(expect_s7_class(Foo(), class = Foo))

tests/testthat/test-reporter-junit.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
test_that("reporter doesn't change without warning", {
2+
skip_if_not_installed("xml2")
23
expect_snapshot_reporter(JunitReporterMock$new())
34
})
45

0 commit comments

Comments
 (0)