Skip to content

Commit f303e68

Browse files
authored
Use waldo::compare(list_as_map) in expect_mapequal() (#2150)
This weakens the expectation so it shouldn't cause any existing tests to fail. Fixes #1521
1 parent 86480e2 commit f303e68

File tree

5 files changed

+20
-100
lines changed

5 files changed

+20
-100
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+
* Power `expect_mapequal()` with `waldo::compare(list_as_map = TRUE)` (#1521).
34
* On CRAN, `test_that()` now automatically skips if a package is not installed (#1585). Practically, this means that you no longer need to check that suggested packages are installed. (We don't do this in the tidyverse because we think it has limited payoff, but other styles advise differently.)
45
* `expect_snapshot()` no longer skips on CRAN, as that skips the rest of the test. Instead it just returns, neither succeeding nor failing (#1585).
56
* Interrupting a test now prints the test name. This makes it easier to tell where a very slow test might be hanging (#1464)

R/expect-setequal.R

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
#' (i.e. `y` is a subset of `x`).
77
#' * `expect_in(x, y)` tests every element of `x` is in `y`
88
#' (i.e. `x` is a subset of `y`).
9-
#' * `expect_mapequal(x, y)` tests that `x` and `y` have the same names, and
10-
#' that `x[names(y)]` equals `y`.
9+
#' * `expect_mapequal(x, y)` treats lists as if they are mappings between names
10+
#' and values. Concretely, this drops `NULL`s in both objects and sorts
11+
#' named components.
1112
#'
1213
#' Note that `expect_setequal()` ignores names, and you will be warned if both
1314
#' `object` and `expected` have them.
@@ -77,37 +78,7 @@ expect_mapequal <- function(object, expected) {
7778
act <- quasi_label(enquo(object))
7879
exp <- quasi_label(enquo(expected))
7980

80-
check_vector(object)
81-
check_map_names(object)
82-
check_vector(expected)
83-
check_map_names(expected)
84-
85-
# Length-0 vectors are OK whether named or unnamed.
86-
if (length(act$val) == 0 && length(exp$val) == 0) {
87-
testthat_warn("`object` and `expected` are empty lists")
88-
return(pass(act$val))
89-
}
90-
91-
act_nms <- names(act$val)
92-
exp_nms <- names(exp$val)
93-
if (setequal(act_nms, exp_nms)) {
94-
act <- labelled_value(act$val[exp_nms], act$lab)
95-
return(expect_waldo_equal_("equal", act, exp))
96-
}
97-
98-
act_miss <- setdiff(exp_nms, act_nms)
99-
if (length(act_miss) > 0) {
100-
vals <- paste0(encodeString(act_miss, quote = '"'), ", ")
101-
return(fail(paste0("Names absent from `object`: ", vals)))
102-
}
103-
104-
exp_miss <- setdiff(act_nms, exp_nms)
105-
if (length(exp_miss) > 0) {
106-
vals <- paste0(encodeString(exp_miss, quote = '"'), ", ")
107-
return(fail(paste0("Names absent from `expected`: ", vals)))
108-
}
109-
110-
pass(act$val)
81+
expect_waldo_equal_("equal", act, exp, list_as_map = TRUE)
11182
}
11283

11384
#' @export

man/expect_setequal.Rd

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/_snaps/expect-setequal.md

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -50,43 +50,6 @@
5050
* Only in `expected`: 3, 4, 5, 6, 7, 8, 9, 10, 11, ...
5151

5252

53-
# check inputs
54-
55-
Code
56-
expect_mapequal(sum, named)
57-
Condition
58-
Error in `expect_mapequal()`:
59-
! `object` must be a vector, not a primitive function.
60-
Code
61-
expect_mapequal(named, sum)
62-
Condition
63-
Error in `expect_mapequal()`:
64-
! `expected` must be a vector, not a primitive function.
65-
Code
66-
expect_mapequal(unnamed, named)
67-
Condition
68-
Error in `expect_mapequal()`:
69-
! All elements in `object` must have names.
70-
x Empty names at position: 1
71-
Code
72-
expect_mapequal(named, unnamed)
73-
Condition
74-
Error in `expect_mapequal()`:
75-
! All elements in `expected` must have names.
76-
x Empty names at position: 1
77-
Code
78-
expect_mapequal(named, duplicated)
79-
Condition
80-
Error in `expect_mapequal()`:
81-
! All elements in `expected` must have unique names.
82-
x Duplicate names: "x"
83-
Code
84-
expect_mapequal(duplicated, named)
85-
Condition
86-
Error in `expect_mapequal()`:
87-
! All elements in `object` must have unique names.
88-
x Duplicate names: "x"
89-
9053
# expect_contains() gives useful message on failure
9154

9255
`x1` (`actual`) doesn't fully contain all the values in `x2` (`expected`).

tests/testthat/test-expect-setequal.R

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,16 @@ test_that("ignores order", {
5353
expect_success(expect_mapequal(list(a = 1, b = 2), list(b = 2, a = 1)))
5454
})
5555

56+
test_that("ignores order recursively", {
57+
x <- list(outer_1 = 1, outer_2 = list(inner_1 = 1, inner_2 = 2))
58+
y <- list(outer_2 = list(inner_2 = 2, inner_1 = 1), outer_1 = 1)
59+
expect_success(expect_mapequal(x, y))
60+
})
61+
5662
test_that("error if any names are duplicated", {
57-
expect_error(expect_mapequal(list(a = 1, b = 2, b = 3), list(b = 2, a = 1)))
58-
expect_error(expect_mapequal(list(a = 1, b = 2), list(b = 3, b = 2, a = 1)))
59-
expect_error(expect_mapequal(
63+
expect_failure(expect_mapequal(list(a = 1, b = 2, b = 3), list(b = 2, a = 1)))
64+
expect_failure(expect_mapequal(list(a = 1, b = 2), list(b = 3, b = 2, a = 1)))
65+
expect_failure(expect_mapequal(
6066
list(a = 1, b = 2, b = 3),
6167
list(b = 3, b = 2, a = 1)
6268
))
@@ -75,31 +81,9 @@ test_that("fails if values don't match", {
7581
expect_failure(expect_mapequal(list(a = 1, b = 2), list(a = 1, b = 3)))
7682
})
7783

78-
test_that("check inputs", {
79-
unnamed <- list(1)
80-
named <- list(a = 1)
81-
duplicated <- list(x = 1, x = 2)
82-
83-
expect_snapshot(error = TRUE, {
84-
expect_mapequal(sum, named)
85-
expect_mapequal(named, sum)
86-
87-
expect_mapequal(unnamed, named)
88-
expect_mapequal(named, unnamed)
89-
90-
expect_mapequal(named, duplicated)
91-
expect_mapequal(duplicated, named)
92-
})
93-
})
94-
95-
test_that("succeeds if comparing empty named and unnamed vectors", {
96-
x1 <- list()
97-
x2 <- setNames(list(), character())
98-
99-
expect_warning(expect_success(expect_mapequal(x1, x1)))
100-
expect_warning(expect_success(expect_mapequal(x1, x2)))
101-
expect_warning(expect_success(expect_mapequal(x2, x1)))
102-
expect_warning(expect_success(expect_mapequal(x2, x2)))
84+
test_that("fails if unnamed values in different location if any unnamed values", {
85+
expect_success(expect_mapequal(list(1, b = 2, c = 3), list(1, c = 3, b = 2)))
86+
expect_failure(expect_mapequal(list(1, b = 2, c = 3), list(b = 2, 1, c = 3)))
10387
})
10488

10589
# contains ----------------------------------------------------------------

0 commit comments

Comments
 (0)