Skip to content

Commit 7eb22e8

Browse files
authored
Deprecate and remove old mocking functions (#1986)
Fixes #1999
1 parent 3f9e226 commit 7eb22e8

File tree

12 files changed

+4960
-327
lines changed

12 files changed

+4960
-327
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+
* `local_mock()` and `with_mock()` have been deprecated because they are no longer permitted in R 4.5.
34
* `snapshot_review()` now passes `...` on to `shiny::runApp()` (#1928).
45
* `expect_named()` now gives more informative errors (#2091).
56
* `expect_*()` functions consistently and rigorously check their inputs (#1754).

R/mock.R

Lines changed: 6 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
#' Mock functions in a package.
22
#'
33
#' @description
4-
#' `r lifecycle::badge("deprecated")`
4+
#' `r lifecycle::badge("defunct")`
55
#'
6-
#' `with_mock()` and `local_mock()` are deprecated in favour of
7-
#' [with_mocked_bindings()] and [local_mocked_bindings()].
8-
#'
9-
#' These functions worked by using some C code to temporarily modify the mocked
10-
#' function _in place_. This was an abuse of R's internals and it is no longer
11-
#' permitted.
6+
#' `with_mock()` and `local_mock()` are now defunct, and can be replaced by
7+
#' [with_mocked_bindings()] and [local_mocked_bindings()]. These functions only
8+
#' worked by abusing of R's internals.
129
#'
1310
#' @param ... named parameters redefine mocked functions, unnamed parameters
1411
#' will be evaluated after mocking the functions
@@ -18,132 +15,13 @@
1815
#' @param .local_envir Environment in which to add exit handler.
1916
#' For expert use only.
2017
#' @keywords internal
21-
#' @return The result of the last unnamed parameter
2218
#' @export
2319
with_mock <- function(..., .env = topenv()) {
24-
lifecycle::deprecate_warn("3.3.0", "with_mock()", "with_mocked_bindings()")
25-
26-
dots <- eval(substitute(alist(...)))
27-
mock_qual_names <- names(dots)
28-
29-
if (all(mock_qual_names == "")) {
30-
cli::cli_warn(
31-
c(
32-
"Not mocking anything.",
33-
"i" = "Please use named parameters to specify the functions you want to mock."
34-
)
35-
)
36-
code_pos <- rep(TRUE, length(dots))
37-
} else {
38-
code_pos <- (mock_qual_names == "")
39-
}
40-
code <- dots[code_pos]
41-
42-
mock_funs <- lapply(dots[!code_pos], eval, parent.frame())
43-
mocks <- extract_mocks(mock_funs, .env = .env)
44-
45-
withr::defer(lapply(mocks, reset_mock))
46-
lapply(mocks, set_mock)
47-
48-
# Evaluate the code
49-
if (length(code) > 0) {
50-
for (expression in code[-length(code)]) {
51-
eval(expression, parent.frame())
52-
}
53-
# Isolate last item for visibility
54-
eval(code[[length(code)]], parent.frame())
55-
}
20+
lifecycle::deprecate_stop("3.2.0", "with_mock()", "with_mocked_bindings()")
5621
}
5722

5823
#' @export
5924
#' @rdname with_mock
6025
local_mock <- function(..., .env = topenv(), .local_envir = parent.frame()) {
61-
lifecycle::deprecate_warn("3.3.0", "local_mock()", "local_mocked_bindings()")
62-
63-
mocks <- extract_mocks(list(...), .env = .env)
64-
on_exit <- bquote(
65-
withr::defer(lapply(.(mocks), .(reset_mock))),
66-
)
67-
68-
lapply(mocks, set_mock)
69-
eval_bare(on_exit, .local_envir)
70-
invisible()
71-
}
72-
73-
pkg_rx <- ".*[^:]"
74-
colons_rx <- "::(?:[:]?)"
75-
name_rx <- ".*"
76-
pkg_and_name_rx <- sprintf("^(?:(%s)%s)?(%s)$", pkg_rx, colons_rx, name_rx)
77-
78-
extract_mocks <- function(funs, .env) {
79-
if (is.environment(.env)) {
80-
.env <- environmentName(.env)
81-
}
82-
mock_qual_names <- names(funs)
83-
84-
lapply(
85-
stats::setNames(nm = mock_qual_names),
86-
function(qual_name) {
87-
pkg_name <- gsub(pkg_and_name_rx, "\\1", qual_name)
88-
89-
if (is_base_pkg(pkg_name)) {
90-
cli::cli_abort(
91-
"Can't mock functions in base package {.pkg {pkg_name}}."
92-
)
93-
}
94-
95-
name <- gsub(pkg_and_name_rx, "\\2", qual_name)
96-
97-
if (pkg_name == "") {
98-
pkg_name <- .env
99-
}
100-
101-
env <- asNamespace(pkg_name)
102-
103-
if (!exists(name, envir = env, mode = "function")) {
104-
cli::cli_abort(
105-
"Function {.fn {name}} not found in environment {environmentName(env)}."
106-
)
107-
}
108-
mock(name = name, env = env, new = funs[[qual_name]])
109-
}
110-
)
111-
}
112-
113-
mock <- function(name, env, new) {
114-
target_value <- get(name, envir = env, mode = "function")
115-
structure(
116-
list(
117-
env = env,
118-
name = as.name(name),
119-
orig_value = .Call(duplicate_, target_value),
120-
target_value = target_value,
121-
new_value = new
122-
),
123-
class = "mock"
124-
)
125-
}
126-
127-
set_mock <- function(mock) {
128-
.Call(
129-
reassign_function,
130-
mock$name,
131-
mock$env,
132-
mock$target_value,
133-
mock$new_value
134-
)
135-
}
136-
137-
reset_mock <- function(mock) {
138-
.Call(
139-
reassign_function,
140-
mock$name,
141-
mock$env,
142-
mock$target_value,
143-
mock$orig_value
144-
)
145-
}
146-
147-
is_base_pkg <- function(x) {
148-
x %in% rownames(utils::installed.packages(priority = "base"))
26+
lifecycle::deprecate_stop("3.2.0", "local_mock()", "local_mocked_bindings()")
14927
}

man/with_mock.Rd

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

revdep/README.md

Lines changed: 99 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,102 @@
11
# Revdeps
22

3-
## New problems (6)
4-
5-
|package |version |error |warning |note |
6-
|:-------|:--------|:------|:-------|:----|
7-
|[arrow](problems.md#arrow)|17.0.0.1 |__+1__ | |2 |
8-
|[epiCo](problems.md#epico)|1.0.0 |__+1__ | |1 |
9-
|[ieegio](problems.md#ieegio)|0.0.2 |__+1__ | | |
10-
|[madrat](problems.md#madrat)|3.6.4 |__+1__ | | |
11-
|[vines](problems.md#vines)|1.1.5 |__+1__ | | |
12-
|[xpose](problems.md#xpose)|0.4.18 |__+1__ | | |
3+
## Failed to check (34)
4+
5+
|package |version |error |warning |note |
6+
|:-------------------|:---------|:-----|:-------|:----|
7+
|arealDB |0.9.4 |1 | | |
8+
|arules |? | | | |
9+
|atom4R |0.3-3 |1 | | |
10+
|bayesdfa |1.3.4 |1 | | |
11+
|ctsem |3.10.4 |1 | |1 |
12+
|dataone |2.2.2 |1 | | |
13+
|datapack |1.4.1 |1 | | |
14+
|DSMolgenisArmadillo |? | | | |
15+
|dsTidyverse |? | | | |
16+
|dsTidyverseClient |? | | | |
17+
|EcoEnsemble |1.1.2 |1 | | |
18+
|FAfA |0.3 |1 | | |
19+
|FAIRmaterials |0.4.2.1 |1 | | |
20+
|fdaPDE |1.1-21 |1 | | |
21+
|fio |0.1.6 |1 | | |
22+
|geess |? | | | |
23+
|gllvm |2.0.5 |1 | | |
24+
|gpboost |1.6.1 |1 | | |
25+
|gpuR |2.0.6 |1 | | |
26+
|loon.shiny |? | | | |
27+
|loon.tourr |? | | | |
28+
|metajam |0.3.1 |1 | | |
29+
|multinma |0.8.1 |1 | | |
30+
|OpenMx |? | | | |
31+
|rdflib |0.2.9 |1 | | |
32+
|recommenderlab |? | | | |
33+
|redland |1.0.17-18 |1 | | |
34+
|rstanarm |2.32.1 |1 | | |
35+
|SQLFormatteR |0.0.2 |1 | | |
36+
|string2path |0.2.2 |1 | | |
37+
|TestAnaAPP |1.1.2 |1 | | |
38+
|TriDimRegression |1.0.2 |1 | | |
39+
|xactonomial |1.0.3 |1 | | |
40+
|zen4R |0.10.2 |1 | | |
41+
42+
## New problems (56)
43+
44+
|package |version |error |warning |note |
45+
|:------------------|:-------|:--------|:-------|:------|
46+
|[aws.comprehend](problems.md#awscomprehend)|0.2.1 |__+1__ | | |
47+
|[bcRP](problems.md#bcrp)|1.0.1 |__+1__ | | |
48+
|[bindr](problems.md#bindr)|0.1.2 |__+1__ | | |
49+
|[conflr](problems.md#conflr)|0.1.1 |__+1__ | |2 |
50+
|[countdown](problems.md#countdown)|0.4.0 |__+1__ | |1 |
51+
|[covr](problems.md#covr)|3.6.4 |__+1__ | | |
52+
|[datarobot](problems.md#datarobot)|2.18.6 |__+1__ | | |
53+
|[digitize](problems.md#digitize)|0.0.4 |__+1__ | | |
54+
|[distro](problems.md#distro)|0.1.0 |__+1__ | |1 |
55+
|[esci](problems.md#esci)|1.0.7 | | |__+1__ |
56+
|[gen3sis](problems.md#gen3sis)|1.5.11 |__+1__ | |1 |
57+
|[geomorph](problems.md#geomorph)|4.0.10 | | |__+1__ |
58+
|[graphhopper](problems.md#graphhopper)|0.1.2 |__+1__ | |1 |
59+
|[handwriterRF](problems.md#handwriterrf)|1.1.1 |__+1__ | | |
60+
|[humanize](problems.md#humanize)|0.2.0 |__+1__ | |1 |
61+
|[ipaddress](problems.md#ipaddress)|1.0.2 |__+1__ | |1 |
62+
|[leaflet.minicharts](problems.md#leafletminicharts)|0.6.2 |__+1__ | | |
63+
|[learnr](problems.md#learnr)|0.11.5 |__+1__ | | |
64+
|[MakefileR](problems.md#makefiler)|1.0 |__+1__ | |1 |
65+
|[manipulateWidget](problems.md#manipulatewidget)|0.11.1 |__+1__ | |2 |
66+
|[mbbe](problems.md#mbbe)|0.1.0 |__+1__ | | |
67+
|[metaDigitise](problems.md#metadigitise)|1.0.1 |__+1__ | |1 |
68+
|[mknapsack](problems.md#mknapsack)|0.1.0 |__+1__ | | |
69+
|[mockery](problems.md#mockery)|0.4.4 |__+3__ | | |
70+
|[moexer](problems.md#moexer)|0.3.0 |__+1__ | | |
71+
|[MolgenisArmadillo](problems.md#molgenisarmadillo)|2.9.1 |__+1__ | | |
72+
|[NasdaqDataLink](problems.md#nasdaqdatalink)|1.0.0 |__+1__ | | |
73+
|[nhlapi](problems.md#nhlapi)|0.1.4 |__+1__ | |1 |
74+
|[owmr](problems.md#owmr)|0.8.2 |__+1__ | | |
75+
|[oxcAAR](problems.md#oxcaar)|1.1.1 |1 __+1__ | | |
76+
|[parameters](problems.md#parameters)|0.27.0 | | |__+1__ |
77+
|[passport](problems.md#passport)|0.3.0 |__+1__ | | |
78+
|[pocketapi](problems.md#pocketapi)|0.1 |__+1__ | |2 |
79+
|[projmgr](problems.md#projmgr)|0.1.1 |__+1__ | | |
80+
|[PubChemR](problems.md#pubchemr)|2.1.4 |1 __+1__ | |1 |
81+
|[Quandl](problems.md#quandl)|2.11.0 |__+1__ | | |
82+
|[REddyProc](problems.md#reddyproc)|1.3.3 | | |__+1__ |
83+
|[regmedint](problems.md#regmedint)|1.0.1 |__+1__ | |1 |
84+
|[Rexperigen](problems.md#rexperigen)|0.2.1 |__+1__ | |1 |
85+
|[rosetteApi](problems.md#rosetteapi)|1.14.4 |__+1__ | | |
86+
|[Rpolyhedra](problems.md#rpolyhedra)|0.5.6 |__+1__ | | |
87+
|[RPresto](problems.md#rpresto)|1.4.7 |__+1__ | | |
88+
|[RTD](problems.md#rtd)|0.4.1 |__+1__ | |1 |
89+
|[Ryacas0](problems.md#ryacas0)|0.4.4 |__+1__ | |2 |
90+
|[shiny.benchmark](problems.md#shinybenchmark)|0.1.1 |__+1__ | | |
91+
|[shinyShortcut](problems.md#shinyshortcut)|0.1.0 |__+1__ | |1 |
92+
|[skimr](problems.md#skimr)|2.1.5 |__+1__ | | |
93+
|[spaero](problems.md#spaero)|0.6.0 |__+1__ | |4 |
94+
|[starwarsdb](problems.md#starwarsdb)|0.1.2 |__+1__ | |1 |
95+
|[tangles](problems.md#tangles)|2.0.1 |__+1__ | | |
96+
|[texreg](problems.md#texreg)|1.39.4 |__+1__ |1 |2 |
97+
|[ThankYouStars](problems.md#thankyoustars)|0.2.0 |__+1__ | |1 |
98+
|[tinyProject](problems.md#tinyproject)|0.6.1 |__+1__ | | |
99+
|[tryCatchLog](problems.md#trycatchlog)|1.3.1 |__+1__ | |1 |
100+
|[WhatIf](problems.md#whatif)|1.5-10 |__+1__ | | |
101+
|[ZillowR](problems.md#zillowr)|1.0.0 |__+1__ | | |
13102

0 commit comments

Comments
 (0)