Import a package with only local side-effect

47 Views Asked by At

When writing tests, I sometimes want to check how R would react to conflicts.

For instance, my package contains a compact() function that conflicts with purrr::compact(), and I wrote some code so that this latter is still used on regular lists.

In my tests, I want to check that purrr::compact() will still work on regular lists if my package is loaded.

Therefore, I wrote a unit-test that looks a bit like this:

test_that("Test A", {
    library(purrr, include.only="compact", warn.conflicts=FALSE)
    compact = crosstable::compact
    x = list(a = "a", b = NULL, c = integer(0), d = NA, e = list())
    expect_identical(compact(x), list(a="a",d=NA))
})

However, the library() call has a global effect that kind of messes up with some other unrelated tests.

Is there a way to import a library locally?

I'm thinking about something like rlang::local_options().

1

There are 1 best solutions below

0
On

My first idea is a great package withr which helps with all temp related problems. Take into account that namespace will be still there, loadedNamespaces().

Example of usage from .GlobalEnv:

search()
#>  [1] ".GlobalEnv"        "package:stats"     "package:graphics" 
#>  [4] "package:grDevices" "package:utils"     "package:datasets" 
#>  [7] "package:methods"   "Autoloads"         "tools:callr"      
#> [10] "package:base"
withr::with_package("dplyr", {airquality %>% mutate(n = 2) %>% head()})
#>   Ozone Solar.R Wind Temp Month Day n
#> 1    41     190  7.4   67     5   1 2
#> 2    36     118  8.0   72     5   2 2
#> 3    12     149 12.6   74     5   3 2
#> 4    18     313 11.5   62     5   4 2
#> 5    NA      NA 14.3   56     5   5 2
#> 6    28      NA 14.9   66     5   6 2
mutate
#> Error in eval(expr, envir, enclos): object 'mutate' not found
search()
#>  [1] ".GlobalEnv"        "package:stats"     "package:graphics" 
#>  [4] "package:grDevices" "package:utils"     "package:datasets" 
#>  [7] "package:methods"   "Autoloads"         "tools:callr"      
#> [10] "package:base"

Created on 2021-06-21 by the reprex package (v2.0.0)

Another idea is usage of utils::getFromNamespace:

fun <- utils::getFromNamespace("fun", "pkg")