Skip to content

Commit 3d32674

Browse files
committed
Merged origin/main into stibu81-main
2 parents 100e4e0 + 558c788 commit 3d32674

File tree

93 files changed

+8454
-2314
lines changed

Some content is hidden

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

93 files changed

+8454
-2314
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,4 @@ Config/testthat/parallel: true
5757
Config/testthat/start-first: watcher, parallel*
5858
Encoding: UTF-8
5959
Roxygen: list(markdown = TRUE, r6 = FALSE)
60-
RoxygenNote: 7.3.2
60+
RoxygenNote: 7.3.3

NAMESPACE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ export(equals_reference)
7979
export(evaluate_promise)
8080
export(exp_signal)
8181
export(expect)
82+
export(expect_all_equal)
83+
export(expect_all_false)
84+
export(expect_all_true)
8285
export(expect_condition)
8386
export(expect_contains)
8487
export(expect_cpp_tests_pass)

NEWS.md

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
# testthat (development version)
22

33
* New `expect_disjoint()` to check for the absence of values (#1851).
4+
* `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).
5+
* 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).
6+
* `set_state_inspector()` gains `tolerance` argument and ignores minor FP differences by default (@mcol, #2237).
7+
* `expect_vector()` fails, instead of erroring, if `object` is not a vector (@plietar, #2224).
48
* New `vignette("mocking")` explains mocking in detail (#1265).
59
* New `vignette("challenging-functions")` provides an index to other documentation organised by testing challenges (#1265).
6-
* When running a test interactively, testthat now reports the number of succeses. The results should also be more useful if you are using nested tests.
7-
* The hints generated by `expect_snapshot()` and `expect_snapshot_file()` now include the path to the package, if its not in the current working directory (#1577).
8-
* `expect_snapshot_file()` now clearly errors if the `path` doesnt exist (#2191).
10+
* When running a test interactively, testthat now reports the number of successes. The results should also be more useful if you are using nested tests.
11+
* The hints generated by `expect_snapshot()` and `expect_snapshot_file()` now include the path to the package, if it's not in the current working directory (#1577).
12+
* `expect_snapshot_file()` now clearly errors if the `path` doesn't exist (#2191).
913
* `expect_snapshot_file()` now considers `.json` to be a text file (#1593).
1014
* `expect_snapshot_file()` now shows differences for text files (#1593).
1115
* The failure messages for all `expect_` functions have been rewritten to first state what was expected and then what was actually received (#2142).
@@ -15,21 +19,20 @@
1519
* New `snapshot_download_gh()` makes it easy to get snapshots off GitHub and into your local package (#1779).
1620
* New `local_mocked_s3_method()`, `local_mocked_s4_method()`, and `local_mocked_r6_class()` allow you to mock S3 and S4 methods and R6 classes (#1892, #1916)
1721
* `expect_snapshot_file(name=)` must have a unique file path. If a snapshot file attempts to be saved with a duplicate `name`, an error will be thrown. (#1592)
18-
* `test_dir()`, `test_file()`, `test_package()`, `test_check()`, `test_local()`, `source_file()` gain a `shuffle` argument uses `sample()` to randomly reorder the top-level expressions in each test file (#1942). This random reordering surfaces dependencies between tests and code outside of any test, as well as dependencies between tests. This helps you find and eliminate unintentional dependencies.
22+
* `test_dir()`, `test_file()`, `test_package()`, `test_check()`, `test_local()`, `source_file()` gain a `shuffle` argument that uses `sample()` to randomly reorder the top-level expressions in each test file (#1942). This random reordering surfaces dependencies between tests and code outside of any test, as well as dependencies between tests. This helps you find and eliminate unintentional dependencies.
1923
* `snapshot_accept(test)` now works when the test file name contains `.` (#1669).
2024
* `local_mock()` and `with_mock()` have been deprecated because they are no longer permitted in R 4.5.
2125
* `snapshot_review()` now passes `...` on to `shiny::runApp()` (#1928).
2226
* `expect_named()` now gives more informative errors (#2091).
23-
* `expect_*()` functions consistently and rigorously check their inputs (#1754).
27+
* `expect_*()` functions consistently and rigorously check their inputs (#1754).
2428
* `test_that()` no longer warns about the absence of `{}` since it no longer seems to be necessary.
2529
* `test_that()`, `describe()`, and `it()` can now be arbitrarily nested. Each component will skip only if it and its subtests don't contain any expectations. The interactive stop reporter has been fixed so it doesn't duplicate failures. (#2063, #2188).
2630
* Test filtering now works with `it()`, and the `desc` argument can take a character vector in order to recursively filter subtests (i.e. `it()` nested inside of `describe()`) (#2118).
2731
* New `snapshot_reject()` rejects all modified snapshots by deleting the `.new` variants (#1923).
2832
* New `SlowReporter` makes it easier to find the slowest tests in your package. The easiest way to run it is with `devtools::test(reporter = "slow")` (#1466).
29-
* Power `expect_mapequal()` with `waldo::compare(list_as_map = TRUE)` (#1521).
3033
* 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.)
3134
* `expect_snapshot()` no longer skips on CRAN, as that skips the rest of the test. Instead it just returns, neither succeeding nor failing (#1585).
32-
* Interrupting a test now prints the test name. This makes it easier to tell where a very slow test might be hanging (#1464)
35+
* Interrupting a test now prints the test name. This makes it easier to tell where a very slow test might be hanging (#1464).
3336
* Parallel testthat now does not ignore test files with syntax errors (#1360).
3437
* `expect_lt()`, `expect_gt()`, and friends have a refined display that is more likely to display the correct number of digits and shows you the actual values compared.
3538
* `describe()`, `it()`, and `test_that()` now have a shared stack of descriptions so that if you nest any inside of each other, any resulting failures will show you the full path.
@@ -39,9 +42,9 @@
3942
* New `expect_r6_class()` (#2030).
4043
* `expect_*()` functions consistently and rigorously check their inputs (#1754).
4144
* `JunitReporter()` no longer fails with `"no applicable method for xml_add_child"` for warnings outside of tests (#1913). Additionally, warnings now save their backtraces.
42-
* `JunitReporter()` strips ANSI escapes in more placese (#1852, #2032).
45+
* `JunitReporter()` strips ANSI escapes in more places (#1852, #2032).
4346
* `try_again()` is now publicised. The first argument is now the number of retries, not tries (#2050).
44-
* `vignette("custom-expectations)` has been overhauled to make it much clearer how to create high-quality expectations (#2113, #2132, #2072).
47+
* `vignette("custom-expectations")` has been overhauled to make it much clearer how to create high-quality expectations (#2113, #2132, #2072).
4548
* `expect_snapshot()` and friends will now fail when creating a new snapshot on CI. This is usually a signal that you've forgotten to run it locally before committing (#1461).
4649
* `expect_snapshot_value()` can now handle expressions that generate `-` (#1678) or zero length atomic vectors (#2042).
4750
* `expect_matches()` failures should be a little easier to read (#2135, #2181).
@@ -988,7 +991,7 @@ This release mostly focusses on an overhaul of how testthat works with condition
988991
* In `expect_equal_to_reference()`, the default value for `update` is
989992
now `FALSE` (@BrodieG, #683).
990993

991-
* `expect_error()` now returns the error object as documentated (#724).
994+
* `expect_error()` now returns the error object as documented (#724).
992995
It also now warns if you're using a classed expectation and you're
993996
not using the `class` argument. This is good practice as it decouples the
994997
error object (which tends to be stable) from its rendering to the user
@@ -1680,7 +1683,7 @@ The reporters system class has been considerably refactored to make existing rep
16801683
* `safe_digest()` uses a better strategy, and returns NA for directories
16811684
(#138, #146).
16821685

1683-
* Random praise is renabled by default (again!) (#164).
1686+
* Random praise is re-enabled by default (again!) (#164).
16841687

16851688
* Teamcity reporter now correctly escapes output messages (#150, @windelinckx).
16861689
It also uses nested suites to include test names.

R/expect-all.R

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#' Do you expect every value in a vector to have this value?
2+
#'
3+
#' These expectations are similar to `expect_true(all(x == "x"))`,
4+
#' `expect_true(all(x))` and `expect_true(all(!x))` but give more informative
5+
#' failure messages if the expectations are not met.
6+
#'
7+
#' @inheritParams expect_equal
8+
#' @export
9+
#' @examples
10+
#' x1 <- c(1, 1, 1, 1, 1, 1)
11+
#' expect_all_equal(x1, 1)
12+
#'
13+
#' x2 <- c(1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2)
14+
#' show_failure(expect_all_equal(x2, 1))
15+
#'
16+
#' # expect_all_true() and expect_all_false() are helpers for common cases
17+
#' set.seed(1016)
18+
#' show_failure(expect_all_true(rpois(100, 10) < 20))
19+
#' show_failure(expect_all_false(rpois(100, 10) > 20))
20+
expect_all_equal <- function(object, expected) {
21+
act <- quasi_label(enquo(object))
22+
exp <- quasi_label(enquo(expected))
23+
24+
expect_all_equal_(act, exp)
25+
invisible(act$val)
26+
}
27+
28+
#' @export
29+
#' @rdname expect_all_equal
30+
expect_all_true <- function(object) {
31+
act <- quasi_label(enquo(object))
32+
exp <- labelled_value(TRUE, "TRUE")
33+
34+
expect_all_equal_(act, exp)
35+
invisible(act$val)
36+
}
37+
38+
#' @export
39+
#' @rdname expect_all_equal
40+
expect_all_false <- function(object) {
41+
act <- quasi_label(enquo(object))
42+
exp <- labelled_value(FALSE, "FALSE")
43+
44+
expect_all_equal_(act, exp)
45+
invisible(act$val)
46+
}
47+
48+
49+
expect_all_equal_ <- function(act, exp, trace_env = caller_env()) {
50+
check_vector(act$val, error_call = trace_env, error_arg = "object")
51+
if (length(act$val) == 0) {
52+
cli::cli_abort("{.arg object} must not be empty.", call = trace_env)
53+
}
54+
55+
check_vector(exp$val, error_call = trace_env, error_arg = "expected")
56+
if (length(exp$val) != 1) {
57+
cli::cli_abort("{.arg expected} must be length 1.", call = trace_env)
58+
}
59+
60+
exp$val <- rep(exp$val, length(act$val))
61+
names(exp$val) <- names(act$val)
62+
expect_waldo_equal_(
63+
"Expected every element of %s to equal %s.",
64+
act,
65+
exp,
66+
tolerance = testthat_tolerance(),
67+
trace_env = trace_env
68+
)
69+
}

R/expect-comparison.R

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,52 +28,60 @@ expect_compare_ <- function(
2828
operator <- match.arg(operator)
2929
op <- match.fun(operator)
3030

31-
actual_op <- switch(operator, "<" = ">=", "<=" = ">", ">" = "<=", ">=" = "<")
32-
3331
cmp <- op(act$val, exp$val)
3432
if (length(cmp) != 1 || !is.logical(cmp)) {
3533
cli::cli_abort(
36-
"Result of comparison must be a single logical value.",
34+
"Result of comparison must be `TRUE`, `FALSE`, or `NA`",
3735
call = trace_env
3836
)
37+
} else if (!isTRUE(cmp)) {
38+
msg <- failure_compare(act, exp, operator)
39+
fail(msg, trace_env = trace_env)
40+
} else {
41+
pass()
3942
}
40-
if (!isTRUE(cmp)) {
41-
diff <- act$val - exp$val
42-
msg_exp <- sprintf("Expected %s %s %s.", act$lab, operator, exp$lab)
43-
44-
digits <- max(
45-
digits(act$val),
46-
digits(exp$val),
47-
min_digits(act$val, exp$val)
48-
)
43+
}
4944

50-
msg_act <- sprintf(
51-
"Actual comparison: %s %s %s",
52-
num_exact(act$val, digits),
53-
actual_op,
54-
num_exact(exp$val, digits)
55-
)
45+
failure_compare <- function(act, exp, operator) {
46+
actual_op <- switch(operator, "<" = ">=", "<=" = ">", ">" = "<=", ">=" = "<")
5647

57-
if (is.na(diff)) {
58-
msg_diff <- NULL
59-
} else {
60-
msg_diff <- sprintf(
61-
"Difference: %s %s 0",
62-
num_exact(diff, digits),
63-
actual_op
64-
)
65-
}
66-
return(fail(c(msg_exp, msg_act, msg_diff), trace_env = trace_env))
48+
diff <- act$val - exp$val
49+
msg_exp <- sprintf("Expected %s %s %s.", act$lab, operator, exp$lab)
50+
51+
digits <- max(
52+
digits(act$val),
53+
digits(exp$val),
54+
min_digits(act$val, exp$val)
55+
)
56+
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+
)
63+
64+
if (is.na(diff)) {
65+
msg_diff <- NULL
66+
} else {
67+
msg_diff <- sprintf(
68+
"Difference: %s %s 0",
69+
num_exact(diff, digits),
70+
actual_op
71+
)
6772
}
68-
pass(act$val)
73+
74+
c(msg_exp, msg_act, msg_diff)
6975
}
76+
7077
#' @export
7178
#' @rdname comparison-expectations
7279
expect_lt <- function(object, expected, label = NULL, expected.label = NULL) {
7380
act <- quasi_label(enquo(object), label)
7481
exp <- quasi_label(enquo(expected), expected.label)
7582

7683
expect_compare_("<", act, exp)
84+
invisible(act$val)
7785
}
7886

7987
#' @export
@@ -83,6 +91,7 @@ expect_lte <- function(object, expected, label = NULL, expected.label = NULL) {
8391
exp <- quasi_label(enquo(expected), expected.label)
8492

8593
expect_compare_("<=", act, exp)
94+
invisible(act$val)
8695
}
8796

8897
#' @export
@@ -92,6 +101,7 @@ expect_gt <- function(object, expected, label = NULL, expected.label = NULL) {
92101
exp <- quasi_label(enquo(expected), expected.label)
93102

94103
expect_compare_(">", act, exp)
104+
invisible(act$val)
95105
}
96106

97107
#' @export
@@ -101,6 +111,7 @@ expect_gte <- function(object, expected, label = NULL, expected.label = NULL) {
101111
exp <- quasi_label(enquo(expected), expected.label)
102112

103113
expect_compare_(">=", act, exp)
114+
invisible(act$val)
104115
}
105116

106117

R/expect-condition.R

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,11 @@ expect_error <- function(
143143
# Access error fields with `[[` rather than `$` because the
144144
# `$.Throwable` from the rJava package throws with unknown fields
145145
if (!is.null(msg)) {
146-
return(fail(msg, info = info, trace = act$cap[["trace"]]))
146+
fail(msg, info = info, trace = act$cap[["trace"]])
147+
} else {
148+
pass()
147149
}
148-
pass(act$val %||% act$cap)
150+
invisible(act$val %||% act$cap)
149151
}
150152
}
151153

@@ -198,9 +200,11 @@ expect_warning <- function(
198200
cond_type = "warnings"
199201
)
200202
if (!is.null(msg)) {
201-
return(fail(msg, info = info))
203+
fail(msg, info = info)
204+
} else {
205+
pass()
202206
}
203-
pass(act$val)
207+
invisible(act$val)
204208
}
205209
}
206210

@@ -236,9 +240,11 @@ expect_message <- function(
236240
act <- quasi_capture(enquo(object), label, capture_messages)
237241
msg <- compare_messages(act$cap, act$lab, regexp = regexp, all = all, ...)
238242
if (!is.null(msg)) {
239-
return(fail(msg, info = info))
243+
fail(msg, info = info)
244+
} else {
245+
pass()
240246
}
241-
pass(act$val)
247+
invisible(act$val)
242248
}
243249
}
244250

@@ -285,9 +291,11 @@ expect_condition <- function(
285291
cond_type = "condition"
286292
)
287293
if (!is.null(msg)) {
288-
return(fail(msg, info = info, trace = act$cap[["trace"]]))
294+
fail(msg, info = info, trace = act$cap[["trace"]])
295+
} else {
296+
pass()
289297
}
290-
pass(act$val %||% act$cap)
298+
invisible(act$val %||% act$cap)
291299
}
292300
}
293301

@@ -327,16 +335,18 @@ expect_condition_matching_ <- function(
327335
# Access error fields with `[[` rather than `$` because the
328336
# `$.Throwable` from the rJava package throws with unknown fields
329337
if (!is.null(msg)) {
330-
return(fail(
338+
fail(
331339
msg,
332340
info = info,
333341
trace = act$cap[["trace"]],
334342
trace_env = trace_env
335-
))
343+
)
344+
} else {
345+
pass()
336346
}
337347
# If a condition was expected, return it. Otherwise return the value
338348
# of the expression.
339-
pass(if (expected) act$cap else act$val)
349+
invisible(if (expected) act$cap else act$val)
340350
}
341351

342352
# -------------------------------------------------------------------------

0 commit comments

Comments
 (0)