mirror of
https://github.com/msberends/AMR.git
synced 2026-11-16 00:10:57 +01:00
(v3.0.1.9114) Fix errors without cli and on R 3.0, and make the tinytest pipeline actually run the unit tests
Package: - stop_() called cli::ansi_has_hyperlink_support() before checking that cli is available, so without cli every error became "there is no package called 'cli'" - interpretive_rules() failed on R 3.0 for guidelines without AmpC rules (assignment to zero rows) - Guard the ggplot2 example of wisca_plot() CI: - check-old: R 3.0 could not install tinytest over HTTPS, so no unit tests ran; install it with curl, and fail when tinytest is missing or any test fails - tinytest shim: record expectations in the test file environment, support skips and errors per test_that() block, add missing testthat equivalents, source helper files - Add R 4.0 (oldrel-6) to check-old, and oldrel-5 to check-recent
This commit is contained in:
1 parent
f0699c6584
commit
9e609dae83
13 files changed
+68
-32
No files matched your search
@@ -53,7 +53,7 @@ jobs:
|
||||
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
||||
echo 'matrix={"config":[{"os":"ubuntu-latest","r":"release","allowfail":false}]}' >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo 'matrix={"config":[{"os":"windows-latest","r":"devel","allowfail":false},{"os":"ubuntu-latest","r":"devel","allowfail":false,"http-user-agent":"release"},{"os":"macOS-latest","r":"release","allowfail":true},{"os":"windows-latest","r":"release","allowfail":false},{"os":"ubuntu-latest","r":"release","allowfail":false},{"os":"ubuntu-latest","r":"oldrel-1","allowfail":false},{"os":"ubuntu-latest","r":"oldrel-2","allowfail":false},{"os":"ubuntu-latest","r":"oldrel-3","allowfail":false},{"os":"ubuntu-latest","r":"oldrel-4","allowfail":false}]}' >> "$GITHUB_OUTPUT"
|
||||
echo 'matrix={"config":[{"os":"windows-latest","r":"devel","allowfail":false},{"os":"ubuntu-latest","r":"devel","allowfail":false,"http-user-agent":"release"},{"os":"macOS-latest","r":"release","allowfail":true},{"os":"windows-latest","r":"release","allowfail":false},{"os":"ubuntu-latest","r":"release","allowfail":false},{"os":"ubuntu-latest","r":"oldrel-1","allowfail":false},{"os":"ubuntu-latest","r":"oldrel-2","allowfail":false},{"os":"ubuntu-latest","r":"oldrel-3","allowfail":false},{"os":"ubuntu-latest","r":"oldrel-4","allowfail":false},{"os":"ubuntu-latest","r":"oldrel-5","allowfail":false}]}' >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
R-code-check:
|
||||
|
||||
@@ -48,7 +48,9 @@ jobs:
|
||||
config:
|
||||
# Test all old versions of R >= 3.0, we support them all!
|
||||
# For these old versions, dependencies and vignettes will not be checked.
|
||||
# For recent R versions, see check-recent.yaml (r-lib and tidyverse support the latest 5 major R releases).
|
||||
# For recent R versions, see check-current-testthat.yaml (r-lib and tidyverse support the latest 5 major R releases).
|
||||
# R 4.0 (oldrel-6) is tested here, since current testthat and its dependencies cannot be installed on it.
|
||||
- {os: ubuntu-latest, r: '4.0', allowfail: false}
|
||||
# - {os: ubuntu-latest, r: '3.6', allowfail: false}
|
||||
# - {os: windows-latest, r: '3.5', allowfail: false} # always fails, horrible with UTF-8
|
||||
# - {os: ubuntu-latest, r: '3.4', allowfail: false} # 3.1-3.4 now always fails with Error in grep(warn_re, lines, invert = TRUE, value = TRUE) attempt to set index 46/46 in SET_STRING_ELT
|
||||
@@ -76,15 +78,17 @@ jobs:
|
||||
|
||||
- uses: r-lib/actions/setup-pandoc@v2
|
||||
|
||||
- name: Install suggested pkgs (and tinytest) from CRAN
|
||||
- name: Install tinytest from CRAN
|
||||
# R < 3.2 cannot download over HTTPS, so install.packages() fails silently on CRAN;
|
||||
# download the source with curl instead (suggested packages require much newer R versions anyway)
|
||||
run: |
|
||||
desc_lines <- readLines('DESCRIPTION')
|
||||
suggests <- readLines('DESCRIPTION')[grepl("^(Suggests:| )", readLines('DESCRIPTION'))]
|
||||
suggests <- suggests[(which(grepl("^Suggests", suggests)) + 1):length(suggests)]
|
||||
suggests <- gsub("[ ,]", "", suggests)
|
||||
pkgs <- unique(c(suggests, "tinytest"))
|
||||
for (p in pkgs) try(install.packages(p, repos = "https://cran.r-project.org"), silent = TRUE)
|
||||
shell: Rscript {0}
|
||||
set -euo pipefail
|
||||
mkdir -p "$R_LIBS_USER"
|
||||
pkg=$(curl -sSL https://cran.r-project.org/src/contrib/ | grep -oE 'tinytest_[0-9.-]+\.tar\.gz' | head -1)
|
||||
curl -sSLo "/tmp/$pkg" "https://cran.r-project.org/src/contrib/$pkg"
|
||||
R CMD INSTALL -l "$R_LIBS_USER" "/tmp/$pkg"
|
||||
Rscript -e "library(tinytest, lib.loc = Sys.getenv('R_LIBS_USER'))"
|
||||
shell: bash
|
||||
|
||||
- name: Show session info
|
||||
if: always()
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
Package: AMR
|
||||
Version: 3.0.1.9113
|
||||
Version: 3.0.1.9114
|
||||
Date: 2026-10-10
|
||||
Title: Antimicrobial Resistance Data Analysis
|
||||
Description: Functions to simplify and standardise antimicrobial resistance (AMR)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# AMR 3.0.1.9113
|
||||
# AMR 3.0.1.9114
|
||||
|
||||
Planned as v3.1.0, mid October 2026.
|
||||
|
||||
|
||||
@@ -650,10 +650,10 @@ stop_ <- function(...,
|
||||
}
|
||||
# prevent errors with single opening curly brackets, we don't evaluate cli's/glue's {} in AMR anyway
|
||||
msg <- gsub("\\{(?!\\.)", "", msg, perl = TRUE)
|
||||
if (!cli::ansi_has_hyperlink_support()) {
|
||||
msg <- simplify_help_markup(msg)
|
||||
}
|
||||
if (has_cli_rlang()) {
|
||||
if (!cli::ansi_has_hyperlink_support()) {
|
||||
msg <- simplify_help_markup(msg)
|
||||
}
|
||||
if (isTRUE(call)) {
|
||||
call_obj <- sys.call(-1)
|
||||
} else if (!isFALSE(call)) {
|
||||
|
||||
+3
-1
@@ -214,7 +214,9 @@
|
||||
#' syndromic_group = "ward"
|
||||
#' )
|
||||
#' out
|
||||
#' wisca_plot(out)
|
||||
#' if (requireNamespace("ggplot2")) {
|
||||
#' wisca_plot(out)
|
||||
#' }
|
||||
#'
|
||||
#' # stratified using grouped tibbles (e.g. by age and gender)
|
||||
#' if (requireNamespace("dplyr")) {
|
||||
|
||||
@@ -663,8 +663,10 @@ interpretive_rules <- function(x,
|
||||
if (isTRUE(ampc_cephalosporin_resistance)) {
|
||||
ampc_cephalosporin_resistance <- "R"
|
||||
}
|
||||
if (!is.null(interpretive_rules_df$reference.rule)) {
|
||||
interpretive_rules_df[which(interpretive_rules_df$reference.rule %like% "ampc"), "to_value"] <- as.character(ampc_cephalosporin_resistance)
|
||||
# old R versions (at least 3.0) give an error when assigning to no rows of a data.frame without rows
|
||||
ampc_rows <- if (is.null(interpretive_rules_df$reference.rule)) integer(0) else which(interpretive_rules_df$reference.rule %like% "ampc")
|
||||
if (length(ampc_rows) > 0) {
|
||||
interpretive_rules_df[ampc_rows, "to_value"] <- as.character(ampc_cephalosporin_resistance)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -313,7 +313,9 @@ out <- wisca(example_isolates,
|
||||
syndromic_group = "ward"
|
||||
)
|
||||
out
|
||||
wisca_plot(out)
|
||||
if (requireNamespace("ggplot2")) {
|
||||
wisca_plot(out)
|
||||
}
|
||||
|
||||
# stratified using grouped tibbles (e.g. by age and gender)
|
||||
if (requireNamespace("dplyr")) {
|
||||
|
||||
@@ -98,7 +98,7 @@ mo_repository_root <- function() {
|
||||
NULL
|
||||
}
|
||||
skip_if_no_mo_repository <- function() {
|
||||
testthat::skip_if(is.null(mo_repository_root()), "Source repository not available (data-raw/ does not ship with the package)")
|
||||
skip_if(is.null(mo_repository_root()), "Source repository not available (data-raw/ does not ship with the package)")
|
||||
}
|
||||
|
||||
# names without a rank suffix, e.g. "Kapabacteria {class}" and "Nitrospira (class)" are both the class
|
||||
|
||||
@@ -37,7 +37,7 @@ test_that("test-_deprecated.R", {
|
||||
# deprecated custom_interpretive_rules() still works and emits a warning
|
||||
expect_warning(
|
||||
x_old <- custom_eucast_rules(AMC == "R" ~ aminopenicillins == "R"),
|
||||
regexp = "custom_eucast_rules"
|
||||
"custom_eucast_rules"
|
||||
)
|
||||
expect_inherits(x_old, "custom_interpretive_rules")
|
||||
}
|
||||
|
||||
@@ -62,8 +62,10 @@ test_that("test-misc.R", {
|
||||
check_df <- function(check_element, return_val = 0) {
|
||||
is_right <<- FALSE
|
||||
for (env in sys.frames()) {
|
||||
if (!is.null(env[[check_element]]) && is.data.frame(env[[check_element]])) {
|
||||
is_right <<- all(colnames(example_isolates) %in% colnames(env[[check_element]]))
|
||||
# in R < 4.2, reading a promise that is still being evaluated (such as `x` in tibble's `[`) gives an error
|
||||
val <- tryCatch(env[[check_element]], error = function(e) NULL)
|
||||
if (!is.null(val) && is.data.frame(val)) {
|
||||
is_right <<- all(colnames(example_isolates) %in% colnames(val))
|
||||
}
|
||||
}
|
||||
return_val
|
||||
|
||||
@@ -242,9 +242,10 @@ test_that("test-interpretive_rules.R", {
|
||||
tolerance = 0.5
|
||||
)
|
||||
|
||||
# clsi_rules() no longer errors (returns data unchanged until CLSI rows are added)
|
||||
# clsi_rules() no longer errors (returns data unchanged until CLSI rows are added);
|
||||
# without the tibble package, a plain data.frame is returned
|
||||
expect_identical(
|
||||
suppressWarnings(clsi_rules(example_isolates, info = FALSE)),
|
||||
example_isolates
|
||||
if (AMR:::pkg_is_available("tibble")) example_isolates else as.data.frame(example_isolates, stringsAsFactors = FALSE)
|
||||
)
|
||||
})
|
||||
+30
-7
@@ -34,16 +34,30 @@ if (identical(Sys.getenv("R_RUN_TINYTEST"), "true")) {
|
||||
# env var 'R_LIBS_USER' gets overwritten during 'R CMD check' in GitHub Actions, so:
|
||||
.libPaths(c(Sys.getenv("R_LIBS_USER_GH_ACTIONS"), .libPaths()))
|
||||
|
||||
if (AMR:::pkg_is_available("tinytest", also_load = TRUE)) {
|
||||
if (!AMR:::pkg_is_available("tinytest", also_load = TRUE)) {
|
||||
stop("R_RUN_TINYTEST is 'true', but the tinytest package could not be loaded, so no unit tests were run")
|
||||
} else {
|
||||
|
||||
# load the package
|
||||
library(AMR)
|
||||
|
||||
# testthat equivalents; tinytest only records expectations that are called from the environment
|
||||
# of a test file, so these call the expectations found there (via `env`) instead of tinytest::
|
||||
test_that <- function(desc, code) {
|
||||
code
|
||||
env <- parent.frame()
|
||||
tryCatch(code,
|
||||
skip_test = function(s) invisible(NULL),
|
||||
error = function(e) get("expect_true", envir = env)(FALSE, info = paste0("Error in '", desc, "': ", conditionMessage(e)))
|
||||
)
|
||||
}
|
||||
skip_if <- function(condition, message = "") {
|
||||
if (isTRUE(condition)) stop(structure(class = c("skip_test", "condition"), list(message = message, call = NULL)))
|
||||
}
|
||||
expect_output <- tinytest::expect_stdout
|
||||
skip_on_cran <- function() invisible(NULL)
|
||||
expect_output <- function(...) get("expect_stdout", envir = parent.frame())(...)
|
||||
expect_named <- function(object, expected, ...) get("expect_identical", envir = parent.frame())(names(object), expected, ...)
|
||||
expect_setequal <- function(object, expected, ...) get("expect_true", envir = parent.frame())(setequal(object, expected), ...)
|
||||
expect_lte <- function(object, expected, ...) get("expect_true", envir = parent.frame())(isTRUE(all(object <= expected)), ...)
|
||||
|
||||
# set language
|
||||
set_AMR_locale("English")
|
||||
@@ -75,17 +89,26 @@ if (identical(Sys.getenv("R_RUN_TINYTEST"), "true")) {
|
||||
`%||%` <- AMR:::`%||%`
|
||||
}
|
||||
|
||||
testdir <- ifelse(dir.exists("inst/testthat"), "inst/testthat", "testthat")
|
||||
# helper files are sourced by testthat, but not by tinytest; helper-functions.R only contains expect_inherits(), which tinytest has itself
|
||||
helpers <- list.files(system.file(testdir, package = "AMR"), pattern = "^helper.*[.]R$", full.names = TRUE)
|
||||
for (helper in helpers[basename(helpers) != "helper-functions.R"]) {
|
||||
source(helper)
|
||||
}
|
||||
|
||||
suppressMessages(
|
||||
out <- test_package("AMR",
|
||||
testdir = ifelse(dir.exists("inst/testthat"),
|
||||
"inst/testthat",
|
||||
"testthat"
|
||||
),
|
||||
testdir = testdir,
|
||||
verbose = FALSE,
|
||||
color = FALSE
|
||||
)
|
||||
)
|
||||
cat("\n\nSUMMARY:\n")
|
||||
print(summary(out))
|
||||
if (!all_pass(out)) {
|
||||
cat("\n\nFAILURES:\n")
|
||||
print(out, passes = FALSE, limit = 100)
|
||||
stop("Unit tests failed, see above")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user