test_that( "running assess_pkg for test package in tar file - no notes", { skip_on_cran() skip_if( .Platform$OS.type == "windows", "covr runs in a subprocess on Windows; mocking is not reliable under devtools::test()" ) # ---- repo setup ---- r <- getOption("repos") r["CRAN"] <- "http://cran.us.r-project.org" options(repos = r) # ---- copy test tarball ---- dp_orig <- system.file( "test-data", "test.package.0001_0.1.0.tar.gz", package = "risk.assessr" ) dp <- tempfile(fileext = ".tar.gz") file.copy(dp_orig, dp) withr::defer(unlink(dp), envir = parent.frame()) # ---- covr mocks --------------------------------------------------- mock_covr_coverage <- function(path, type = "tests", ...) { line_cov <- data.frame( filename = c( "R/myfunction.R", "tests/testthat/test-myfunction.R" ), line = c(1L, 1L), value = c(1L, 1L), stringsAsFactors = FALSE ) cov <- list( package = "test.package.0001", line_coverage = line_cov ) class(cov) <- "coverage" cov } # stub *before* assess_pkg() runs mockery::stub( assess_pkg, "covr::package_coverage", mock_covr_coverage ) mockery::stub( assess_pkg, "covr::report", function(...) invisible(NULL) ) mockery::stub( assess_pkg, "covr::percent_coverage", function(x) 1 ) # ---- other external mocks ---------------------------------------- # 1) Return a fully-populated covr_list from run_coverage() mock_run_coverage <- function(pkg_source_path, covr_timeout) { list( total_cov = 1.0, # non-NA to bypass skip STF res_cov = list( name = "test.package.0001", coverage = list( filecoverage = c(100), # non-NA totalcoverage = 100 ) ) ) } # 2) Stub run_coverage at the call-site inside run_covr_modes() mockery::stub( risk.assessr::run_covr_modes, "run_coverage", mock_run_coverage ) # 3) Ensure the "has_testthat" condition is TRUE mockery::stub( assess_pkg, "check_pkg_tests_and_snaps", function(pkg_source_path) { list( has_testthat = TRUE, has_testit = FALSE, has_snaps = TRUE, n_golden_tests = 100, n_test_files = 100 ) } ) mock_get_host_package <- function(pkg_name, pkg_ver, pkg_source_path) { list( cran_links = "CRAN", github_links = NULL, bioconductor_links = NULL, internal_links = NULL ) } mockery::stub( assess_pkg, "get_host_package", mock_get_host_package ) mock_check_pkg_tests <- function(pkg_source_path) { list( has_testthat = TRUE, has_snaps = TRUE, n_golden_tests = 100, n_test_files = 100 ) } mockery::stub( assess_pkg, "check_pkg_tests_and_snaps", mock_check_pkg_tests ) mock_check_and_fetch_cran_package <- function(pkg_name, pkg_ver) { list( all_versions = list( list(version = "0.1.0", date = "2021-01-01"), list(version = "0.9.0", date = "2022-01-01"), list(version = "1.0.0", date = "2023-01-01") ), last_version = list( version = "1.0.0", date = "2023-01-01" ) ) } mockery::stub( assess_pkg, "check_and_fetch_cran_package", mock_check_and_fetch_cran_package ) mockery::stub( assess_pkg, "get_risk_analysis", function(pkg_name) list() ) # ---- package setup ------------------------------------------------ install_list <- set_up_pkg(dp) pkg_source_path <- install_list$pkg_source_path rcmdcheck_args <- install_list$rcmdcheck_args # --- after set_up_pkg(dp) --- # Discover package name from DESCRIPTION without extra dependencies pkg_name <- unname(read.dcf(file.path(pkg_source_path, "DESCRIPTION"), "Package")[1, 1]) # Load the package *from source* so base::getNamespaceExports(pkg_name) works pkgload::load_all( pkg_source_path, quiet = TRUE, export_all = FALSE, # don't attach non-exports helpers = FALSE, attach_testthat = FALSE ) # Make sure we unload even on test failure withr::defer( try(pkgload::unload(pkg_name), silent = TRUE), envir = parent.frame() ) withr::defer( unlink(pkg_source_path, recursive = TRUE, force = TRUE), envir = parent.frame() ) # pretend install succeeded rcmdcheck_args$path <- pkg_source_path # ---- run assess_pkg ----------------------------------------------- assess_package <- assess_pkg(pkg_source_path, rcmdcheck_args) # ---- assertions --------------------------------------------------- expect_identical(length(assess_package), 5L) expect_true(checkmate::check_class(assess_package, "list")) expect_identical(length(assess_package$results), 32L) expect_true(!is.na(assess_package$results$pkg_name)) expect_true(!is.na(assess_package$results$pkg_version)) expect_true(!is.na(assess_package$results$pkg_source_path)) expect_true(!is.na(assess_package$results$date_time)) expect_true(checkmate::test_numeric(assess_package$results$covr)) expect_gte(assess_package$results$covr, 0.7) # ---- covr list ---------------------------------------------------- expect_identical(length(assess_package$covr_list), 2L) expect_identical( length(assess_package$covr_list$res_cov$coverage), 2L ) # ---- TM coverage -------------------------------------------------- expect_identical(length(assess_package$tm_list$tm), 9L) # high risk expect_true(is.list(assess_package$tm_list$coverage$high_risk)) expect_identical( assess_package$tm_list$coverage$high_risk$pkg_name, "test.package.0001" ) # medium risk expect_true(is.list(assess_package$tm_list$coverage$medium_risk)) # low risk low_risk <- assess_package$tm_list$coverage$low_risk expect_equal(nrow(low_risk), 1L) expect_identical(low_risk$exported_function[1], "myfunction") expect_true(grepl("^R/", low_risk$code_script[1])) expect_equal(low_risk$coverage_percent[1], 100) # ---- check data --------------------------------------------------- expect_identical(length(assess_package$check_list), 2L) expect_identical( length(assess_package$check_list$res_check), 21L ) # ---- version delta ----------------------------------------------- diff_months <- assess_package$results$version_info$difference_version_months expect_equal(diff_months, 24) }) Sys.setenv("R_TESTS" = "") library(testthat) test_that("running assess_pkg for test package in tar file - no exports", { skip_on_cran() r = getOption("repos") r["CRAN"] = "http://cran.us.r-project.org" options(repos = r) # Copy test package to a temp file dp_orig <- system.file("test-data", "test.package.0005_0.1.0.tar.gz", package = "risk.assessr") dp <- tempfile(fileext = ".tar.gz") file.copy(dp_orig, dp) # Defer cleanup of copied tarball withr::defer(unlink(dp), envir = parent.frame()) # Defer cleanup of unpacked source directory withr::defer(unlink(pkg_source_path, recursive = TRUE, force = TRUE), envir = parent.frame()) mock_get_host_package <- function(pkg_name, pkg_ver, pkg_source_path) { return(list(cran_links = "CRAN", github_links = NULL, bioconductor_links = NULL, internal_links= NULL)) } mockery::stub(assess_pkg, "get_host_package", mock_get_host_package) mock_unit_test <- function(pkg_source_path) { return(list( has_testthat = TRUE, has_snaps = TRUE, n_golden_tests = 100, n_test_files = 100 )) } mockery::stub(assess_pkg, "check_pkg_tests_and_snaps", mock_unit_test) mock_check_and_fetch_cran_package <- function(pkg_name, pkg_ver) { return(list( all_versions = list( list(version = "0.1.0", date = "2023-01-01"), # actual package version list(version = "0.9.0", date = "2022-01-01"), list(version = "1.0.0", date = "2023-01-01") ), last_version = list(version = "1.0.0", date = "2023-01-01") )) } mockery::stub(assess_pkg, "check_and_fetch_cran_package", mock_check_and_fetch_cran_package) mock_get_risk_analysis <- function(pkg_name) { return(list()) } mockery::stub(assess_pkg, "get_risk_analysis", mock_get_risk_analysis) # set up package install_list <- set_up_pkg(dp) build_vignettes <- install_list$build_vignettes package_installed <- install_list$package_installed pkg_source_path <- install_list$pkg_source_path rcmdcheck_args <- install_list$rcmdcheck_args # install package locally to ensure test works package_installed <- install_package_local(pkg_source_path) package_installed <- TRUE if (package_installed == TRUE ) { # ensure path is set to package source path rcmdcheck_args$path <- pkg_source_path assess_package <- assess_pkg(pkg_source_path, rcmdcheck_args) testthat::expect_identical(length(assess_package), 5L) testthat::expect_true(checkmate::check_class(assess_package, "list")) testthat::expect_identical(length(assess_package$results), 32L) testthat::expect_true(!is.na(assess_package$results$pkg_name)) testthat::expect_true(!is.na(assess_package$results$pkg_version)) testthat::expect_true(!is.na(assess_package$results$pkg_source_path)) testthat::expect_true(!is.na(assess_package$results$date_time)) testthat::expect_true(!is.na(assess_package$results$executor)) testthat::expect_true(!is.na(assess_package$results$sysname)) testthat::expect_true(!is.na(assess_package$results$version)) testthat::expect_true(!is.na(assess_package$results$release)) testthat::expect_true(!is.na(assess_package$results$machine)) testthat::expect_true(!is.na(assess_package$results$comments)) testthat::expect_null(assess_package$results$has_bug_reports_url) testthat::expect_true(!is.na(assess_package$results$suggested_deps$source)) testthat::expect_true(identical(assess_package$results$suggested_deps$message, "No exported functions from Suggested packages in the DESCRIPTION file")) testthat::expect_true(!is.na(assess_package$results$license)) testthat::expect_true(!is.na(assess_package$results$size_codebase)) testthat::expect_true(checkmate::test_numeric(assess_package$results$size_codebase)) testthat::expect_true(checkmate::test_numeric(assess_package$results$check)) testthat::expect_gte(assess_package$results$check, 0) testthat::expect_true(checkmate::test_numeric(assess_package$results$covr)) testthat::expect_gte(assess_package$results$covr, 0) testthat::expect_identical(length(assess_package$covr_list), 2L) testthat::expect_true(!is.na(assess_package$covr_list$res_cov$name)) testthat::expect_identical(length(assess_package$covr_list$res_cov$coverage), 2L) testthat::expect_identical(length(assess_package$tm_list), 4L) testthat::expect_identical(length(assess_package$tm_list$tm), 0L) expect_identical(assess_package$tm_list$coverage$filecoverage, 0) expect_identical(assess_package$tm_list$coverage$totalcoverage, 0) testthat::expect_identical(length(assess_package$check_list), 2L) testthat::expect_identical(length(assess_package$check_list$res_check), 21L) testthat::expect_true(!is.na(assess_package$check_list$res_check$platform)) testthat::expect_true(!is.na(assess_package$check_list$res_check$package)) testthat::expect_identical(length(assess_package$check_list$res_check$test_output), 0L) testthat::expect_true(is.null(assess_package$check_list$res_check$test_output$testthat)) testthat::expect_true(all(sapply(assess_package$check_list$res_check$session_info$platform, function(x) !is.null(x) && x != ""))) diff_months <- assess_package$results$version_info$difference_version_months expect_equal(diff_months, 0) } }) test_that("running assess_pkg for test package with Config/build/clean-inst-doc: false", { skip_on_cran() mock_get_host_package <- function(pkg_name, pkg_ver, pkg_source_path) { return(list(cran_links = "CRAN", github_links = NULL, bioconductor_links = NULL, internal_links= NULL)) } mockery::stub(assess_pkg, "get_host_package", mock_get_host_package) mock_unit_test <- function(pkg_source_path) { return(list( has_testthat = TRUE, has_snaps = TRUE, n_golden_tests = 100, n_test_files = 100 )) } mockery::stub(assess_pkg, "check_pkg_tests_and_snaps", mock_unit_test) mock_check_and_fetch_cran_package <- function(pkg_name, pkg_ver) { return(list( all_versions = list( list(version = "0.1.0", date = "2023-01-01"), # actual package version list(version = "0.9.0", date = "2022-01-01"), list(version = "1.0.0", date = "2023-01-01") ), last_version = list(version = "1.0.0", date = "2023-01-01") )) } mockery::stub(assess_pkg, "check_and_fetch_cran_package", mock_check_and_fetch_cran_package) mock_get_risk_analysis <- function(pkg_name) { return(list()) } mockery::stub(assess_pkg, "get_risk_analysis", mock_get_risk_analysis) dp <- system.file("test-data", "test.package.0005_0.1.0.tar.gz", package = "risk.assessr") # Check if the file exists before attempting to download if (!file.exists(dp)) { stop("The tar file does not exist at the specified path.") } # Create a temporary file to store the downloaded package file_name <- basename(dp) # Use the base name for temporary file temp_file <- file.path(tempdir(), file_name) # Copy the file to the temporary file instead of downloading it file.copy(dp, temp_file, overwrite = TRUE) # Verify that the copy was successful if (!file.exists(temp_file)) { stop("File copy failed: temporary file not found.") } # Run the function to modify the DESCRIPTION file modified_tar_file <- modify_description_file(temp_file) # Set up package install_list <- set_up_pkg(dp) build_vignettes <- install_list$build_vignettes package_installed <- install_list$package_installed pkg_source_path <- install_list$pkg_source_path rcmdcheck_args <- install_list$rcmdcheck_args if (package_installed == TRUE) { assess_package <- assess_pkg(pkg_source_path, rcmdcheck_args) testthat::expect_true(checkmate::check_class(assess_package, "list")) } }) test_that("running assess_pkg for test package fail suggest", { skip_on_cran() # Robust, version-independent Windows skip (covr subprocess + devtools::test) skip_if( .Platform$OS.type == "windows", "covr runs in a subprocess on Windows; mocking is not reliable under devtools::test()." ) # ---- repo setup ---- r <- getOption("repos") r["CRAN"] <- "http://cran.us.r-project.org" options(repos = r) # ---- copy test tarball ---- dp_orig <- system.file( "test-data", "test.package.0001_0.1.0.tar.gz", package = "risk.assessr" ) dp <- tempfile(fileext = ".tar.gz") file.copy(dp_orig, dp) withr::defer(unlink(dp), envir = parent.frame()) # ---- covr path control: force STF and prevent fallback ---- # 1) Mock run_coverage() at its call site inside run_covr_modes() mock_run_coverage <- function(pkg_source_path, covr_timeout) { list( total_cov = 1.0, # MUST be non-NA to prevent fallback res_cov = list( name = "test.package.0001", coverage = list( filecoverage = c(100), # MUST be non-NA to prevent fallback totalcoverage = 100 ) ) ) } mockery::stub( risk.assessr::run_covr_modes, "run_coverage", mock_run_coverage ) # 2) Optional tripwires: if any direct covr path is still hit, fail fast tripwire <- function(...) stop("covr must not be called in this unit test", call. = FALSE) if (exists("create_covr_list_no_skip", envir = asNamespace("risk.assessr"), inherits = FALSE)) { mockery::stub(risk.assessr:::create_covr_list_no_skip, "covr::package_coverage", tripwire) } if (exists("run_covr_skip_stf", envir = asNamespace("risk.assessr"), inherits = FALSE)) { mockery::stub(risk.assessr::run_covr_skip_stf, "covr::package_coverage", tripwire) } if (exists("run_covr_skip_nstf", envir = asNamespace("risk.assessr"), inherits = FALSE)) { mockery::stub(risk.assessr::run_covr_skip_nstf, "covr::package_coverage", tripwire) } # ---- other external mocks ---- mockery::stub( assess_pkg, "get_host_package", function(pkg_name, pkg_ver, pkg_source_path) { list(cran_links = "CRAN", github_links = NULL, bioconductor_links = NULL, internal_links = NULL) } ) # Ensure STF branch is selected mockery::stub( assess_pkg, "check_pkg_tests_and_snaps", function(pkg_source_path) { list( has_testthat = TRUE, has_testit = FALSE, has_snaps = TRUE, n_golden_tests = 100, n_test_files = 100 ) } ) mockery::stub( assess_pkg, "check_and_fetch_cran_package", function(pkg_name, pkg_ver) { list( all_versions = list( list(version = "0.1.0", date = "2023-01-01"), # actual package version list(version = "0.9.0", date = "2022-01-01"), list(version = "1.0.0", date = "2023-01-01") ), last_version = list(version = "1.0.0", date = "2023-01-01") ) } ) mockery::stub( assess_pkg, "get_risk_analysis", function(pkg_name) list() ) # stub inside assess_pkg() because that's where the call appears in the function body. mockery::stub( assess_pkg, "check_suggested_exp_funcs", function(...) stop("forced failure") ) # ---- package setup ---- install_list <- set_up_pkg(dp) pkg_source_path <- install_list$pkg_source_path rcmdcheck_args <- install_list$rcmdcheck_args withr::defer(unlink(pkg_source_path, recursive = TRUE, force = TRUE), envir = parent.frame()) # Install locally if your pipeline needs it (you had this) package_installed <- install_package_local(pkg_source_path) package_installed <- TRUE if (isTRUE(package_installed)) { rcmdcheck_args$path <- pkg_source_path assess_package <- assess_pkg(pkg_source_path, rcmdcheck_args) suggested_deps <- assess_package$results$suggested_deps } testthat::expect_identical(length(suggested_deps), 4L) expected <- c("source", "suggested_function", "message", "where") # Same number of columns testthat::expect_identical(ncol(suggested_deps), length(expected)) expect_identical(suggested_deps$source, "test.package.0001" ) expect_identical(suggested_deps$message, "Error in checking suggested functions" ) }) test_that("assess_pkg handles errors in check_suggested_exp_funcs correctly", { skip_on_cran() # Robust Windows skip: covr runs in a subprocess on Windows and mocks won't cross it reliably skip_if( .Platform$OS.type == "windows", "covr runs in a subprocess on Windows; mocking is not reliable under devtools::test()." ) # ---- CRAN repo setup (if your helpers install deps) ---- r <- getOption("repos") r["CRAN"] <- "http://cran.us.r-project.org" options(repos = r) # ---- copy test tarball ---- dp_orig <- system.file( "test-data", "test.package.0001_0.1.0.tar.gz", package = "risk.assessr" ) dp <- tempfile(fileext = ".tar.gz") file.copy(dp_orig, dp) withr::defer(unlink(dp), envir = parent.frame()) # We'll collect pkg_source_path for cleanup once set_up_pkg() runs # (we declare it here only so the defer below has a symbol) pkg_source_path <- NULL withr::defer( if (!is.null(pkg_source_path)) unlink(pkg_source_path, recursive = TRUE, force = TRUE), envir = parent.frame() ) # ---- Force STF path and prevent any fallback to skip-STF ---- # run_covr_modes() calls run_coverage(pkg_source_path, covr_timeout) # Return non-NA values to ensure the fallback condition is FALSE. mock_run_coverage <- function(pkg_source_path, covr_timeout) { list( total_cov = 1.0, # non-NA to bypass fallback res_cov = list( name = "test.package.0001", coverage = list( filecoverage = c(100), # non-NA to bypass fallback totalcoverage = 100 ) ) ) } mockery::stub( risk.assessr::run_covr_modes, "run_coverage", mock_run_coverage ) # Tripwires: if any direct covr call is still reached, fail fast tripwire <- function(...) stop("covr must not be called in this unit test", call. = FALSE) if (exists("create_covr_list_no_skip", envir = asNamespace("risk.assessr"), inherits = FALSE)) { mockery::stub(risk.assessr:::create_covr_list_no_skip, "covr::package_coverage", tripwire) } if (exists("run_covr_skip_stf", envir = asNamespace("risk.assessr"), inherits = FALSE)) { mockery::stub(risk.assessr::run_covr_skip_stf, "covr::package_coverage", tripwire) } if (exists("run_covr_skip_nstf", envir = asNamespace("risk.assessr"), inherits = FALSE)) { mockery::stub(risk.assessr::run_covr_skip_nstf, "covr::package_coverage", tripwire) } # ---- Other external mocks used by assess_pkg() ---- mockery::stub( assess_pkg, "get_host_package", function(pkg_name, pkg_ver, pkg_source_path) { list(cran_links = "CRAN", github_links = NULL, bioconductor_links = NULL, internal_links = NULL) } ) # Ensure STF branch is picked mockery::stub( assess_pkg, "check_pkg_tests_and_snaps", function(pkg_source_path) { list( has_testthat = TRUE, has_testit = FALSE, has_snaps = TRUE, n_golden_tests = 100, n_test_files = 100 ) } ) mockery::stub( assess_pkg, "check_and_fetch_cran_package", function(pkg_name, pkg_ver) { list( all_versions = list( list(version = "0.1.0", date = "2023-01-01"), # actual package version list(version = "0.9.0", date = "2022-01-01"), list(version = "1.0.0", date = "2023-01-01") ), last_version = list(version = "1.0.0", date = "2023-01-01") ) } ) mockery::stub( assess_pkg, "get_risk_analysis", function(pkg_name) list() ) # ---- Key fix: stub the *caller* of check_suggested_exp_funcs, i.e., inside assess_pkg() ---- mockery::stub( assess_pkg, "check_suggested_exp_funcs", function(...) stop("Mock error") # your test is specifically about error handling ) # ---- Prepare the test package ---- install_list <- set_up_pkg(dp) pkg_source_path <- install_list$pkg_source_path rcmdcheck_args <- install_list$rcmdcheck_args # Discover package name from DESCRIPTION without extra dependencies pkg_name <- unname(read.dcf(file.path(pkg_source_path, "DESCRIPTION"), "Package")[1, 1]) # Load the package *from source* so base::getNamespaceExports(pkg_name) works pkgload::load_all( pkg_source_path, quiet = TRUE, export_all = FALSE, # don't attach non-exports helpers = FALSE, attach_testthat = FALSE ) # Make sure we unload even on test failure withr::defer( try(pkgload::unload(pkg_name), silent = TRUE), envir = parent.frame() ) # If your pipeline actually needs an install (some helper may assume it), keep it package_installed <- install_package_local(pkg_source_path) if (isTRUE(package_installed)) { rcmdcheck_args$path <- pkg_source_path # ---- Execute ---- assess_package <- assess_pkg(pkg_source_path, rcmdcheck_args) # ---- Assertions ---- expect_true("suggested_deps" %in% names(assess_package$results)) suggested_deps <- assess_package$results$suggested_deps expect_equal(nrow(suggested_deps), 1) expect_equal(suggested_deps$source, "test.package.0001") expect_equal(suggested_deps$suggested_function, 0) # If your intended behavior on error is to fall back to the “no exported functions…” row: expect_equal( suggested_deps$message, "Error in checking suggested functions" ) # The covr value should be 1 based on our mock_run_coverage() expect_true("covr" %in% names(assess_package$results)) expect_equal(assess_package$results$covr, 1) } else { skip("Local install of test package failed (install_package_local returned FALSE).") } }) test_that("assess_pkg handles error in check_suggested_exp_funcs via withCallingHandlers", { # Create a real temporary directory and DESCRIPTION file pkg_source_path <- withr::local_tempdir() desc_path <- file.path(pkg_source_path, "DESCRIPTION") writeLines(c( "Package: mockpkg", "Version: 0.1.0", "Title: Mock Package", "Description: A mock package for testing.", "Authors@R: c(person(given = \"Mock\", family = \"Author\", role = c(\"aut\", \"cre\")))" ), desc_path) # Stub get_pkg_desc to return mock name/version mockery::stub(assess_pkg, "get_pkg_desc", function(path, fields) { list(Package = "mockpkg", Version = "0.1.0") }) # Stub all other required functions to return minimal valid data mockery::stub(assess_pkg, "get_risk_metadata", function() list()) mockery::stub(assess_pkg, "create_empty_results", function(...) list(suggested_deps = NULL)) mockery::stub(assess_pkg, "doc_riskmetric", function(...) list( has_bug_reports_url = TRUE, license = TRUE, has_examples = TRUE, has_maintainer = TRUE, size_codebase = 10, has_news = TRUE, has_source_control = TRUE, has_vignettes = TRUE, has_website = TRUE, news_current = TRUE, export_help = TRUE )) mockery::stub(assess_pkg, "check_pkg_tests_and_snaps", function(...) list(has_testthat = FALSE, has_testit = FALSE)) mockery::stub(assess_pkg, "run_rcmdcheck", function(...) list(check_score = 1)) mockery::stub(assess_pkg, "get_dependencies", function(...) list()) mockery::stub(assess_pkg, "create_empty_tm", function(...) list()) # Stub check_suggested_exp_funcs to throw an error caught by withCallingHandlers mockery::stub(assess_pkg, "check_suggested_exp_funcs", function(...) stop("Simulated error in inner handler")) rcmdcheck_args <- list(timeout = Inf, args = c("--no-manual"), build_args = NULL, env = "mockenv", quiet = TRUE) expect_message( assess_pkg(pkg_source_path, rcmdcheck_args), "No recognised standard or non-standard testing configuration" ) }) test_that("assess_pkg handles error via outer tryCatch block", { # Create a real temporary directory and DESCRIPTION file pkg_source_path <- withr::local_tempdir() desc_path <- file.path(pkg_source_path, "DESCRIPTION") writeLines(c( "Package: mockpkg", "Version: 0.1.0", "Title: Mock Package", "Description: A mock package for testing.", "Authors@R: c(person(given = \"Mock\", family = \"Author\", role = c(\"aut\", \"cre\")))" ), desc_path) # Stub get_pkg_desc to return mock name/version mockery::stub(assess_pkg, "get_pkg_desc", function(path, fields) { list(Package = "mockpkg", Version = "0.1.0") }) # Stub all other required functions to return minimal valid data mockery::stub(assess_pkg, "get_risk_metadata", function() list()) mockery::stub(assess_pkg, "create_empty_results", function(...) list(suggested_deps = NULL)) mockery::stub(assess_pkg, "doc_riskmetric", function(...) list( has_bug_reports_url = TRUE, license = TRUE, has_examples = TRUE, has_maintainer = TRUE, size_codebase = 10, has_news = TRUE, has_source_control = TRUE, has_vignettes = TRUE, has_website = TRUE, news_current = TRUE, export_help = TRUE )) mockery::stub(assess_pkg, "check_pkg_tests_and_snaps", function(...) list(has_testthat = FALSE, has_testit = FALSE)) mockery::stub(assess_pkg, "run_rcmdcheck", function(...) list(check_score = 1)) mockery::stub(assess_pkg, "get_dependencies", function(...) list()) mockery::stub(assess_pkg, "create_empty_tm", function(...) list()) # Stub withCallingHandlers to simulate an error that bypasses inner handler mockery::stub( assess_pkg, "check_suggested_exp_funcs", function(...) stop("Mock error") ) rcmdcheck_args <- list(timeout = Inf, args = c("--no-manual"), build_args = NULL, env = "mockenv", quiet = TRUE) expect_message( assess_pkg(pkg_source_path, rcmdcheck_args), "An error occurred in checking suggested functions: Mock error" ) }) test_that("assess_pkg follows Bioconductor path and records version/revdeps", { skip_on_cran() # Create a minimal real pkg structure pkg_source_path <- withr::local_tempdir() writeLines(c( "Package: mockbio", "Version: 1.0.0", # matches an entry below → difference months = 0 "Title: Mock BioPkg", "Description: A mock package.", "Authors@R: person('A','B',role=c('aut','cre'))", "License: MIT" ), file.path(pkg_source_path, "DESCRIPTION")) dir.create(file.path(pkg_source_path, "R"), showWarnings = FALSE) writeLines("", file.path(pkg_source_path, "NAMESPACE")) # Minimal rcmdcheck args rcmdcheck_args <- list(timeout = Inf, args = c("--no-manual"), build_args = NULL, env = "mockenv", quiet = TRUE) # --- Stubs to force the Bioconductor branch and keep runtime tiny --- mockery::stub(assess_pkg, "get_risk_metadata", function() list()) mockery::stub(assess_pkg, "create_empty_results", function(...) { list( pkg_name = "mockbio", pkg_version = "1.0.0", pkg_source_path = pkg_source_path, date_time = Sys.time(), executor = "test", sysname = "Windows", version = "R", release = "0", machine = "x86", comments = "", suggested_deps = NULL ) }) mockery::stub(assess_pkg, "doc_riskmetric", function(...) list( has_bug_reports_url = TRUE, license = "MIT", has_examples = TRUE, has_maintainer = TRUE, size_codebase = 10, has_news = TRUE, has_source_control = TRUE, has_vignettes = TRUE, has_website = TRUE, news_current = TRUE, export_help = TRUE )) mockery::stub(assess_pkg, "check_pkg_tests_and_snaps", function(...) list(has_testthat = FALSE, has_testit = FALSE)) mockery::stub(assess_pkg, "run_rcmdcheck", function(...) list(check_score = 1)) mockery::stub(assess_pkg, "get_dependencies", function(...) list()) mockery::stub(assess_pkg, "create_empty_tm", function(...) list()) mockery::stub(assess_pkg, "get_pkg_author", function(...) list(maintainer = "A B", funder = NA, authors = "A B")) mockery::stub(assess_pkg, "extract_license_from_description", function(...) "MIT") mockery::stub(assess_pkg, "get_host_package", function(pkg, ver, path) { list(cran_links = NULL, github_links = NULL, bioconductor_links = "bioc", internal_links = NULL) }) mockery::stub(assess_pkg, "get_repo_owner", function(...) "owner") mockery::stub(assess_pkg, "get_github_data", function(...) list(created_at = NA, stars = 0, forks = 0, date = NA, recent_commits_count = 0)) mockery::stub(assess_pkg, "get_cran_total_downloads", function(...) 0) # Bioconductor-specific stubs mockery::stub(assess_pkg, "fetch_bioconductor_releases", function() "") mockery::stub(assess_pkg, "parse_bioconductor_releases", function(html) list()) # not used by our next stub mockery::stub(assess_pkg, "get_bioconductor_package_url", function(pkg, ver, rel) { list( all_versions = list( list(version = "0.9.0", date = "2022-01-01"), list(version = "1.0.0", date = "2023-01-01") ), last_version = list(version = "1.0.0", date = "2023-01-01"), bioconductor_version_package = "3.17" ) }) mockery::stub(assess_pkg, "bioconductor_reverse_deps", function(pkg, version) c("pkgA", "pkgB")) mockery::stub(assess_pkg, "risk.assessr::get_session_dependencies", function(...) list()) mockery::stub(assess_pkg, "get_risk_analysis", function(...) list()) res <- assess_pkg(pkg_source_path, rcmdcheck_args) expect_true(is.list(res)) expect_true("results" %in% names(res)) expect_true("version_info" %in% names(res$results)) expect_equal(res$results$version_info$bioconductor_version_package, "3.17") expect_equal(res$results$version_info$last_version$version, "1.0.0") # Version in DESCRIPTION == "1.0.0" → index matches → difference months 0 expect_equal(res$results$version_info$difference_version_months, 0) # Revdeps populated from Bioconductor path: expect_equal(res$results$rev_deps, c("pkgA", "pkgB")) }) test_that("assess_pkg Bioconductor path coerces empty reverse deps to 0", { skip_on_cran() pkg_source_path <- withr::local_tempdir() writeLines(c( "Package: mockbioempty", "Version: 1.0.0", "Title: Mock BioPkg Empty", "Description: A mock package.", "Authors@R: person('A','B',role=c('aut','cre'))", "License: MIT" ), file.path(pkg_source_path, "DESCRIPTION")) dir.create(file.path(pkg_source_path, "R"), showWarnings = FALSE) writeLines("", file.path(pkg_source_path, "NAMESPACE")) rcmdcheck_args <- list(timeout = Inf, args = c("--no-manual"), build_args = NULL, env = "mockenv", quiet = TRUE) mockery::stub(assess_pkg, "get_risk_metadata", function() list()) mockery::stub(assess_pkg, "create_empty_results", function(...) list(suggested_deps = NULL)) mockery::stub(assess_pkg, "doc_riskmetric", function(...) list( has_bug_reports_url = TRUE, license = "MIT", has_examples = TRUE, has_maintainer = TRUE, size_codebase = 10, has_news = TRUE, has_source_control = TRUE, has_vignettes = TRUE, has_website = TRUE, news_current = TRUE, export_help = TRUE )) mockery::stub(assess_pkg, "check_pkg_tests_and_snaps", function(...) list(has_testthat = FALSE, has_testit = FALSE)) mockery::stub(assess_pkg, "run_rcmdcheck", function(...) list(check_score = 1)) mockery::stub(assess_pkg, "get_dependencies", function(...) list()) mockery::stub(assess_pkg, "create_empty_tm", function(...) list()) mockery::stub(assess_pkg, "get_host_package", function(pkg, ver, path) { list(cran_links = NULL, github_links = NULL, bioconductor_links = "bioc", internal_links = NULL) }) mockery::stub(assess_pkg, "fetch_bioconductor_releases", function() "") mockery::stub(assess_pkg, "parse_bioconductor_releases", function(html) list()) mockery::stub(assess_pkg, "get_bioconductor_package_url", function(pkg, ver, rel) { list( all_versions = list( list(version = "1.0.0", date = "2023-01-01") ), last_version = list(version = "1.0.0", date = "2023-01-01"), bioconductor_version_package = "3.18" ) }) # Return empty to trigger the post-processing fallback to 0 mockery::stub(assess_pkg, "bioconductor_reverse_deps", function(pkg, version) character(0)) mockery::stub(assess_pkg, "risk.assessr::get_session_dependencies", function(...) list()) mockery::stub(assess_pkg, "get_risk_analysis", function(...) list()) res <- assess_pkg(pkg_source_path, rcmdcheck_args) expect_true(is.list(res)) expect_true("results" %in% names(res)) expect_equal(res$results$version_info$bioconductor_version_package, "3.18") expect_equal(res$results$version_info$difference_version_months, 0) # Empty reverse deps must be coerced to numeric 0 expect_identical(res$results$rev_deps, 0) })