Skip to content

Commit 1191a91

Browse files
committed
Merged origin/main into deprecate-mock
2 parents c7d32bc + ca8fe6a commit 1191a91

File tree

22 files changed

+202
-18
lines changed

22 files changed

+202
-18
lines changed

.github/workflows/R-CMD-check.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ on:
88
push:
99
branches: [main, master]
1010
pull_request:
11-
branches: [main, master]
1211

1312
name: R-CMD-check.yaml
1413

.github/workflows/pkgdown.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ on:
44
push:
55
branches: [main, master]
66
pull_request:
7-
branches: [main, master]
87
release:
98
types: [published]
109
workflow_dispatch:

.github/workflows/test-coverage.yaml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ on:
44
push:
55
branches: [main, master]
66
pull_request:
7-
branches: [main, master]
87

98
name: test-coverage.yaml
109

@@ -35,14 +34,16 @@ jobs:
3534
clean = FALSE,
3635
install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package")
3736
)
37+
print(cov)
3838
covr::to_cobertura(cov)
3939
shell: Rscript {0}
4040

41-
- uses: codecov/codecov-action@v4
41+
- uses: codecov/codecov-action@v5
4242
with:
43-
fail_ci_if_error: ${{ github.event_name != 'pull_request' && true || false }}
44-
file: ./cobertura.xml
45-
plugin: noop
43+
# Fail if error if not on PR, or if on PR and token is given
44+
fail_ci_if_error: ${{ github.event_name != 'pull_request' || secrets.CODECOV_TOKEN }}
45+
files: ./cobertura.xml
46+
plugins: noop
4647
disable_search: true
4748
token: ${{ secrets.CODECOV_TOKEN }}
4849

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: testthat
22
Title: Unit Testing for R
3-
Version: 3.2.2.9000
3+
Version: 3.2.3.9000
44
Authors@R: c(
55
person("Hadley", "Wickham", , "[email protected]", role = c("aut", "cre")),
66
person("Posit Software, PBC", role = c("cph", "fnd")),

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ export(local_test_context)
164164
export(local_test_directory)
165165
export(make_expectation)
166166
export(matches)
167+
export(mock_output_sequence)
167168
export(new_expectation)
168169
export(not)
169170
export(prints_text)

NEWS.md

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

33
* `local_mock()` and `with_mock()` have been deprecated because they are no longer permitted in R 4.5.
4+
* Fixed an issue preventing compilation from succeeding due to deprecation / removal of `std::uncaught_exception()` (@kevinushey, #2047).
5+
6+
# testthat 3.2.3
7+
48
* Fixed an issue where `expect_no_error(1)` was failing (#2037).
59
* Fixed an issue where calling `skip()` outside of an active test could
610
cause an unexpected error (@kevinushey, #2039).

R/expect-known.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,5 +215,5 @@ expect_known_hash <- function(object, hash = NULL) {
215215
}
216216

217217
all_utf8 <- function(x) {
218-
! any(is.na(iconv(x, "UTF-8", "UTF-8")))
218+
!anyNA(iconv(x, "UTF-8", "UTF-8"))
219219
}

R/mock2-helpers.R

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#' Mock a sequence of output from a function
2+
#'
3+
#' Specify multiple return values for mocking
4+
#'
5+
#' @param ... <[`dynamic-dots`][rlang::dyn-dots]> Values to return in sequence.
6+
#' @param recycle whether to recycle. If `TRUE`, once all values have been returned,
7+
#' they will be returned again in sequence.
8+
#'
9+
#' @return A function that you can use within `local_mocked_bindings()` and
10+
#' `with_mocked_bindings()`
11+
#' @export
12+
#'
13+
#' @examples
14+
#' # inside local_mocked_bindings()
15+
#' \dontrun{
16+
#' local_mocked_bindings(readline = mock_output_sequence("3", "This is a note", "n"))
17+
#' }
18+
#' # for understanding
19+
#' mocked_sequence <- mock_output_sequence("3", "This is a note", "n")
20+
#' mocked_sequence()
21+
#' mocked_sequence()
22+
#' mocked_sequence()
23+
#' try(mocked_sequence())
24+
#' recycled_mocked_sequence <- mock_output_sequence(
25+
#' "3", "This is a note", "n",
26+
#' recycle = TRUE
27+
#' )
28+
#' recycled_mocked_sequence()
29+
#' recycled_mocked_sequence()
30+
#' recycled_mocked_sequence()
31+
#' recycled_mocked_sequence()
32+
#' @family mocking
33+
mock_output_sequence <- function(..., recycle = FALSE) {
34+
values <- rlang::list2(...)
35+
i <- 1
36+
function(...) {
37+
if (i > length(values) && !recycle) {
38+
cli::cli_abort(c(
39+
"Can't find value for {i}th iteration.",
40+
i = "{.arg ...} has only {length(values)} values.",
41+
i = "You can set {.arg recycle} to {.code TRUE}."
42+
))
43+
}
44+
index <- (i - 1) %% length(values) + 1
45+
value <- rep_len(values, length.out = index)[[index]]
46+
i <<- i + 1
47+
value
48+
}
49+
}

R/mock2.R

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,17 @@
9292
#' my_wrapper = function(...) "new_value"
9393
#' )
9494
#' ```
95+
#'
96+
#' ## Multiple return values / sequence of outputs
97+
#'
98+
#' To mock a function that returns different values in sequence,
99+
#' for instance an API call whose status would be 502 then 200,
100+
#' or an user intput to `readline()`, you can use [mock_output_sequence()]
101+
#'
102+
#' ```R
103+
#' local_mocked_bindings(readline = mock_output_sequence("3", "This is a note", "n"))
104+
#' ```
105+
#'
95106
#' @export
96107
#' @param ... Name-value pairs providing new values (typically functions) to
97108
#' temporarily replace the named bindings.
@@ -103,6 +114,7 @@
103114
#' under active development (i.e. loaded with [pkgload::load_all()]).
104115
#' We don't recommend using this to mock functions in other packages,
105116
#' as you should not modify namespaces that you don't own.
117+
#' @family mocking
106118
local_mocked_bindings <- function(..., .package = NULL, .env = caller_env()) {
107119
bindings <- list2(...)
108120
check_bindings(bindings)
@@ -132,7 +144,7 @@ local_mocked_bindings <- function(..., .package = NULL, .env = caller_env()) {
132144
local_bindings_rebind(!!!bindings, .env = test_env, .frame = .env)
133145
}
134146

135-
if (any(!bindings_found)) {
147+
if (!all(bindings_found)) {
136148
missing <- names(bindings)[!bindings_found]
137149
cli::cli_abort("Can't find binding for {.arg {missing}}")
138150
}

R/praise.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ praise <- function() {
2121
"\U0001f9ff Your tests look perfect \U0001f9ff",
2222
"\U0001f3af Your tests hit the mark \U0001f3af",
2323
"\U0001f41d Your tests are the bee's knees \U0001f41d",
24-
"\U0001f4a3 Your tests are da bomb \U0001f4a3",
25-
"\U0001f525 Your tests are lit \U0001f525"
24+
"\U0001f3b8 Your tests rock \U0001f3b8",
25+
"\U0001f44f Your tests get an ovation \U0001f44f"
2626
)
2727

2828
x <- if (cli::is_utf8_output()) c(plain, utf8) else plain

0 commit comments

Comments
 (0)