diff --git a/R/getPkgZips.R b/R/getPkgZips.R index e0ebe2c..20fc1ff 100644 --- a/R/getPkgZips.R +++ b/R/getPkgZips.R @@ -127,14 +127,14 @@ getPkgZips <- function(lockfile_path = NULL, supplement = NULL, override_lock = pkg_results <- list() # initiate list to store package information (version, URL, R-version, etc.) pkg_vector <- names(pkgsVers_list$Packages) # pull vector of all packages from pkgsVers_list, overrides the previous versio used before searching for requirements - # Searching URLs and downloading ---- for (pkg in pkg_vector) { version <- pkgsVers_list$Packages[[pkg]]$Version # pull package version from pkgsVers_list + found <- FALSE # initialize as FALSE if (!(is.null(version))) { # if a version is specified, then search! for (r_rel in sort(r_rels_vect, decreasing = TRUE)) { # try newest R version first - found <- FALSE # initalize as FALSE + # found <- FALSE # initialize as FALSE! Don't declare here, leads to errors saying package is found but giving the URL and name of the last found package test_url <- paste0("https://cran.r-project.org/bin/windows/contrib/", r_rel, "/", pkg, "_", version , ".zip") if (httr::HEAD(test_url)$status_code == 200) { # status_code = 200 checks for existence of the URL @@ -168,7 +168,7 @@ getPkgZips <- function(lockfile_path = NULL, supplement = NULL, override_lock = url <- test_url if (is.null(version)) { - version <- "UNSPECIFIED" # override for print message, only used there within this statement + version <- "UNSPECIFIED" # override for print message } cli::cli_alert_warning(paste0("ALTERNATE: Found ", pkg, " v", alt_version, " under R v", backupRrel, " as an alternate to ", pkg, " v", version)) @@ -187,7 +187,10 @@ getPkgZips <- function(lockfile_path = NULL, supplement = NULL, override_lock = } if (!found) { # if the package isn't found under the alternate version of R - cli::cli_alert_danger(cat(paste0("PACKAGE NOT FOUND: Unable to find ", pkg, " v", version, " or a suitable alternate version under R v", backupRrel)), "\n") + if (is.null(version)) { + version <- "UNSPECIFIED" # override for print message + } + cli::cli_alert_danger(paste0("PACKAGE NOT FOUND: Unable to find ", pkg, " v", version, " or a suitable alternate version under R v", backupRrel), "\n") # got rid of cat() for testing pr pkg_list <- list(Package = pkg, Version = version, R_release = NULL, diff --git a/tests/testthat/test-getPkgZips.R b/tests/testthat/test-getPkgZips.R new file mode 100644 index 0000000..e4363d4 --- /dev/null +++ b/tests/testthat/test-getPkgZips.R @@ -0,0 +1,298 @@ +# Create a lockfile ---- +# Create a temporary file path +lockfile <- tempfile(pattern = "renv_", fileext = ".lock") + +# Lockfile content +lock_content <- list( + R = list( + Version = "4.6.0", + Repositories = list( # c() doesn't lead to exact structure like renv.lock when loaded in + list( + Name = "CRAN", + URL = "https://packagemanager.posit.co/cran/latest" + ) + ) + ), + Packages = list(DarwinShinyModules = list(Package = "DarwinShinyModules", + Version = "0.4.0", + Source = "GitHub", + RemoteType = "github", + RemoteHost = "api.github.com", + RemoteRepo = "DarwinShinyModules", + RemoteUsername = "darwin-eu", + RemoteSha = "2d35aae58626c94ec4bb964d0cfa20b57a4ffc4b", + Requirements = c("DT", # will it still download requirements if it doesn't find the package? -yes! + "R", + "R6", + "checkmate", + "dplyr", + "flextable", + "ggplot2", + "gt", + "plotly", + "promises", + "purrr", + "reactable", + "rlang", + "shiny", + "shinyWidgets", + "stringr"), + Hash = "7d9083247a80bb0aff94c0d5305c137d"), + DiagrammeR = list(Package = "DiagrammeR", + Version = "1.0.11", + Source = "Repository", + Repository = "CRAN", + Requirements = c("R", + "RColorBrewer", + "cli", + "dplyr", + "glue", + "htmltools", + "htmlwidgets", + "igraph", + "magrittr", + "purrr", + "readr", + "rlang", + "rstudioapi", + "scales", + "stringr", + "tibble", + "tidyr", + "viridisLite", + "visNetwork"), + Hash = "584c1e1cbb6f9b6c3b0f4ef0ad960966"), + renv = list(Package = "renv", + Version = "1.0.11", # Doesn't exist in the R releases provided in r_rels_vect, should get v1.2.2 from R v4.4 as alternate + Source = "Repository", + Repository = "CRAN", + Requirements = c("utils"), + Hash = "47623f66b4e80b3b0587bc5d7b309888"), + rlang = list(Package = "rlang", + Version = "1.2.0", + Source = "Repository", + Repository = "CRAN", + Requirements = c("R", + "utils"), + Hash = "f88151fb9ca15e72dc351deb1328716e"), + rmarkdown = list(Package = "rmarkdown", + Version = "2.31", + Source = "Repository", + Repository = "CRAN", + Requirements = c("R", + "bslib", + "evaluate", + "fontawesome", + "htmltools", + "jquerylib", + "jsonlite", + "knitr", + "methods", + "tinytex", + "tools", + "utils", + "xfun", + "yaml" + ), + Hash = "f34039d57d861d2869cbf9be813ed08e"), + rprojroot = list(Package = "rprojroot", + Version = "2.1.1", + Source = "Repository", + Repository = "CRAN", + Requirements = c("R"), + Hash = "b2453de2d29aa646afe4781defdc7903"), + rstudioapi = list(Package = "rstudioapi", + Version = "0.16.0", + Source = "Repository", + Repository = "CRAN", + Hash = "96710351d642b70e8f02ddeb237c46a7"), + sass = list(Package = "sass", + Version = "0.4.9", + Source = "Repository", + Repository = "CRAN", + Requirements = c("R6", + "fs", + "htmltools", + "rappdirs", + "rlang"), + Hash = "d53dbfddf695303ea4ad66f86e99b95d"), + scales = list(Package = "scales", + Version = "1.4.0", + Source = "Repository", + Repository = "RSPM", + Requirements = c("R", + "R6", + "RColorBrewer", + "cli", + "farver", + "glue", + "labeling", + "lifecycle", + "rlang", + "viridisLite"), + Hash = "c5bba8f0d1df8c4b9538a40570798d9b"), + xfun = list(Package = "xfun", + Version = "0.58", + Source = "Repository", + Repository = "CRAN" + ), + zip = list(Package = "zip", + Version = "2.3.3", + Source = "Repository", + Repository = "RSPM", + Hash = "6ebe4b1dc74c3e50e74e316323629583")) + ) + +# Write JSON to temporary file +jsonlite::write_json( + lock_content, + path = lockfile, + auto_unbox = TRUE, + pretty = TRUE +) + +# Path to temporary lockfile +lockfile + +# Create a supplementary file ---- +supp <- list(Packages = list(devtools = list(Package = "devtools", Version = "2.5.2"), # 2.5.2 exists in multiple releases, should pick from the newest (R v4.6) + dplyr = list(Package = "dplyr", Version = "0.6"), # there is no 0.6 in any of the releases, should get v1.2.1 as alternate from R v4.4 + tidyrr = list(Package = "tidyr", Version = "1.3.2"), # tidyrr does not exist + RPostgres = list(Package = "RPostgres", Version = NULL), # no version provided, should get v1.4.10 as alternate from R v4.4 + renv = list(Package = "renv", Version = "1.0.7"), # renv already exists in lockfile, if override_lock = TRUE, should get v1.0.7 from R v4.2 + xfun = list(Package = "xfun", Version = NULL))) # xfun already exists in lockfile, if override_lock = TRUE, should get v0.57 from R v4.4 + + +# Sanity check of counts ---- +lock <- renv::lockfile_read(lockfile) + +pkgs <- names(lock[["Packages"]]) + +supps <- names(supp[["Packages"]]) + +reqs <- unique(unlist(lapply(pkgs, function(pkg) { + lock[["Packages"]][[pkg]]$Requirements +}))) +reqs <- reqs[reqs != "R"] +# reqs_wo_overlap <- reqs[!reqs %in% intersect(c(pkgs,supps), reqs)] # reqs that don't already exist in pkgs+supps + +n_pkgs <- length(pkgs) +n_supps <- length(supps) +n_reqs <- length(reqs) +# n_reqs_wo_overlap <- length(reqs_wo_overlap) + +n_all <- length(unique(c(pkgs, supps, reqs))) + +# Test of counts ---- +test_that("Package counts", { + + expect_equal(n_pkgs, 11) + expect_equal(n_supps, 6) # 2 overlap with pkgs in lockfile, don't count unique as we have diff versions + expect_equal(n_reqs, 46) + # expect_equal(n_reqs_wo_overlap, 41) + expect_equal(n_all, 56) # not 58 bc of the supps overlap + + +}) + +# Test on getPkgZips(): creation of dir and download of zips from project specific renv.lock ---- +test_that("Package zips are actually downloaded to renv/cellar from studyGenerics renv.lock", { + msgs <- capture_messages(getPkgZips()) + + expect_true(dir.exists("renv/cellar")) # the default directory was created + + expect_true(any(grepl("Found 27 of 33 specified package\\(s)", msgs))) + expect_true(any(grepl("Identified alternate for 1 of 6 package\\(s) that were not found", msgs))) + expect_true(any(grepl("Unable to find 5 package\\(s)", msgs))) + + n_files <- length(list.files("renv/cellar")) + n_zips <- length(list.files("renv/cellar", pattern = "\\.zip$")) + + expect_equal(n_files, n_zips) # the dir should only contain zips + + expect_equal(n_zips, 28) # at the time of testing on the project renv.lock, should have 28 zips + + # print(msgs) + +}) + +# Test on lockfile only as input ---- +test_that("Message checks - lockfile only", { + + msgs <- capture_messages(pkg_summary <- getPkgZips(lockfile_path = lockfile)) + + expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find DarwinShinyModules v0.4.0 or a suitable alternate version under R v4.4", msgs))) + expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find utils vUNSPECIFIED or a suitable alternate version under R v4.4", msgs))) + expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find methods vUNSPECIFIED or a suitable alternate version under R v4.4", msgs))) + expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find tools vUNSPECIFIED or a suitable alternate version under R v4.4", msgs))) + + expect_true(any(grepl("ALTERNATE: Found renv v1.2.2 under R v4.4 as an alternate to renv v1.0.11", msgs))) + expect_true(any(grepl("Found xfun v0.58", msgs))) + expect_true(any(grepl("ALTERNATE: Found dplyr v1.2.1 under R v4.4 as an alternate to dplyr vUNSPECIFIED", msgs))) # from Requirements + + expect_true(any(grepl("Found 9 of 53 specified package\\(s)", msgs))) + expect_true(any(grepl("Identified alternate for 40 of 44 package\\(s) that were not found", msgs))) + expect_true(any(grepl("Unable to find 4 package\\(s)", msgs))) + + # print(msgs) +}) + +# Test on lockfile + supp, override_lock = FALSE ---- +test_that("Message checks - lockfile + supp, override_lock = FALSE", { + + msgs <- capture_messages(pkg_summary <- getPkgZips(lockfile_path = lockfile, supplement = supp)) + + expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find DarwinShinyModules v0.4.0 or a suitable alternate version under R v4.4", msgs))) + expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find utils vUNSPECIFIED or a suitable alternate version under R v4.4", msgs))) + expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find methods vUNSPECIFIED or a suitable alternate version under R v4.4", msgs))) + expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find tools vUNSPECIFIED or a suitable alternate version under R v4.4", msgs))) + expect_true(any(grepl("ALTERNATE: Found renv v1.2.2 under R v4.4 as an alternate to renv v1.0.11", msgs))) + expect_true(any(grepl("Found xfun v0.58", msgs))) + + + expect_true(any(grepl("Found devtools v2.5.2", msgs))) + expect_true(any(grepl("Found RPostgres v1.4.10 under R v4.4 as an alternate to RPostgres", msgs))) + expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find tidyrr v1.3.2 or a suitable alternate version under R v4.4", msgs))) + expect_true(any(grepl("Found dplyr v1.2.1 under R v4.4 as an alternate to dplyr v0.6", msgs))) # from supplement + + expect_true(any(grepl("Found 10 of 56 specified package\\(s)", msgs))) + expect_true(any(grepl("Identified alternate for 41 of 46 package\\(s) that were not found", msgs))) + expect_true(any(grepl("Unable to find 5 package\\(s)", msgs))) + + # print(msgs) + +}) + +# Test on lockfile + supp, override_lock = TRUE ---- +test_that("Message checks - lockfile + supp, override_lock = TRUE", { + + msgs <- capture_messages(pkg_summary <- getPkgZips(lockfile_path = lockfile, supplement = supp, override_lock = TRUE)) + + expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find DarwinShinyModules v0.4.0 or a suitable alternate version under R v4.4", msgs))) + expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find utils vUNSPECIFIED or a suitable alternate version under R v4.4", msgs))) + expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find methods vUNSPECIFIED or a suitable alternate version under R v4.4", msgs))) + expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find tools vUNSPECIFIED or a suitable alternate version under R v4.4", msgs))) + + # These should be TRUE if override_lock = FALSE, so we expect_false + expect_false(any(grepl("ALTERNATE: Found renv v1.2.2 under R v4.4 as an alternate to renv v1.0.11", msgs))) + expect_false(any(grepl("Found xfun v0.58", msgs))) + + # These should be TRUE if override_lock = TRUE + expect_true(any(grepl("Found renv v1.0.7", msgs))) + expect_true(any(grepl("ALTERNATE: Found xfun v0.57 under R v4.4 as an alternate to xfun vUNSPECIFIED", msgs))) + + expect_true(any(grepl("Found devtools v2.5.2", msgs))) + expect_true(any(grepl("Found RPostgres v1.4.10 under R v4.4 as an alternate to RPostgres", msgs))) + expect_true(any(grepl("PACKAGE NOT FOUND: Unable to find tidyrr v1.3.2 or a suitable alternate version under R v4.4", msgs))) + expect_true(any(grepl("Found dplyr v1.2.1 under R v4.4 as an alternate to dplyr v0.6", msgs))) # from supplement + + expect_true(any(grepl("Found 10 of 56 specified package\\(s)", msgs))) + expect_true(any(grepl("Identified alternate for 41 of 46 package\\(s) that were not found", msgs))) + expect_true(any(grepl("Unable to find 5 package\\(s)", msgs))) + + # print(msgs) + +}) + + +