diff --git a/DESCRIPTION b/DESCRIPTION index e9833251..6975b540 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -44,7 +44,8 @@ Imports: graphics, grDevices, stats -Suggests: +Suggests: + callr, covr, DBI, knitr, diff --git a/NEWS.md b/NEWS.md index 034688ab..69dd8ac9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,9 @@ # withr (development version) +* Handlers registered with the global environment (as happens when `local_()` + is run at the top-level, outside a function) are now automatically run + when the R session ends (#173). + * New `with_language()` and `local_language()` to temporarily control the language used for translations (#180). diff --git a/R/compat-defer.R b/R/compat-defer.R index 050143ef..f2e1e82e 100644 --- a/R/compat-defer.R +++ b/R/compat-defer.R @@ -13,9 +13,11 @@ defer <<- defer <- function(expr, envir = parent.frame(), priority = c("first", if (identical(envir, .GlobalEnv) && is.null(get_handlers(envir))) { message( "Setting deferred event(s) on global environment.\n", + " * Will be run automatically when session ends\n", " * Execute (and clear) with `withr::deferred_run()`.\n", " * Clear (without executing) with `withr::deferred_clear()`." ) + reg.finalizer(envir, function(env) deferred_run(env), onexit = TRUE) } invisible( add_handler( diff --git a/tests/testthat/_snaps/defer.md b/tests/testthat/_snaps/defer.md index ddc51cc1..337c468b 100644 --- a/tests/testthat/_snaps/defer.md +++ b/tests/testthat/_snaps/defer.md @@ -4,6 +4,7 @@ defer(print("howdy"), envir = globalenv()) Message Setting deferred event(s) on global environment. + * Will be run automatically when session ends * Execute (and clear) with `withr::deferred_run()`. * Clear (without executing) with `withr::deferred_clear()`. diff --git a/tests/testthat/test-defer.R b/tests/testthat/test-defer.R index df0b87db..dad71896 100644 --- a/tests/testthat/test-defer.R +++ b/tests/testthat/test-defer.R @@ -41,6 +41,17 @@ test_that("defer()'s global env facilities work", { expect_null(h) }) +test_that("defered actions in global env are run on exit", { + path <- local_tempfile() + callr::r( + function(path) { + withr::defer(writeLines("a", path), env = globalenv()) + }, + list(path = path) + ) + expect_equal(readLines(path), "a") +}) + test_that("defer executes all handlers even if there is an error in one of them", { old <- options("test_option" = 1)