Skip to content

Commit 97d1ebd

Browse files
committed
make expect_lt() etc. work properly for non-numeric data
1 parent c80ca1a commit 97d1ebd

File tree

5 files changed

+178
-23
lines changed

5 files changed

+178
-23
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+
* Make `expect_lt()`, `expect_lte()`, `expect_gt()`, and `expect_gte()` work properly for non-numeric data (#2268)
34
* New `expect_disjoint()` to check for the absence of values (@stibu81, #1851).
45
* `expect_all_equal()`, `expect_all_true()`, and `expect_all_false()` are a new family of expectations that checks that every element of a vector has the same value. Compared to using `expect_true(all(...))` they give better failure messages (#1836, #2235).
56
* Expectations now consistently return the value of the first argument, regardless of whether the expectation succeeds or fails. The primary exception are `expect_message()` and friends which will return the condition. This shouldn't affect existing tests, but will make failures clearer when you chain together multiple expectations (#2246).

R/expect-comparison.R

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
#' Do you expect a number bigger or smaller than this?
1+
#' Do you expect a value bigger or smaller than this?
2+
#'
3+
#' These functions compare values of comparable data types, such as numbers,
4+
#' dates, and times.
25
#'
36
#' @inheritParams expect_equal
47
#' @param object,expected A value to compare and its expected bound.
@@ -45,30 +48,41 @@ expect_compare_ <- function(
4548
failure_compare <- function(act, exp, operator) {
4649
actual_op <- switch(operator, "<" = ">=", "<=" = ">", ">" = "<=", ">=" = "<")
4750

48-
diff <- act$val - exp$val
4951
msg_exp <- sprintf("Expected %s %s %s.", act$lab, operator, exp$lab)
5052

51-
digits <- max(
52-
digits(act$val),
53-
digits(exp$val),
54-
min_digits(act$val, exp$val)
55-
)
53+
if (is.numeric(act$val)) {
54+
digits <- max(
55+
digits(act$val),
56+
digits(exp$val),
57+
min_digits(act$val, exp$val)
58+
)
59+
60+
msg_act <- sprintf(
61+
"Actual comparison: %s %s %s",
62+
num_exact(act$val, digits),
63+
actual_op,
64+
num_exact(exp$val, digits)
65+
)
5666

57-
msg_act <- sprintf(
58-
"Actual comparison: %s %s %s",
59-
num_exact(act$val, digits),
60-
actual_op,
61-
num_exact(exp$val, digits)
62-
)
67+
diff <- act$val - exp$val
68+
if (is.na(diff)) {
69+
msg_diff <- NULL
70+
} else {
71+
msg_diff <- sprintf(
72+
"Difference: %s %s 0",
73+
num_exact(diff, digits),
74+
actual_op
75+
)
76+
}
6377

64-
if (is.na(diff)) {
65-
msg_diff <- NULL
6678
} else {
67-
msg_diff <- sprintf(
68-
"Difference: %s %s 0",
69-
num_exact(diff, digits),
70-
actual_op
79+
msg_act <- sprintf(
80+
"Actual comparison: \"%s\" %s \"%s\"",
81+
act$val,
82+
actual_op,
83+
exp$val
7184
)
85+
msg_diff <- NULL
7286
}
7387

7488
c(msg_exp, msg_act, msg_diff)

man/comparison-expectations.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-comparison.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,114 @@
7676
! Expected `x` < 10.
7777
Actual comparison: NA >= 10.0
7878

79+
# comparisons with POSIXct objects work
80+
81+
Code
82+
expect_lt(time2, time)
83+
Condition
84+
Error:
85+
! Expected `time2` < `time`.
86+
Actual comparison: "2020-01-01 01:00:01" >= "2020-01-01 01:00:00"
87+
88+
---
89+
90+
Code
91+
expect_lte(time2, time)
92+
Condition
93+
Error:
94+
! Expected `time2` <= `time`.
95+
Actual comparison: "2020-01-01 01:00:01" > "2020-01-01 01:00:00"
96+
97+
---
98+
99+
Code
100+
expect_gt(time, time2)
101+
Condition
102+
Error:
103+
! Expected `time` > `time2`.
104+
Actual comparison: "2020-01-01 01:00:00" <= "2020-01-01 01:00:01"
105+
106+
---
107+
108+
Code
109+
expect_gte(time, time2)
110+
Condition
111+
Error:
112+
! Expected `time` >= `time2`.
113+
Actual comparison: "2020-01-01 01:00:00" < "2020-01-01 01:00:01"
114+
115+
# comparisons with Date objects work
116+
117+
Code
118+
expect_lt(date2, date)
119+
Condition
120+
Error:
121+
! Expected `date2` < `date`.
122+
Actual comparison: "2020-01-02" >= "2020-01-01"
123+
124+
---
125+
126+
Code
127+
expect_lte(date2, date)
128+
Condition
129+
Error:
130+
! Expected `date2` <= `date`.
131+
Actual comparison: "2020-01-02" > "2020-01-01"
132+
133+
---
134+
135+
Code
136+
expect_gt(date, date2)
137+
Condition
138+
Error:
139+
! Expected `date` > `date2`.
140+
Actual comparison: "2020-01-01" <= "2020-01-02"
141+
142+
---
143+
144+
Code
145+
expect_gte(date, date2)
146+
Condition
147+
Error:
148+
! Expected `date` >= `date2`.
149+
Actual comparison: "2020-01-01" < "2020-01-02"
150+
151+
# comparisons with character objects work
152+
153+
Code
154+
expect_lt("b", "a")
155+
Condition
156+
Error:
157+
! Expected "b" < "a".
158+
Actual comparison: "b" >= "a"
159+
160+
---
161+
162+
Code
163+
expect_lte("b", "a")
164+
Condition
165+
Error:
166+
! Expected "b" <= "a".
167+
Actual comparison: "b" > "a"
168+
169+
---
170+
171+
Code
172+
expect_gt("a", "b")
173+
Condition
174+
Error:
175+
! Expected "a" > "b".
176+
Actual comparison: "a" <= "b"
177+
178+
---
179+
180+
Code
181+
expect_gte("a", "b")
182+
Condition
183+
Error:
184+
! Expected "a" >= "b".
185+
Actual comparison: "a" < "b"
186+
79187
# comparison must yield a single logical
80188

81189
Code

tests/testthat/test-expect-comparison.R

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,44 @@ test_that("comparisons with NA work", {
5858
expect_snapshot_failure(expect_lt(x, 10))
5959
})
6060

61-
test_that("comparisons with more complicated objects work", {
62-
time <- Sys.time()
61+
test_that("comparisons with POSIXct objects work", {
62+
time <- as.POSIXct("2020-01-01 01:00:00")
6363
time2 <- time + 1
6464
expect_success(expect_lt(time, time2))
6565
expect_success(expect_lte(time, time2))
6666
expect_success(expect_gt(time2, time))
6767
expect_success(expect_gte(time2, time))
68+
69+
expect_snapshot_failure(expect_lt(time2, time))
70+
expect_snapshot_failure(expect_lte(time2, time))
71+
expect_snapshot_failure(expect_gt(time, time2))
72+
expect_snapshot_failure(expect_gte(time, time2))
73+
})
74+
75+
test_that("comparisons with Date objects work", {
76+
date <- as.Date("2020-01-01")
77+
date2 <- date + 1
78+
expect_success(expect_lt(date, date2))
79+
expect_success(expect_lte(date, date2))
80+
expect_success(expect_gt(date2, date))
81+
expect_success(expect_gte(date2, date))
82+
83+
expect_snapshot_failure(expect_lt(date2, date))
84+
expect_snapshot_failure(expect_lte(date2, date))
85+
expect_snapshot_failure(expect_gt(date, date2))
86+
expect_snapshot_failure(expect_gte(date, date2))
87+
})
88+
89+
test_that("comparisons with character objects work", {
90+
expect_success(expect_lt("a", "b"))
91+
expect_success(expect_lte("a", "b"))
92+
expect_success(expect_gt("b", "a"))
93+
expect_success(expect_gte("b", "a"))
94+
95+
expect_snapshot_failure(expect_lt("b", "a"))
96+
expect_snapshot_failure(expect_lte("b", "a"))
97+
expect_snapshot_failure(expect_gt("a", "b"))
98+
expect_snapshot_failure(expect_gte("a", "b"))
6899
})
69100

70101
test_that("comparison must yield a single logical", {

0 commit comments

Comments
 (0)