Skip to content

Commit ff6a673

Browse files
committed
Overhaul expect_matches()
Use `expect_snapshot_failure()` to look at more of the messaging, and then use that to make a bunch of minor improvements.
1 parent 41bb354 commit ff6a673

File tree

6 files changed

+61
-53
lines changed

6 files changed

+61
-53
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# testthat (development version)
22

3+
* `expect_matches()` failures should be a little easier to read (#2135).
34
* New `local_on_cran(TRUE)` allows you to simulate how your tests will run on CRAN (#2112).
45
* `expect_no_*()` now executes the entire code block, rather than stopping at the first message or warning (#1991).
56
* `expect_no_failures()` and `expect_no_successes()` are now deprecated as `expect_success()` now test for no failures and `expect_failure()` tests for no successes (#)

R/expect-match.R

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,7 @@ expect_no_match <- function(
7575
# Capture here to avoid environment-related messiness
7676
act <- quasi_label(enquo(object), label, arg = "object")
7777
stopifnot(is.character(regexp), length(regexp) == 1)
78-
7978
stopifnot(is.character(act$val))
80-
if (length(object) == 0) {
81-
return(fail(sprintf("%s is empty.", act$lab), info = info))
82-
}
8379

8480
expect_match_(
8581
act = act,
@@ -114,20 +110,17 @@ expect_match_ <- function(
114110
return(pass(act$val))
115111
}
116112

117-
escape <- if (fixed) identity else escape_regex
118-
113+
text <- encodeString(act$val)
119114
if (length(act$val) == 1) {
120-
values <- paste0("Actual value: \"", escape(encodeString(act$val)), "\"")
115+
values <- paste0("Text: \"", text, "\"")
121116
} else {
122-
values <- paste0(
123-
"Actual values:\n",
124-
paste0("* ", escape(encodeString(act$val)), collapse = "\n")
125-
)
117+
values <- paste0("Text:\n", paste0("* ", text, collapse = "\n"))
126118
}
127119

128120
msg <- sprintf(
129-
if (negate) "%s does match %s.\n%s" else "%s does not match %s.\n%s",
130-
escape(act$lab),
121+
if (negate) "%s does match %s %s.\n%s" else "%s does not match %s %s.\n%s",
122+
act$lab,
123+
if (fixed) "string" else "regexp",
131124
encodeString(regexp, quote = '"'),
132125
values
133126
)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# generates useful failure messages
2+
3+
`zero` is empty.
4+
5+
---
6+
7+
`one` does not match regexp "asdf".
8+
Text: "bcde"
9+
10+
---
11+
12+
`many` does not match regexp "asdf".
13+
Text:
14+
* a
15+
* b
16+
* c
17+
* d
18+
* e
19+
20+
# expect_no_match works
21+
22+
`x` does match string "e*".
23+
Text: "te*st"
24+
25+
---
26+
27+
`x` does match regexp "TEST".
28+
Text: "test"
29+

tests/testthat/_snaps/expect-output.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# expect = string checks for match
22

3-
`g\(\)` does not match "x".
4-
Actual value: "!"
3+
`g()` does not match regexp "x".
4+
Text: "!"
55

66
---
77

tests/testthat/_snaps/expect-self-test.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# expect_failure() can optionally match message
22

3-
Failure message does not match "banana".
4-
Actual value: "apple"
3+
Failure message does not match regexp "banana".
4+
Text: "apple"
55

66
# errors in expect_success bubble up
77

tests/testthat/test-expect-match.R

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,32 @@
1-
test_that("extra arguments to matches passed onto grepl", {
2-
expect_success(expect_match("te*st", "e*", fixed = TRUE))
3-
expect_success(expect_match("test", "TEST", ignore.case = TRUE))
4-
})
1+
test_that("generates useful failure messages", {
2+
zero <- character(0)
3+
expect_snapshot_failure(expect_match(zero, 'asdf'))
54

6-
test_that("special regex characters are escaped in output", {
7-
error <- tryCatch(
8-
expect_match("f() test", "f() test"),
9-
expectation = function(e) e$message
10-
)
11-
expect_equal(
12-
error,
13-
"\"f\\(\\) test\" does not match \"f() test\".\nActual value: \"f\\(\\) test\""
14-
)
15-
})
5+
one <- "bcde"
6+
expect_snapshot_failure(expect_match(one, 'asdf'))
167

17-
test_that("correct reporting of expected label", {
18-
expect_failure(expect_match("[a]", "[b]"), escape_regex("[a]"), fixed = TRUE)
19-
expect_failure(expect_match("[a]", "[b]", fixed = TRUE), "[a]", fixed = TRUE)
8+
many <- letters[1:5]
9+
expect_snapshot_failure(expect_match(many, 'asdf'))
2010
})
2111

22-
test_that("errors if obj is empty str", {
23-
x <- character(0)
24-
err <- expect_error(
25-
expect_match(x, 'asdf'),
26-
class = "expectation_failure"
27-
)
28-
expect_match(err$message, 'is empty')
29-
})
12+
test_that("extra arguments passed onto grepl", {
13+
expect_failure(expect_match("\\s", "\\s"))
14+
expect_success(expect_match("\\s", "\\s", fixed = TRUE))
3015

31-
test_that("prints multiple unmatched values", {
32-
err <- expect_error(
33-
expect_match(letters[1:10], 'asdf'),
34-
class = "expectation_failure"
35-
)
36-
expect_match(err$message, "does not match")
16+
expect_failure(expect_match("test", "TEST"))
17+
expect_success(expect_match("test", "TEST", ignore.case = TRUE))
3718
})
3819

3920
test_that("expect_no_match works", {
4021
expect_success(expect_no_match("[a]", "[b]"))
4122
expect_success(expect_no_match("[a]", "[b]", fixed = TRUE))
42-
expect_failure(
43-
expect_no_match("te*st", "e*", fixed = TRUE),
44-
escape_regex("te*st")
45-
)
46-
expect_failure(expect_no_match("test", "TEST", ignore.case = TRUE), "test")
23+
24+
x <- "te*st"
25+
expect_snapshot_failure(expect_no_match(x, "e*", fixed = TRUE))
26+
x <- "test"
27+
expect_snapshot_failure(expect_no_match(x, "TEST", ignore.case = TRUE))
28+
})
29+
30+
test_that("empty string is never a match", {
31+
expect_success(expect_no_match(character(), "x"))
4732
})

0 commit comments

Comments
 (0)