test_that("resolving with a list", { conf <- current_config() cache <- list(package = pkgcache::package_cache$new(), metadata = NULL) do <- function() { res <- new_resolution(config = conf, cache = cache) res$push(.list = parse_pkg_refs("foo::bar")) res$push(.list = parse_pkg_refs("foo::bar2")) res$when_complete() } foo_resolve <- function(remote, direct, config, cache, dependencies) { list(ref = remote$ref, type = remote$type, package = remote$rest, version = "1.0.0", sources = c("src1", "src2"), direct = direct) } res <- withr::with_options( list(pkg.remote_types = list(foo = list(resolve = foo_resolve))), synchronise(do())) expect_equal(nrow(res), 2) expect_identical(res$ref, c("foo::bar", "foo::bar2")) expect_identical(res$package, c("bar", "bar2")) expect_identical(res$status, c("OK", "OK")) expect_true(is.list(res$remote[[1]])) expect_true(is.list(res$remote[[2]])) expect_identical(res$sources, list(c("src1", "src2"), c("src1", "src2"))) }) test_that("resolving with a tbl", { conf <- current_config() cache <- list(package = pkgcache::package_cache$new(), metadata = NULL) do <- function() { res <- new_resolution(config = conf, cache = cache) res$push(.list = parse_pkg_refs("foo::bar")) res$push(.list = parse_pkg_refs("foo2::bar2")) res$when_complete() } foo_resolve <- function(remote, direct, config, cache, dependencies) { data_frame(ref = remote$ref, type = c("type1", "type2"), package = c("pkg1", "pkg2"), version = c("ver1", "ver2"), sources = list(c("s11", "s12"), c("s21", "s22")), direct = direct) } types <- list(foo = list(resolve = foo_resolve), foo2 = list(resolve = foo_resolve)) res <- withr::with_options( list(pkg.remote_types = types), synchronise(do())) expect_equal(nrow(res), 4) expect_identical(res$ref, c("foo::bar", "foo::bar", "foo2::bar2", "foo2::bar2")) expect_identical(res$package, c("pkg1", "pkg2", "pkg1", "pkg2")) expect_identical(res$status, c("OK", "OK", "OK", "OK")) expect_true(is.list(res$remote[[1]])) expect_true(is.list(res$remote[[2]])) expect_identical( res$sources, list(c("s11", "s12"), c("s21", "s22"), c("s11", "s12"), c("s21", "s22")) ) }) test_that("unknown deps are pushed in the queue", { conf <- current_config() cache <- list(package = pkgcache::package_cache$new(), metadata = NULL) do <- function() { res <- new_resolution(config = conf, cache = cache) res$push(.list = parse_pkg_refs("foo::bar")) res$when_complete() } foo_resolve <- function(remote, direct, config, cache, dependencies) { list(ref = remote$ref, type = remote$type, package = remote$rest, version = "1.0.0", sources = c("src1", "src2"), unknown_deps = "foo::bar2", direct = direct) } res <- withr::with_options( list(pkg.remote_types = list(foo = list(resolve = foo_resolve))), synchronise(do())) expect_equal(nrow(res), 2) expect_identical(res$ref, c("foo::bar", "foo::bar2")) expect_identical(res$package, c("bar", "bar2")) expect_identical(res$status, c("OK", "OK")) expect_true(is.list(res$remote[[1]])) expect_true(is.list(res$remote[[2]])) expect_identical(res$sources, list(c("src1", "src2"), c("src1", "src2"))) }) test_that("unknown deps, tble", { conf <- current_config() cache <- list(package = pkgcache::package_cache$new(), metadata = NULL) do <- function() { res <- new_resolution(config = conf, cache = cache) res$push(.list = parse_pkg_refs("foo::bar")) res$when_complete() } foo_resolve <- function(remote, direct, config, cache, dependencies) { data_frame(ref = remote$ref, type = c("type1", "type2"), package = c("pkg1", "pkg2"), version = c("ver1", "ver2"), sources = list(c("s11", "s12"), c("s21", "s22")), unknown_deps = "foo::bar2", direct = direct, params = list(character())) } types <- list(foo = list(resolve = foo_resolve), foo2 = list(resolve = foo_resolve)) res <- withr::with_options( list(pkg.remote_types = types), synchronise(do())) expect_equal(nrow(res), 4) expect_identical(res$ref, c("foo::bar", "foo::bar", "foo::bar2", "foo::bar2")) expect_identical(res$package, c("pkg1", "pkg2", "pkg1", "pkg2")) expect_identical(res$status, c("OK", "OK", "OK", "OK")) expect_true(is.list(res$remote[[1]])) expect_true(is.list(res$remote[[2]])) expect_identical( res$sources, list(c("s11", "s12"), c("s21", "s22"), c("s11", "s12"), c("s21", "s22")) ) }) test_that("error", { conf <- current_config() cache <- list(package = pkgcache::package_cache$new(), metadata = NULL) do <- function() { res <- new_resolution(config = conf, cache = cache) res$push(.list = parse_pkg_refs("foo::bar")) res$push(.list = parse_pkg_refs("foo::bar2")) res$when_complete() } foo_resolve <- function(remote, direct, config, cache, dependencies) { stop("foobar", call. = FALSE) } res <- withr::with_options( list(pkg.remote_types = list(foo = list(resolve = foo_resolve))), synchronise(do())) expect_equal(nrow(res), 2) expect_equal(res$ref, c("foo::bar", "foo::bar2")) expect_snapshot(res$error[[1]]) expect_snapshot(res$error[[2]]) expect_equal(res$status, c("FAILED", "FAILED")) expect_equal(res$type, c("foo", "foo")) }) test_that("installed refs are also resolved", { conf <- current_config() mkdirp(lib <- tempfile()) lib <- normalizePath(lib) on.exit(unlink(lib, recursive = TRUE), add = TRUE) mkdirp(file.path(lib, "bar")) mkdirp(file.path(lib, "bar2")) cache <- list(package = pkgcache::package_cache$new(), metadata = NULL) cache$installed <- list( pkgs = data_frame( ref = paste0("installed::", lib, c("/bar", "/bar2")), type = "installed", status = "OK", package = c("bar", "bar2"), version = "1.0.9", license = NA_character_, needscompilation = TRUE, priority = NA_character_, md5sum = NA_character_, platform = "source", rversion = "*", sources = list(NULL, NULL), built = NA_character_, deps = list(NULL, NULL), repotype = NA_character_, sysreqs = NA_character_) ) do <- function() { res <- new_resolution(config = conf, cache = cache, library = lib) res$push(.list = parse_pkg_refs("foo::bar")) res$push(.list = parse_pkg_refs("foo::bar2")) res$when_complete() } foo_resolve <- function(remote, direct, config, cache, dependencies) { list(ref = remote$ref, type = remote$type, package = remote$rest, version = "1.0.0", sources = c("src1", "src2"), direct = direct) } types <- list(foo = list(resolve = foo_resolve)) res <- withr::with_options( list(pkg.remote_types = types), synchronise(do())) expect_equal(nrow(res), 4) expect_equal(res$ref[1:2], c("foo::bar", "foo::bar2")) expect_equal(res$ref[3:4], paste0("installed::", lib, "/", c("bar", "bar2"))) expect_equal(res$status, rep("OK", 4)) expect_equal(res$package, c("bar", "bar2", "bar", "bar2")) }) test_that("explicit cran", { setup_fake_apps() conf <- current_config() cache <- list(package = pkgcache::package_cache$new(), metadata = pkgcache::get_cranlike_metadata_cache()) do <- function(refs) { res <- new_resolution(config = conf, cache = cache) res$push(.list = parse_pkg_refs(refs), direct = TRUE) res$when_complete() } res <- suppressMessages(synchronise(do("cran::dplyr"))) expect_true(inherits(res, "tbl")) expect_true("cran::dplyr" %in% res$ref) expect_true(all(grep("::", res$ref, value = TRUE) == "cran::dplyr")) expect_equal(res$type, ifelse(res$ref == "cran::dplyr", "cran", "standard")) expect_equal(res$direct, res$ref == "cran::dplyr") expect_equal(res$status, rep("OK", nrow(res))) expect_equal(res$package, sub("^.*::", "", res$ref)) expect_true(all(grepl(".", res$version, fixed = TRUE))) expect_true(all(res$platform == "source" | ! res$needscompilation)) expect_true(all(is.na(res$built) | res$platform != "source")) good_platforms <- c( default_platforms(), if (is_windows()) "i386+x86_64-w64-mingw32" ) expect_true(all(res$platform %in% good_platforms)) expect_true(all(res$rversion %in% c(get_minor_r_version(current_r_version()), "*"))) expect_true(is_character(res$repodir)) expect_true(is_character(res$target)) expect_true(all(vlapply(res$deps, inherits, what = "tbl"))) expect_true("imports" %in% unlist(lapply(res$deps, "[[", "type"))) expect_true("suggests" %in% unlist(lapply(res$deps, "[[", "type"))) expect_true(all(grepl("source|darwin", res$platform) | viapply(res$sources, length) == 1)) expect_true(all(vlapply(res$remote, inherits, what = "remote_ref"))) expect_true(all(vlapply(res$error, identical, list()))) ## TODO: metadata }) test_that("standard", { setup_fake_apps() conf <- current_config() cache <- list( package = pkgcache::package_cache$new(), metadata = pkgcache::get_cranlike_metadata_cache()) do <- function(refs) { res <- new_resolution(config = conf, cache = cache) res$push(.list = parse_pkg_refs(refs), direct = TRUE) res$when_complete() } res <- synchronise(do("dplyr")) expect_true(inherits(res, "tbl")) expect_true("dplyr" %in% res$ref) expect_true(! any(grepl("::", res$ref))) expect_equal(res$type, ifelse(res$ref == "cran::dplyr", "cran", "standard")) expect_equal(res$direct, res$ref == "dplyr") expect_equal(res$status, rep("OK", nrow(res))) expect_equal(res$package, sub("^.*::", "", res$ref)) expect_true(all(grepl(".", res$version, fixed = TRUE))) expect_true(all(res$platform == "source" | ! res$needscompilation)) expect_true(all(is.na(res$built) | res$platform != "source")) good_platforms <- c( default_platforms(), if (is_windows()) "i386+x86_64-w64-mingw32" ) expect_true(all(res$platform %in% good_platforms)) expect_true(all(res$rversion %in% c(get_minor_r_version(current_r_version()), "*"))) expect_true(is_character(res$repodir)) expect_true(is_character(res$target)) expect_true(all(vlapply(res$deps, inherits, what = "tbl"))) expect_true("imports" %in% unlist(lapply(res$deps, "[[", "type"))) expect_true("suggests" %in% unlist(lapply(res$deps, "[[", "type"))) expect_true(all(grepl("source|darwin", res$platform) | viapply(res$sources, length) == 1)) expect_true(all(vlapply(res$remote, inherits, what = "remote_ref"))) expect_true(all(vlapply(res$error, identical, list()))) ## TODO: metadata }) test_that("dependencies are honoured", { setup_fake_apps() conf <- current_config() cache <- list( package = pkgcache::package_cache$new(), metadata = pkgcache::get_cranlike_metadata_cache()) do <- function(refs, deps) { conf$set("dependencies", deps) res <- new_resolution(config = conf, cache = cache) res$push(.list = parse_pkg_refs(refs), direct = TRUE) res$when_complete() } ## FALSE means nothing res <- synchronise(do("cran::dplyr", FALSE)) expect_true(all(res$direct)) expect_true(all(res$ref == "cran::dplyr")) ## Exactly the specified ones res <- synchronise(do("cran::dplyr", "Imports")) imported <- unique(unlist( lapply(res$deps, function(x) x$package[x$type == "imports"]))) expect_true(all(res$package[!res$direct] %in% imported)) ## NA means hard ones res <- synchronise(do("cran::dplyr", NA)) hard <- c("imports", "depends", "linkingto") harddep <- unique(unlist( lapply(res$deps, function(x) x$package[x$type %in% hard]))) expect_true(all(res$package[!res$direct] %in% harddep)) ## TRUE means hard + suggests on direct, hard only on rest res <- synchronise(do("cran::dplyr", TRUE)) harddep <- unique(unlist( lapply(res$deps, function(x) x$package[x$type %in% hard]))) softdirectdep <- unique(unlist( lapply(res$deps[res$direct], function(x) x$package[x$type == "suggests"]))) indirect <- res$package[!res$direct] expect_true(all(indirect %in% harddep | indirect %in% softdirectdep)) }) test_that("error if cannot find package", { setup_fake_apps() conf <- current_config() cache <- list( package = pkgcache::package_cache$new(), metadata = pkgcache::get_cranlike_metadata_cache()) do <- function(refs) { res <- new_resolution(config = conf, cache = cache) res$push(.list = parse_pkg_refs(refs), direct = TRUE) res$when_complete() } bad <- c("cran::thiscannotexistxxx", "neitherthisonexxx") res <- suppressMessages(synchronise(do(bad))) expect_equal(res$ref, bad) expect_equal(res$type, c("cran", "standard")) expect_equal(res$direct, c(TRUE, TRUE)) expect_equal(res$status, c("FAILED", "FAILED")) }) test_that("dependency types", { setup_fake_apps() conf <- current_config() conf$set("dependencies", TRUE) cache <- list( package = pkgcache::package_cache$new(), metadata = pkgcache::get_cranlike_metadata_cache()) do <- function(refs) { res <- new_resolution(config = conf, cache = cache) res$push(.list = parse_pkg_refs(refs), direct = TRUE) res$when_complete() } res <- suppressMessages(synchronise(do("processx"))) dt <- res$dep_types expect_equal( dt[res$package == "processx"], replicate( sum(res$package == "processx"), c("Depends", "Imports", "LinkingTo", "Suggests"), simplify = FALSE ) ) expect_equal( dt[res$package != "processx"], replicate( sum(res$package != "processx"), c("Depends", "Imports", "LinkingTo"), simplify = FALSE ) ) })