Skip to content

Commit 3e7628d

Browse files
committed
Merge commit '3c45e5cbf2f4852fa5381b0a18a9a75753d1be24'
2 parents 066ab59 + 3c45e5c commit 3e7628d

23 files changed

+191
-280
lines changed

NAMESPACE

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,16 +145,13 @@ export(is.expectation)
145145
export(is_a)
146146
export(is_checking)
147147
export(is_equivalent_to)
148-
export(is_false)
149148
export(is_identical_to)
150149
export(is_informative_error)
151150
export(is_less_than)
152151
export(is_more_than)
153-
export(is_null)
154152
export(is_parallel)
155153
export(is_snapshot)
156154
export(is_testing)
157-
export(is_true)
158155
export(it)
159156
export(local_edition)
160157
export(local_mock)
@@ -164,10 +161,10 @@ export(local_snapshotter)
164161
export(local_test_context)
165162
export(local_test_directory)
166163
export(make_expectation)
167-
export(matches)
168164
export(mock_output_sequence)
169165
export(new_expectation)
170166
export(not)
167+
export(pass)
171168
export(prints_text)
172169
export(quasi_label)
173170
export(run_cpp_tests)

NEWS.md

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

33
* `expect_no_failures()` and `expect_no_succeses()` are now deprecated as `expect_success()` now test for no failures and `expect_failure()` tests for no successes (#)
4+
* New `pass()` function to use in place of `succeed()` (#2113).
5+
* `expectation()` is now a combination of `new_expectation()` and `exp_signal()` (#2125).
6+
* `is_null()`/`matches()` deprecated in 2.0.0 (2017-12-19) and `is_true()`/`is_false()` deprecated in 2.1.0 (2019-04-23) have been removed (#2109).
47
* `local_edition()` now gives a useful error for bad values (#1547).
58
* testthat now requires R 4.1.
69
* `expect_s4_class()` now supports unquoting (@stibu81, #2064).

R/expect-constant.R

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#'
88
#' Attributes are ignored.
99
#'
10-
#' @seealso [is_false()] for complement
1110
#' @inheritParams expect_that
1211
#' @family expectations
1312
#' @examples

R/expect-self-test.R

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ expect_snapshot_reporter <- function(
165165
paths = test_path("reporters/tests.R")
166166
) {
167167
local_options(rlang_trace_format_srcrefs = FALSE)
168-
local_rng_version("3.3")
168+
withr::local_rng_version("3.3")
169169
set.seed(1014)
170170
# withr::local_seed(1014)
171171

@@ -178,12 +178,6 @@ expect_snapshot_reporter <- function(
178178
)
179179
}
180180

181-
# to work around https://github.com/r-lib/withr/issues/167
182-
local_rng_version <- function(version, .local_envir = parent.frame()) {
183-
withr::defer(RNGversion(as.character(getRversion())), envir = .local_envir)
184-
suppressWarnings(RNGversion(version))
185-
}
186-
187181
# Use specifically for testthat tests in order to override the
188182
# defaults found when starting the reporter
189183
local_output_override <- function(

R/expect-that.R

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,24 @@ expect_that <- function(object, condition, info = NULL, label = NULL) {
3636
condition(object)
3737
}
3838

39-
#' Default expectations that always succeed or fail.
39+
#' `pass()` or `fail()` a test
4040
#'
41-
#' These allow you to manually trigger success or failure. Failure is
42-
#' particularly useful to a pre-condition or mark a test as not yet
43-
#' implemented.
41+
#' @description
42+
#' These are the primitives that you can use to implement your own expectations.
43+
#' Every branch of code inside an expectation must call either `pass()` or
44+
#' `fail()`; learn more in `vignette("custom-expectation")`.
4445
#'
4546
#' @param message a string to display.
46-
#' @inheritParams expect
47+
#' @param info Character vector continuing additional information. Included
48+
#' for backward compatibility only and new expectations should not use it.
49+
#' @param srcref Location of the failure. Should only needed to be explicitly
50+
#' supplied when you need to forward a srcref captured elsewhere.
51+
#' @param trace An optional backtrace created by [rlang::trace_back()].
52+
#' When supplied, the expectation is displayed with the backtrace.
53+
#' @param trace_env If `is.null(trace)`, this is used to automatically
54+
#' generate a traceback running from `test_code()`/`test_file()` to
55+
#' `trace_env`. You'll generally only need to set this if you're wrapping
56+
#' an expectation inside another function.
4757
#' @export
4858
#' @examples
4959
#' \dontrun{
@@ -53,39 +63,41 @@ expect_that <- function(object, condition, info = NULL, label = NULL) {
5363
fail <- function(
5464
message = "Failure has been forced",
5565
info = NULL,
56-
trace_env = caller_env()
66+
srcref = NULL,
67+
trace_env = caller_env(),
68+
trace = NULL
5769
) {
58-
expect(FALSE, message, info = info, trace_env = trace_env)
70+
if (is.null(trace)) {
71+
trace <- trace_back(top = getOption("testthat_topenv"), bottom = trace_env)
72+
}
73+
# Only show if there's at least one function apart from the expectation
74+
if (trace_length(trace) <= 1) {
75+
trace <- NULL
76+
}
77+
78+
message <- paste(c(message, info), collapse = "\n")
79+
expectation("failure", message, srcref = srcref, trace = trace)
5980
}
6081

6182
#' @rdname fail
83+
#' @param value Value to return, typically the result of evaluating the
84+
#' `object` argument to the expectation.
6285
#' @export
63-
succeed <- function(message = "Success has been forced", info = NULL) {
64-
expect(TRUE, message, info = info)
86+
pass <- function(value) {
87+
expectation("success", "success")
88+
invisible(value)
6589
}
6690

67-
#' Negate an expectation
91+
#' Mark a test as successful
6892
#'
69-
#' This negates an expectation, making it possible to express that you
70-
#' want the opposite of a standard expectation. This function is deprecated
71-
#' and will be removed in a future version.
93+
#' This is an older version of [pass()] that exists for backwards compatibility.
94+
#' You should now use `pass()` instead`
7295
#'
73-
#' @param f an existing expectation function
74-
#' @keywords internal
7596
#' @export
76-
not <- function(f) {
77-
warning("`not()` is deprecated.", call. = FALSE)
78-
stopifnot(is.function(f))
79-
80-
negate <- function(expt) {
81-
expect(
82-
!expectation_success(expt),
83-
failure_message = paste0("NOT(", expt$message, ")"),
84-
srcref = expt$srcref
85-
)
86-
}
97+
#' @inheritParams fail
98+
#' @keywords internal
99+
succeed <- function(message = "Success has been forced", info = NULL) {
100+
message <- paste(c(message, info), collapse = "\n")
87101

88-
function(...) {
89-
negate(capture_expectation(f(...)))
90-
}
102+
expectation("success", message)
91103
}

R/expectation.R

Lines changed: 26 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,9 @@
55
#'
66
#' @param ok `TRUE` or `FALSE` indicating if the expectation was successful.
77
#' @param failure_message Message to show if the expectation failed.
8-
#' @param info Character vector continuing additional information. Included
9-
#' for backward compatibility only and new expectations should not use it.
10-
#' @param srcref Location of the failure. Should only needed to be explicitly
11-
#' supplied when you need to forward a srcref captured elsewhere.
12-
#' @param trace An optional backtrace created by [rlang::trace_back()].
13-
#' When supplied, the expectation is displayed with the backtrace.
14-
#' @param trace_env If `is.null(trace)`, this is used to automatically
15-
#' generate a traceback running from `test_code()`/`test_file()` to
16-
#' `trace_env`. You'll generally only need to set this if you're wrapping
17-
#' an expectation inside another function.
18-
#' @return An expectation object. Signals the expectation condition
8+
#' @inheritParams fail
9+
#' @return An expectation object from either `succeed()` or `fail()`.
1910
#' with a `continue_test` restart.
20-
#'
21-
#' @details
22-
#'
23-
#' While `expect()` creates and signals an expectation in one go,
24-
#' `exp_signal()` separately signals an expectation that you
25-
#' have manually created with [new_expectation()]. Expectations are
26-
#' signalled with the following protocol:
27-
#'
28-
#' * If the expectation is a failure or an error, it is signalled with
29-
#' [base::stop()]. Otherwise, it is signalled with
30-
#' [base::signalCondition()].
31-
#'
32-
#' * The `continue_test` restart is registered. When invoked, failing
33-
#' expectations are ignored and normal control flow is resumed to
34-
#' run the other tests.
35-
#'
3611
#' @seealso [exp_signal()]
3712
#' @export
3813
expect <- function(
@@ -43,58 +18,39 @@ expect <- function(
4318
trace = NULL,
4419
trace_env = caller_env()
4520
) {
46-
type <- if (ok) "success" else "failure"
47-
48-
# Preserve existing API which appear to be used in package test code
49-
# Can remove in next major release
50-
if (missing(failure_message)) {
51-
warn("`failure_message` is missing, with no default.")
52-
message <- "unknown failure"
21+
if (ok) {
22+
succeed(failure_message)
5323
} else {
54-
# A few packages include code in info that errors on evaluation
55-
if (ok) {
56-
message <- paste(failure_message, collapse = "\n")
57-
} else {
58-
message <- paste(c(failure_message, info), collapse = "\n")
59-
}
60-
}
61-
62-
if (!ok) {
63-
if (is.null(trace)) {
64-
trace <- trace_back(
65-
top = getOption("testthat_topenv"),
66-
bottom = trace_env
67-
)
68-
}
69-
70-
# Only show if there's at least one function apart from the expectation
71-
if (trace_length(trace) <= 1) {
72-
trace <- NULL
73-
}
24+
fail(
25+
failure_message,
26+
info,
27+
srcref = srcref,
28+
trace = trace,
29+
trace_env = trace_env
30+
)
7431
}
75-
76-
exp <- expectation(type, message, srcref = srcref, trace = trace)
77-
exp_signal(exp)
7832
}
7933

80-
8134
#' Construct an expectation object
8235
#'
36+
#' @description
8337
#' For advanced use only. If you are creating your own expectation, you should
84-
#' call [expect()] instead. See `vignette("custom-expectation")` for more
38+
#' call [pass()] or [fail()]. See `vignette("custom-expectation")` for more
8539
#' details.
8640
#'
87-
#' Create an expectation with `expectation()` or `new_expectation()`
88-
#' and signal it with `exp_signal()`.
41+
#' `new_expectation()` creates an expectation object and `exp_signal()` signals
42+
#' it. `expectation()` does both.
8943
#'
9044
#' @param type Expectation type. Must be one of "success", "failure", "error",
9145
#' "skip", "warning".
9246
#' @param message Message describing test failure
9347
#' @param srcref Optional `srcref` giving location of test.
48+
#' @keywords internal
9449
#' @inheritParams expect
9550
#' @export
9651
expectation <- function(type, message, srcref = NULL, trace = NULL) {
97-
new_expectation(type, message, srcref = srcref, trace = trace)
52+
exp <- new_expectation(type, message, srcref = srcref, trace = trace)
53+
exp_signal(exp)
9854
}
9955
#' @rdname expectation
10056
#' @param ... Additional attributes for the expectation object.
@@ -207,7 +163,7 @@ as.expectation.error <- function(x, srcref = NULL) {
207163
cnd_message(x)
208164
)
209165

210-
expectation("error", msg, srcref, trace = x[["trace"]])
166+
new_expectation("error", msg, srcref = srcref, trace = x[["trace"]])
211167
}
212168

213169

@@ -217,12 +173,17 @@ is_simple_error <- function(x) {
217173

218174
#' @export
219175
as.expectation.warning <- function(x, srcref = NULL) {
220-
expectation("warning", cnd_message(x), srcref, trace = x[["trace"]])
176+
new_expectation(
177+
"warning",
178+
cnd_message(x),
179+
srcref = srcref,
180+
trace = x[["trace"]]
181+
)
221182
}
222183

223184
#' @export
224185
as.expectation.skip <- function(x, ..., srcref = NULL) {
225-
expectation("skip", cnd_message(x), srcref, trace = x[["trace"]])
186+
new_expectation("skip", cnd_message(x), srcref = srcref, trace = x[["trace"]])
226187
}
227188

228189
#' @export

0 commit comments

Comments
 (0)