This is an automated email from the git hooks/post-receive script. tille pushed a commit to branch master in repository r-cran-pkgconfig.
commit cc686378965d4045336827a5117eed1bc1bcd48a Author: Andreas Tille <ti...@debian.org> Date: Fri Sep 15 08:56:07 2017 +0200 New upstream version 2.0.1 --- DESCRIPTION | 19 ++++++ LICENSE | 2 + MD5 | 18 ++++++ NAMESPACE | 6 ++ R/getset.R | 115 ++++++++++++++++++++++++++++++++++++ R/pkgconfig-package.R | 13 +++++ R/utils.R | 4 ++ inst/NEWS.markdown | 19 ++++++ inst/README.Rmd | 113 +++++++++++++++++++++++++++++++++++ inst/README.markdown | 113 +++++++++++++++++++++++++++++++++++ man/get_config.Rd | 33 +++++++++++ man/pkgconfig-package.Rd | 16 +++++ man/set_config.Rd | 23 ++++++++ man/set_config_in.Rd | 31 ++++++++++ tests/testthat.R | 9 +++ tests/testthat/test-api.R | 40 +++++++++++++ tests/testthat/test-errors.R | 10 ++++ tests/testthat/test-globalenv.R | 25 ++++++++ tests/testthat/tests.R | 126 ++++++++++++++++++++++++++++++++++++++++ 19 files changed, 735 insertions(+) diff --git a/DESCRIPTION b/DESCRIPTION new file mode 100644 index 0000000..a0c3295 --- /dev/null +++ b/DESCRIPTION @@ -0,0 +1,19 @@ +Package: pkgconfig +Title: Private Configuration for 'R' Packages +Version: 2.0.1 +Author: Gábor Csárdi +Maintainer: Gábor Csárdi <csardi.ga...@gmail.com> +Description: Set configuration options on a per-package basis. + Options set by a given package only apply to that package, + other packages are unaffected. +License: MIT + file LICENSE +LazyData: true +Imports: utils +Suggests: covr, testthat, disposables (>= 1.0.3) +URL: https://github.com/gaborcsardi/pkgconfig +BugReports: https://github.com/gaborcsardi/pkgconfig/issues +Encoding: UTF-8 +NeedsCompilation: no +Packaged: 2017-03-21 10:15:26 UTC; gaborcsardi +Repository: CRAN +Date/Publication: 2017-03-21 15:20:20 UTC diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..510de3e --- /dev/null +++ b/LICENSE @@ -0,0 +1,2 @@ +YEAR: 2014--2017 +COPYRIGHT HOLDER: Gábor Csárdi diff --git a/MD5 b/MD5 new file mode 100644 index 0000000..5dfda65 --- /dev/null +++ b/MD5 @@ -0,0 +1,18 @@ +0866c2f4d8ce2f24b8d1ffe424e12f84 *DESCRIPTION +4b7ff7c348e978f33981b2237200878d *LICENSE +cd8e0bb63bd54833fe1e01ad1a8647d6 *NAMESPACE +9f75eb47d58b82e003713579356c2af6 *R/getset.R +1531da19568f0512ff768360cb78540f *R/pkgconfig-package.R +72539c3bc185b91ce53a54f2bc8336b2 *R/utils.R +126f0602cc011b89c24915b2cf4af4e2 *inst/NEWS.markdown +650807f1f0cac8233dfd54cfdf0d6454 *inst/README.Rmd +650807f1f0cac8233dfd54cfdf0d6454 *inst/README.markdown +df949f83f265547f97085e9ad1891a6b *man/get_config.Rd +e97c9e9fa3c680d05d3758f07448ef2b *man/pkgconfig-package.Rd +006950b03f96ba261abaeb6f225df012 *man/set_config.Rd +d80ab36e7a5e1b8863b79fbbd50466b9 *man/set_config_in.Rd +0138a95afd3fe43ad69771aa955b910a *tests/testthat.R +98b113f008c249e31b7035ba76077f84 *tests/testthat/test-api.R +da73dc4a696ec2066812ab8c467ab361 *tests/testthat/test-errors.R +909e8b0e2558c28ffef1cfae84b8139d *tests/testthat/test-globalenv.R +a196e36e881f8baf7306dd633ada68e2 *tests/testthat/tests.R diff --git a/NAMESPACE b/NAMESPACE new file mode 100644 index 0000000..29fe3f3 --- /dev/null +++ b/NAMESPACE @@ -0,0 +1,6 @@ +# Generated by roxygen2 (4.1.1): do not edit by hand + +export(get_config) +export(set_config) +export(set_config_in) +importFrom(utils,packageName) diff --git a/R/getset.R b/R/getset.R new file mode 100644 index 0000000..f0c7be5 --- /dev/null +++ b/R/getset.R @@ -0,0 +1,115 @@ + +## This is the environment that stores all parameters + +config <- new.env() + +## ---------------------------------------------------------------------- + +#' Query a configuration parameter key +#' +#' Query a configuration parameter key, and return the value +#' set in the calling package(s). +#' +#' @details +#' This function is meant to be called from the package whose +#' behavior depends on it. It searches for the given configuration +#' key, and if it exists, it checks which package(s) it was called +#' from and returns the configuration setting for that package. +#' +#' If the key is not set in any calling package, but it is set in +#' the global environment (i.e. at the R prompt), then it returns that +#' setting. +#' +#' If the key is not set anywhere, then it returns \code{NULL}. +#' +#' @param key The name of the parameter to query. +#' @param fallback Fallback if the parameter id not found anywhere. +#' @return The value of the parameter, or the fallback value if not found. +#' +#' @export + +get_config <- function(key, fallback = NULL) { + result <- get_from_session(key) + if (is.null(result)) fallback else result[[1]] +} + +get_from_session <- function(key) { + value <- config[[key]] + if (is.null(value)) return(NULL) + + pkgs <- sys.frames() + pkgs <- lapply(pkgs, parent.env) + pkgs <- Filter(pkgs, f = isNamespace) + pkgs <- vapply(pkgs, environmentName, "") + pkgs <- unique(pkgs) + + for (p in rev(pkgs)) { + if (p %in% names(value)) return(value[p]) + } + + if ("R_GlobalEnv" %in% names(value)) { + return(value["R_GlobalEnv"]) + } + + NULL +} + +## ---------------------------------------------------------------------- + +#' Set a configuration parameter +#' +#' Set a configuration parameter, for the package we are calling from. +#' If called from the R prompt and not from a package, then it sets +#' the parameter for global environment. +#' +#' @param ... Parameters to set, they should be all named. +#' @return Nothing. +#' +#' @export +#' @seealso \code{\link{set_config_in}} + +set_config <- function(...) { + set_config_in(..., .in = parent.frame()) +} + +check_named_args <- function(...) { + nn <- names(list(...)) + if (is.null(nn) || any(nn == "")) { + stop("Some parameters are not named") + } +} + +#' Set a configuration parameter for a package +#' +#' This is a more flexible variant of \code{link{set_config}}, +#' and it allows creating an custom API in the package that +#' uses \code{pkgconfig} for its configuration. +#' +#' @details +#' This function is identical to \code{\link{set_config}}, but it allows +#' supplying the environment that is used as the package the configuration +#' is set for. This makes it possible to create an API for setting +#' (and getting) configuration parameters. +#' +#' @param ... Parameters to set, they should be all named. +#' @param .in An environment, typically belonging to a package. +#' @return Nothing. +#' +#' @export +#' @seealso \code{\link{set_config}} +#' @importFrom utils packageName + +set_config_in <- function(..., .in = parent.frame()) { + check_named_args(...) + who <- packageName(env = .in) %||% "R_GlobalEnv" + set_config_session(who = who, ...) +} + +set_config_session <- function(who, ...) { + l <- list(...) + for (n in names(l)) { + key <- config[[n]] %||% list() + key[[who]] <- l[[n]] + config[[n]] <- key + } +} diff --git a/R/pkgconfig-package.R b/R/pkgconfig-package.R new file mode 100644 index 0000000..821c0a9 --- /dev/null +++ b/R/pkgconfig-package.R @@ -0,0 +1,13 @@ + +#' Persistent configuration for R packages +#' +#' This package is meant to be used in other packages, and provides +#' configuration options for them. +#' +#' It is currently very minimal, and has two main functions: one +#' for setting configuration options (\code{\link{set_config}}), and one +#' for querying them (\code{\link{get_config}}). +#' +#' @docType package +#' @name pkgconfig-package +NULL diff --git a/R/utils.R b/R/utils.R new file mode 100644 index 0000000..1605613 --- /dev/null +++ b/R/utils.R @@ -0,0 +1,4 @@ + +`%||%` <- function(lhs, rhs) { + if (!is.null(lhs)) { lhs } else { rhs } +} diff --git a/inst/NEWS.markdown b/inst/NEWS.markdown new file mode 100644 index 0000000..a751135 --- /dev/null +++ b/inst/NEWS.markdown @@ -0,0 +1,19 @@ + +# 2.0.1 + +No changes in functionality, only internal cleanup. + +# 2.0.0 + +* Can also be used from the global environment, not only from packages. +* `set_config_in()` function, to allow custom APIs. This means that + packages does not have to use `set_config()` and `get_config()`, but + they can provide their own API. +* Fix a `get_config()` bug, for composite values only the first element + was returned. +* Fix a bug when key was not set at all. In these cases `fallback` was + ignored in `get_config()`. + +# 1.0.0 + +Initial release. diff --git a/inst/README.Rmd b/inst/README.Rmd new file mode 100644 index 0000000..2fd4852 --- /dev/null +++ b/inst/README.Rmd @@ -0,0 +1,113 @@ + +# Private configuration for R packages + +[![Linux Build Status](https://travis-ci.org/gaborcsardi/pkgconfig.svg?branch=master)](https://travis-ci.org/gaborcsardi/pkgconfig) +[![Windows Build status](https://ci.appveyor.com/api/projects/status/github/gaborcsardi/pkgconfig?svg=true)](https://ci.appveyor.com/project/gaborcsardi/pkgconfig) +[![](http://www.r-pkg.org/badges/version/pkgconfig)](http://www.r-pkg.org/pkg/pkgconfig) +[![](http://cranlogs.r-pkg.org/badges/pkgconfig)](http://www.r-pkg.org/pkg/pkgconfig) +[![Coverage Status](https://img.shields.io/codecov/c/github/gaborcsardi/pkgconfig/master.svg)](https://codecov.io/github/gaborcsardi/pkgconfig?branch=master) + +Easy way to create configuration parameters in your R package. Configuration +values set in different packages are independent. + +Call `set_config()` to set a configuration parameter. +Call `get_config()` to query it. + +## Installation + +Use the `devtools` package: + +```r +devtools::install_github("gaborcsardi/pkgconfig") +``` + +## Typical usage + +> Note: this is a real example, but it is not yet implemented in +> the CRAN version of the `igraph` package. + +The igraph package has two ways of returning a set of vertices. Before +version 1.0.0, it simply returned a numeric vector. From version 1.0.0 +it sets an S3 class on this vector by default, but it has an option +called `return.vs.es` that can be set to `FALSE` to request the old +behavior. + +The problem with the `return.vs.es` option is that it is global. Once set +to `FALSE` (interactively or from a package), R will use that setting in +all packages, which breaks packages that expect the new behavior. + +`pkgconfig` solves this problem, by providing configuration settings +that are private to packages. Setting a configuration key from a +given package will only apply to that package. + +## Workflow + +Let's assume that two packages, `pkgA` and `pkgB`, both set the igraph +option `return.vs.es`, but `pkgA` sets it to `TRUE`, and `pkgB` sets it +to `FALSE`. Here is how their code will look. + +### `pkgA` + +`pkgA` imports `set_config` from the `pkgconfig` package, and sets +the `return.vs.es` option from it's `.onLoad` function: + +```r +.onLoad <- function(lib, pkg) { + pkgconfig::set_config("igraph::return.vs.es" = TRUE) +} +``` + +### `pkgB` + +`pkgB` is similar, but it sets the option to `FALSE`: + +```r +.onLoad <- function(lib, pkg) { + pkgconfig::set_config("igraph::return.vs.es" = FALSE) +} +``` + +### `igraph` + +The igraph package will use `get_config` to query the option, and +will supply a fallback value for the cases when it is not set: + +```r +return_vs_es_default <- TRUE +# ... +igraph_func <- function() { + # ... + pkgconfig::get_config("igraph::return.vs.es", return_vs_es_default) + # ... +} +``` + +If `igraph_func` is called from `pkgA` (maybe through other packages), +`get_config` will return `TRUE`, and if it is called from `pkgB`, +`get_config` will return `FALSE`. For all other packages the +`igraph::return.vs.es` option is not set, and the default value is used, +as specified in `igraph`. + +## What if `pkgA` calls `pkgB`? + +It might happen that both `pkgA` and `pkgB` set an option, and +`pkgA` also calls functions from `pkgB`, which in turn, might call +`igraph`. In this case the package that is further down the call +stack wins. In other words, if the call sequence looks like this: + +``` +... -> pkgA -> ... -> pkgB -> ... -> igraph +``` + +then `pkgB`'s value is used in `igraph`. (Assuming the last `...` does +not contain a call to `pkgA` of course.) + +## Feedback + +Please comment in the +[Github issue tracker](https://github.com/gaborcsardi/pkgconfig/issues) +of the project. + +## License + +MIT © [Gábor Csárdi](https://github.com/gaborcsardi) diff --git a/inst/README.markdown b/inst/README.markdown new file mode 100644 index 0000000..2fd4852 --- /dev/null +++ b/inst/README.markdown @@ -0,0 +1,113 @@ + +# Private configuration for R packages + +[![Linux Build Status](https://travis-ci.org/gaborcsardi/pkgconfig.svg?branch=master)](https://travis-ci.org/gaborcsardi/pkgconfig) +[![Windows Build status](https://ci.appveyor.com/api/projects/status/github/gaborcsardi/pkgconfig?svg=true)](https://ci.appveyor.com/project/gaborcsardi/pkgconfig) +[![](http://www.r-pkg.org/badges/version/pkgconfig)](http://www.r-pkg.org/pkg/pkgconfig) +[![](http://cranlogs.r-pkg.org/badges/pkgconfig)](http://www.r-pkg.org/pkg/pkgconfig) +[![Coverage Status](https://img.shields.io/codecov/c/github/gaborcsardi/pkgconfig/master.svg)](https://codecov.io/github/gaborcsardi/pkgconfig?branch=master) + +Easy way to create configuration parameters in your R package. Configuration +values set in different packages are independent. + +Call `set_config()` to set a configuration parameter. +Call `get_config()` to query it. + +## Installation + +Use the `devtools` package: + +```r +devtools::install_github("gaborcsardi/pkgconfig") +``` + +## Typical usage + +> Note: this is a real example, but it is not yet implemented in +> the CRAN version of the `igraph` package. + +The igraph package has two ways of returning a set of vertices. Before +version 1.0.0, it simply returned a numeric vector. From version 1.0.0 +it sets an S3 class on this vector by default, but it has an option +called `return.vs.es` that can be set to `FALSE` to request the old +behavior. + +The problem with the `return.vs.es` option is that it is global. Once set +to `FALSE` (interactively or from a package), R will use that setting in +all packages, which breaks packages that expect the new behavior. + +`pkgconfig` solves this problem, by providing configuration settings +that are private to packages. Setting a configuration key from a +given package will only apply to that package. + +## Workflow + +Let's assume that two packages, `pkgA` and `pkgB`, both set the igraph +option `return.vs.es`, but `pkgA` sets it to `TRUE`, and `pkgB` sets it +to `FALSE`. Here is how their code will look. + +### `pkgA` + +`pkgA` imports `set_config` from the `pkgconfig` package, and sets +the `return.vs.es` option from it's `.onLoad` function: + +```r +.onLoad <- function(lib, pkg) { + pkgconfig::set_config("igraph::return.vs.es" = TRUE) +} +``` + +### `pkgB` + +`pkgB` is similar, but it sets the option to `FALSE`: + +```r +.onLoad <- function(lib, pkg) { + pkgconfig::set_config("igraph::return.vs.es" = FALSE) +} +``` + +### `igraph` + +The igraph package will use `get_config` to query the option, and +will supply a fallback value for the cases when it is not set: + +```r +return_vs_es_default <- TRUE +# ... +igraph_func <- function() { + # ... + pkgconfig::get_config("igraph::return.vs.es", return_vs_es_default) + # ... +} +``` + +If `igraph_func` is called from `pkgA` (maybe through other packages), +`get_config` will return `TRUE`, and if it is called from `pkgB`, +`get_config` will return `FALSE`. For all other packages the +`igraph::return.vs.es` option is not set, and the default value is used, +as specified in `igraph`. + +## What if `pkgA` calls `pkgB`? + +It might happen that both `pkgA` and `pkgB` set an option, and +`pkgA` also calls functions from `pkgB`, which in turn, might call +`igraph`. In this case the package that is further down the call +stack wins. In other words, if the call sequence looks like this: + +``` +... -> pkgA -> ... -> pkgB -> ... -> igraph +``` + +then `pkgB`'s value is used in `igraph`. (Assuming the last `...` does +not contain a call to `pkgA` of course.) + +## Feedback + +Please comment in the +[Github issue tracker](https://github.com/gaborcsardi/pkgconfig/issues) +of the project. + +## License + +MIT © [Gábor Csárdi](https://github.com/gaborcsardi) diff --git a/man/get_config.Rd b/man/get_config.Rd new file mode 100644 index 0000000..92cf0a2 --- /dev/null +++ b/man/get_config.Rd @@ -0,0 +1,33 @@ +% Generated by roxygen2 (4.1.1): do not edit by hand +% Please edit documentation in R/getset.R +\name{get_config} +\alias{get_config} +\title{Query a configuration parameter key} +\usage{ +get_config(key, fallback = NULL) +} +\arguments{ +\item{key}{The name of the parameter to query.} + +\item{fallback}{Fallback if the parameter id not found anywhere.} +} +\value{ +The value of the parameter, or the fallback value if not found. +} +\description{ +Query a configuration parameter key, and return the value +set in the calling package(s). +} +\details{ +This function is meant to be called from the package whose +behavior depends on it. It searches for the given configuration +key, and if it exists, it checks which package(s) it was called +from and returns the configuration setting for that package. + +If the key is not set in any calling package, but it is set in +the global environment (i.e. at the R prompt), then it returns that +setting. + +If the key is not set anywhere, then it returns \code{NULL}. +} + diff --git a/man/pkgconfig-package.Rd b/man/pkgconfig-package.Rd new file mode 100644 index 0000000..cf0d59f --- /dev/null +++ b/man/pkgconfig-package.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2 (4.1.1): do not edit by hand +% Please edit documentation in R/pkgconfig-package.R +\docType{package} +\name{pkgconfig-package} +\alias{pkgconfig-package} +\title{Persistent configuration for R packages} +\description{ +This package is meant to be used in other packages, and provides +configuration options for them. +} +\details{ +It is currently very minimal, and has two main functions: one +for setting configuration options (\code{\link{set_config}}), and one +for querying them (\code{\link{get_config}}). +} + diff --git a/man/set_config.Rd b/man/set_config.Rd new file mode 100644 index 0000000..774f5d9 --- /dev/null +++ b/man/set_config.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2 (4.1.1): do not edit by hand +% Please edit documentation in R/getset.R +\name{set_config} +\alias{set_config} +\title{Set a configuration parameter} +\usage{ +set_config(...) +} +\arguments{ +\item{...}{Parameters to set, they should be all named.} +} +\value{ +Nothing. +} +\description{ +Set a configuration parameter, for the package we are calling from. +If called from the R prompt and not from a package, then it sets +the parameter for global environment. +} +\seealso{ +\code{\link{set_config_in}} +} + diff --git a/man/set_config_in.Rd b/man/set_config_in.Rd new file mode 100644 index 0000000..909d9a2 --- /dev/null +++ b/man/set_config_in.Rd @@ -0,0 +1,31 @@ +% Generated by roxygen2 (4.1.1): do not edit by hand +% Please edit documentation in R/getset.R +\name{set_config_in} +\alias{set_config_in} +\title{Set a configuration parameter for a package} +\usage{ +set_config_in(..., .in = parent.frame()) +} +\arguments{ +\item{...}{Parameters to set, they should be all named.} + +\item{.in}{An environment, typically belonging to a package.} +} +\value{ +Nothing. +} +\description{ +This is a more flexible variant of \code{link{set_config}}, +and it allows creating an custom API in the package that +uses \code{pkgconfig} for its configuration. +} +\details{ +This function is identical to \code{\link{set_config}}, but it allows +supplying the environment that is used as the package the configuration +is set for. This makes it possible to create an API for setting +(and getting) configuration parameters. +} +\seealso{ +\code{\link{set_config}} +} + diff --git a/tests/testthat.R b/tests/testthat.R new file mode 100644 index 0000000..8512ff3 --- /dev/null +++ b/tests/testthat.R @@ -0,0 +1,9 @@ + +if (require(testthat, quietly = TRUE) && + require(disposables, quietly = TRUE)) { + library(pkgconfig) + test_check("pkgconfig") + +} else { + cat("The testthat and disposables packages are required for unit tests") +} diff --git a/tests/testthat/test-api.R b/tests/testthat/test-api.R new file mode 100644 index 0000000..903b33e --- /dev/null +++ b/tests/testthat/test-api.R @@ -0,0 +1,40 @@ + +context("Creating a custom API") + +test_that("We can create a custom API", { + + on.exit(try(disposables::dispose_packages(pkgs))) + pkgs <- disposables::make_packages( + + utility = { + set_opt <- function(...) { + pars <- list(...) + names(pars) <- paste0("utility::", names(pars)) + do.call(pkgconfig::set_config_in, + c(pars, list(.in = parent.frame()))) + } + + get_opt <- function(key) { + real_key <- paste0("utility::", key) + pkgconfig::get_config(real_key) + } + }, + + pkgA = { + setter <- function() { utility::set_opt(key4 = "value_A") } + getter <- function() { utility::get_opt("key4") } + }, + + pkgB = { + setter <- function() { utility::set_opt(key4 = "value_B") } + getter <- function() { utility::get_opt("key4") } + } + ) + + pkgA::setter() + pkgB::setter() + + expect_equal(pkgA::getter(), "value_A") + expect_equal(pkgB::getter(), "value_B") + +}) diff --git a/tests/testthat/test-errors.R b/tests/testthat/test-errors.R new file mode 100644 index 0000000..d241236 --- /dev/null +++ b/tests/testthat/test-errors.R @@ -0,0 +1,10 @@ + +context("Errors") + +test_that("Arguments must be named", { + + expect_error( + set_config("foo" = "bar", "foobar"), + "Some parameters are not named" + ) +}) diff --git a/tests/testthat/test-globalenv.R b/tests/testthat/test-globalenv.R new file mode 100644 index 0000000..69a8566 --- /dev/null +++ b/tests/testthat/test-globalenv.R @@ -0,0 +1,25 @@ + +context("Global env") + +test_that("Global env does not bother packages", { + + evalq(set_config(key3 = "value"), .GlobalEnv) + on.exit(try(evalq(set_config(key3 = NULL), .GlobalEnv)), add = TRUE) + + on.exit(try(disposables::dispose_packages(pkgs)), add = TRUE) + + pkgs <- disposables::make_packages( + pkgA = { + setter <- function() { set_config(key3 = "value2") } + getter <- function() { utility::getter() } + }, + utility = { + getter <- function() { get_config("key3", "fallback") } + } + ) + + pkgA::setter() + + expect_equal(get_config("key3"), "value") + expect_equal(pkgA::getter(), "value2") +}) diff --git a/tests/testthat/tests.R b/tests/testthat/tests.R new file mode 100644 index 0000000..2a8d067 --- /dev/null +++ b/tests/testthat/tests.R @@ -0,0 +1,126 @@ + +context("Session") + +test_that("Session variables", { + + on.exit(try(disposables::dispose_packages(pkgs))) + pkgs <- disposables::make_packages( + pkgconfigtest = { + f <- function() { + set_config(foo = "bar") + get_config("foo") + } + g <- function() { get_config("foo") } + h <- function() { get_config("foobar") } + } + ) + + expect_equal(f(), "bar") + expect_equal(g(), "bar") + expect_null(h()) + +}) + + +test_that("Composite values", { + + on.exit(try(disposables::dispose_packages(pkgs))) + pkgs <- disposables::make_packages( + pkgconfigtest = { + f <- function() { + set_config(foo = list(1,2,3)) + get_config("foo") + } + g <- function() { get_config("foo") } + h <- function() { get_config("foobar") } + } + ) + + expect_equal(f(), list(1,2,3)) + expect_equal(g(), list(1,2,3)) + expect_null(h()) + +}) + +context("Keys are private") + +test_that("Two packages do not interfere", { + + on.exit(try(disposables::dispose_packages(pkgs))) + + pkgs <- disposables::make_packages( + + pkgA = { + setter <- function() { pkgconfig::set_config(key = "A") } + getter <- function() { utility::getter() } + }, + + pkgB = { + setter <- function() { pkgconfig::set_config(key = "B") } + getter <- function() { utility::getter() } + }, + + utility = { + getter <- function() { pkgconfig::get_config("key") } + } + ) + + pkgA::setter() + pkgB::setter() + + expect_equal(pkgA::getter(), "A") + expect_equal(pkgB::getter(), "B") + +}) + +test_that("Cannot get if set by another package", { + + on.exit(try(disposables::dispose_packages(pkgs))) + + pkgs <- disposables::make_packages( + pkgconfigtest1 = { + getter <- function() { get_config("foo") } + getter_parent <- function() { getter() } + }, + pkgconfigtest2 = { + setter <- function() { set_config(foo = "bar") } + } + ) + + pkgconfigtest2::setter() + expect_null(pkgconfigtest1::getter_parent()) +}) + +test_that("Setting from .onLoad works fine", { + + if (utils::packageVersion("disposables") < "1.0.3") { + skip("test needs disposables >= 1.0.3") + } + + on.exit(try(disposables::dispose_packages(pkgs)), add = TRUE) + + pkgs <- disposables::make_packages( + utility = { + getter <- function() { pkgconfig::get_config("key", "fallback") } + }, + + pkgA = { + .onLoad <- function(lib, pkg) { pkgconfig::set_config(key = "A") } + getter <- function() { utility::getter() } + }, + + pkgB = { + .onLoad <- function(lib, pkg) { pkgconfig::set_config(key = "B") } + getter <- function() { utility::getter() } + }, + + pkgC = { + getter <- function() { utility::getter() } + } + ) + + expect_equal(pkgA::getter(), "A") + expect_equal(pkgB::getter(), "B") + expect_equal(pkgC::getter(), "fallback") + +}) -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/r-cran-pkgconfig.git _______________________________________________ debian-med-commit mailing list debian-med-commit@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/debian-med-commit