R/aaa-cov-env.R

#' Package-Private Coverage Environment
#'
#' `cov_env` is a package-internal environment used by test/coverage helpers
#' (e.g., `cleanup_and_return_null()`) to store temporary state without ever
#' touching the user's workspace (`.GlobalEnv`). It is created at package load
#' time so that a binding for `cov_env` exists *inside the locked package
#' namespace*, which allows tests to temporarily replace its value (mock) while
#' still complying with CRAN’s “no .GlobalEnv modifications” rule.
#'
#' @details
#' **When is it built?**  
#' During package setup, all `R/` files are parsed and evaluated as part of
#' namespace loading. At that point this line is executed:
#'
#' ```
#' cov_env <- new.env(parent = baseenv())
#' ```
#'
#' which creates the binding `cov_env` in the package namespace **before** the
#' namespace is locked by R. Once a namespace is locked, you cannot add or
#' remove bindings—you may only change the *values* of existing bindings. By
#' pre-creating `cov_env`, tests can safely and temporarily replace it (e.g.,
#' with `testthat::local_mocked_bindings()`), because they modify an *existing*
#' binding rather than creating a new one.  (See: R’s environment/namespace
#' locking rules and testthat’s guidance that mocked bindings must already
#' exist.)  [1](https://colinfay.me/writing-r-extensions/writing-r-documentation-files.html)[2](https://contributor.r-project.org/cran-cookbook/code_issues.html)
#'
#' **Why `parent = baseenv()`?**  
#' Using `baseenv()` isolates lookups so they do not fall through to the user’s
#' workspace. This keeps internal state separate and avoids accidental reads or
#' writes to `.GlobalEnv`.  [3](https://github.com/coolbutuseless/CRAN-checks)
#'
#' **Testing tip:**  
#' In unit tests, you can temporarily replace this binding without editing the
#' global environment:
#'
#' ```
#' testthat::local_mocked_bindings(
#'   .package = "yourpkg",
#'   cov_env  = new.env(parent = baseenv())
#' )
#' ```
#'
#' This works because the `cov_env` *binding already exists* in the namespace;
#' `local_mocked_bindings()` cannot create new bindings in a locked namespace.  [2](https://contributor.r-project.org/cran-cookbook/code_issues.html)
#'
#' @keywords internal
cov_env <- new.env(parent = baseenv())   # package-private state

Try the test.assessr package in your browser

Any scripts or data that you put into this service are public.

test.assessr documentation built on March 3, 2026, 1:06 a.m.