diff --git a/R/adat2eSet.R b/R/adat2eSet.R index 440ee70..4d651b7 100644 --- a/R/adat2eSet.R +++ b/R/adat2eSet.R @@ -32,10 +32,12 @@ adat2eSet <- function(adat) { if ( !requireNamespace("Biobase", quietly = TRUE) ) { + # nocov start stop( "The `Biobase` package is required to use this function.\n", "See ?adat2eSet for installation instructions.", call. = FALSE ) + # nocov end } stopifnot("`adat` must have intact attributes." = is_intact_attr(adat)) diff --git a/R/groupGenerics.R b/R/groupGenerics.R index 438b77f..66e2707 100644 --- a/R/groupGenerics.R +++ b/R/groupGenerics.R @@ -166,10 +166,23 @@ Summary.soma_adat <- function(..., na.rm = FALSE) { args <- lapply(list(...), function(x) { if ( is.soma_adat(x) ) { data.matrix(x[, getAnalytes(x)]) + .apts <- getAnalytes(x) + rfu <- x[, .apts] + mode_ok <- vapply(rfu, function(.x) { + is.numeric(.x) || is.complex(.x) || is.logical(.x) + }, NA) + if ( !all(mode_ok) ) { + warning( + "Non-numeric variable(s) detected in `soma_adat` object ", + "where RFU values should be. Removing: ", + .value(names(rfu[, .apts])[!mode_ok]), ".", call. = FALSE + ) + } + data.matrix(rfu[, mode_ok]) } else if ( !is.numeric(x) && !is.logical(x) && !is.complex(x) ) { - stop(deparse(.Generic), - " is only defined on a `soma_adat` with all numeric-alike variables.", - call. = FALSE + stop("`", .Generic, "()`", + " is only defined on a `soma_adat` with all numeric-alike variables.", + call. = FALSE ) } else { x @@ -197,11 +210,11 @@ Summary.soma_adat <- function(..., na.rm = FALSE) { #' @export Math.soma.adat <- function(x, ...) { .msg <- paste( - "The", .value("soma.adat"), "class is now", .value("soma_adat"), - "\nPlease either:\n", + "The", .value("soma.adat"), "class is now", .value("soma_adat"), ".\n", + "Please either:\n", " 1) Re-class with x <- addClass(x, 'soma_adat')\n", " 2) Re-call 'x <- read_adat(file)' to pick up the new 'soma_adat' class.\n" ) cat(.msg) - deprecate_stop("2019-01-31", "SomaDataIO::Math.soma.adat()") + deprecate_stop("(2019-01-31)", "SomaDataIO::Math.soma.adat()") } diff --git a/R/pivotExpressionSet.R b/R/pivotExpressionSet.R index 025c11d..3a6baaf 100644 --- a/R/pivotExpressionSet.R +++ b/R/pivotExpressionSet.R @@ -25,10 +25,12 @@ pivotExpressionSet <- function(eSet) { if ( !requireNamespace("Biobase", quietly = TRUE) ) { + # nocov start stop( "The `Biobase` package is required to use this function.\n", "See ?adat2eSet for installation instructions.", call. = FALSE ) + # nocov end } # samples (rows) x features (cols); move rn -> 1st column diff --git a/R/read-annotations.R b/R/read-annotations.R index fd64587..8d08a58 100644 --- a/R/read-annotations.R +++ b/R/read-annotations.R @@ -10,7 +10,7 @@ #' @examples #' \dontrun{ #' # for example -#' file <- "~/Desktop/SomaScan_V4.1_7K_Annotated_Content_20210616.xlsx" +#' file <- "~/Downloads/SomaScan_11K_Annotated_Content.xlsx" #' anno_tbl <- read_annotations(file) #' } #' @importFrom readxl read_xlsx @@ -48,7 +48,7 @@ read_annotations <- function(file) { # file modified if ( !identical(md5_file, md5_true) ) { warning( - "Checksum mismatch.", .value(basename(file)), " may have been modified.", + "Checksum mismatch. ", .value(basename(file)), " may have been modified.", call. = FALSE ) } diff --git a/R/utils-read-adat.R b/R/utils-read-adat.R index fdf87d3..904a0ba 100644 --- a/R/utils-read-adat.R +++ b/R/utils-read-adat.R @@ -217,7 +217,7 @@ catchDims <- function(x, y) { cli_rule(cr_bold("Trailing 2 RFU features"), line_col = "magenta") ) nc <- ncol(rfu) - print(rfu[1:6, (nc - 1):nc]) + print(head(as_tibble(rfu[, (nc - 1L):nc]))) writeLines(cli_rule(line_col = "green", line = 2)) invisible(NULL) } diff --git a/R/zzz.R b/R/zzz.R index 9c643ec..5d7ef34 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -4,6 +4,7 @@ .onLoad <- function(libname, pkgname) { # this is to make the active binding switch between # UTF-8 and ASCII symbol encodings + # nocov start `%enc%` <- function(utf, ascii) { if ( getOption("cli.unicode", TRUE) && l10n_info()$`UTF-8` ) { utf @@ -17,6 +18,7 @@ makeActiveBinding("symb_warn", function() "\u26A0" %enc% "!", pkgenv) makeActiveBinding("symb_point", function() "\u276F" %enc% ">", pkgenv) makeActiveBinding("symb_info", function() "\u2139" %enc% "i", pkgenv) + # nocov end } .onAttach <- function(libname, pkgname) { diff --git a/man/read_annotations.Rd b/man/read_annotations.Rd index 0c6ba84..a29eb78 100644 --- a/man/read_annotations.Rd +++ b/man/read_annotations.Rd @@ -23,7 +23,7 @@ Import a SomaLogic Annotations File \examples{ \dontrun{ # for example - file <- "~/Desktop/SomaScan_V4.1_7K_Annotated_Content_20210616.xlsx" + file <- "~/Downloads/SomaScan_11K_Annotated_Content.xlsx" anno_tbl <- read_annotations(file) } } diff --git a/tests/testthat/_snaps/S3-print.md b/tests/testthat/_snaps/S3-print.md index 0ccd153..a9f8e93 100644 --- a/tests/testthat/_snaps/S3-print.md +++ b/tests/testthat/_snaps/S3-print.md @@ -1,4 +1,4 @@ -# `soma_adat` S3 print method returns known output +# `soma_adat` S3 print method returns expected default output == SomaScan Data =============================================================== SomaScan version V4 (5k) @@ -35,7 +35,7 @@ # SampleDescription , ... ================================================================================ ---- +# `soma_adat` S3 print method returns expected head output == SomaScan Data =============================================================== SomaScan version V4 (5k) @@ -67,7 +67,7 @@ # SampleDescription , ... ================================================================================ ---- +# `soma_adat` S3 print method returns expected `show_header = TRUE` output == SomaScan Data =============================================================== SomaScan version V4 (5k) @@ -105,7 +105,7 @@ # i 20 more rows ================================================================================ ---- +# `soma_adat` S3 print method returns expected `grouped_df` output == SomaScan Data =============================================================== SomaScan version V4 (5k) @@ -143,7 +143,7 @@ # AssayNotes , ... ================================================================================ ---- +# `soma_adat` S3 print method returns expected broken attributes output == SomaScan Data =============================================================== SomaScan version unknown (NA) diff --git a/tests/testthat/_snaps/groupGenerics.md b/tests/testthat/_snaps/groupGenerics.md index c8896da..cecc5ed 100644 --- a/tests/testthat/_snaps/groupGenerics.md +++ b/tests/testthat/_snaps/groupGenerics.md @@ -19,3 +19,13 @@ Output ================================================================================ +# error conditions generate the expected output for deprecated `soma.adat` + + Code + readLines(catfile) + Output + [1] "The 'soma.adat' class is now 'soma_adat' ." + [2] " Please either:" + [3] " 1) Re-class with x <- addClass(x, 'soma_adat')" + [4] " 2) Re-call 'x <- read_adat(file)' to pick up the new 'soma_adat' class." + diff --git a/tests/testthat/_snaps/parseCheck.md b/tests/testthat/_snaps/parseCheck.md new file mode 100644 index 0000000..e4c4390 --- /dev/null +++ b/tests/testthat/_snaps/parseCheck.md @@ -0,0 +1,28 @@ +# `parseCheck()` prints expected output + + Code + specs + Output + [1] "== Parsing Specs ===============================================================" + [2] "• Table Begin '45'" + [3] "• Col.Meta Start '46'" + [4] "• Col.Meta Shift '35'" + [5] "• Header Row '66'" + [6] "• Rows of the Col Meta '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65'" + [7] "-- Col Meta -------------------------------------------------------------- 20 --" + [8] "i SeqId, SeqIdVersion, SomaId, TargetFullName, Target, UniProt, EntrezGeneID," + [9] "i EntrezGeneSymbol, Organism, Units, Type, Dilution, PlateScale_Reference," + [10] "i CalReference, Cal_Example_Adat_Set001, ColCheck," + [11] "i CalQcRatio_Example_Adat_Set001_170255, QcReference_170255," + [12] "i Cal_Example_Adat_Set002, CalQcRatio_Example_Adat_Set002_170255" + [13] "-- Row Meta -------------------------------------------------------------- 34 --" + [14] "i PlateId, PlateRunDate, ScannerID, PlatePosition, SlideId, Subarray, SampleId," + [15] "i SampleType, PercentDilution, SampleMatrix, Barcode, Barcode2d, SampleName," + [16] "i SampleNotes, AliquotingNotes, SampleDescription, AssayNotes, TimePoint," + [17] "i ExtIdentifier, SsfExtId, SampleGroup, SiteId, TubeUniqueID, CLI," + [18] "i HybControlNormScale, RowCheck, NormScale_20, NormScale_0_005, NormScale_0_5," + [19] "i ANMLFractionUsed_20, ANMLFractionUsed_0_005, ANMLFractionUsed_0_5, Age, Sex" + [20] "-- Empty Strings Detected in Col.Meta ------------------------------------- ! --" + [21] "i They may be missing in: [1] \"'Spuriomers', 'HybControls'\"" + [22] "== Parse Diagnostic Complete ===================================================" + diff --git a/tests/testthat/_snaps/utils-read-adat.md b/tests/testthat/_snaps/utils-read-adat.md new file mode 100644 index 0000000..cb9c99f --- /dev/null +++ b/tests/testthat/_snaps/utils-read-adat.md @@ -0,0 +1,47 @@ +# `checkHeader()` prints expected output + + Code + checkHeader(header, verbose = TRUE) + Message + v Header passed checks and traps + +# .verbosity()` prints expected output + + Code + .verbosity(adat, header) + Output + == Parsing Diagnostics ========================================================= + Message + v ADAT version > 1.2 + v Header skip > 41 + v Table begin > 20 + v Col.Meta start > 21 + v Col.Meta shift > 35 + v Is old ADAT > FALSE + v no. clinical variables > 34 + v no. RFU variables > 5284 + v Dim data matrix > 1 x 5318 + v Dim Col.Meta (annot.) > 5284 x 20 + Output + -- Head Col Meta --------------------------------------------------------------- + # A tibble: 6 x 20 + SeqId SeqIdVersion SomaId TargetFullName Target UniProt EntrezGeneID + + 1 10000-28 3 SL019233 Beta-crystallin B2 CRBB2 P43320 1415 + 2 10001-7 3 SL002564 RAF proto-oncogene~ c-Raf P04049 5894 + 3 10003-15 3 SL019245 Zinc finger protei~ ZNF41 P51814 7592 + 4 10006-25 3 SL019228 ETS domain-contain~ ELK1 P19419 2002 + 5 10008-43 3 SL019234 Guanylyl cyclase-a~ GUC1A P43080 2978 + 6 10011-65 3 SL019246 Inositol polyphosp~ OCRL Q01968 4952 + # i 13 more variables: EntrezGeneSymbol , Organism , Units , + # Type , Dilution , PlateScale_Reference , CalReference , + # Cal_Example_Adat_Set001 , ColCheck , + # CalQcRatio_Example_Adat_Set001_170255 , QcReference_170255 , + # Cal_Example_Adat_Set002 , CalQcRatio_Example_Adat_Set002_170255 + -- Trailing 2 RFU features ----------------------------------------------------- + # A tibble: 1 x 2 + seq.9997.12 seq.9999.1 + + 1 11983. 1741. + ================================================================================ + diff --git a/tests/testthat/_snaps/utils-release.md b/tests/testthat/_snaps/utils-release.md new file mode 100644 index 0000000..55fb500 --- /dev/null +++ b/tests/testthat/_snaps/utils-release.md @@ -0,0 +1,110 @@ +# `.bullets()` prints expected output + + Code + .bullets("prepare") + Output + [1] "Merge final branch(es) to `main`" + [2] "Sync forks and `git pull --rebase`" + [3] "Create release candidate branch: `git checkout -b rc-{version}`" + [4] "Review [extrachecks](https://github.com/DavisVaughan/extrachecks)" + [5] "Check if any deprecation processes should be advanced:" + [6] " [Gradual deprecation](https://lifecycle.r-lib.org/articles/communicate.html#gradual-deprecation)" + [7] "[Polish NEWS.md](https://style.tidyverse.org/news.html#news-release)" + [8] " `cat(usethis:::news_latest(readLines('NEWS.md')))`" + [9] "`devtools::spell_check()`" + [10] "`urlchecker::url_check()`" + [11] "Build `README`:" + [12] " `make readme`" + [13] " `devtools::build_readme()`" + [14] "Update roxygen docs: `make docs`" + [15] "Run local checks: `make check`" + [16] "Check revdeps on CRAN" + [17] "Remote checks:" + [18] " `devtools::check(remote = TRUE, manual = TRUE)`" + [19] " `rhub::check(platform = 'ubuntu-rchk')`" + [20] " `devtools::check_win_devel()`" + [21] " `rhub::check_with_sanitizers()`" + [22] " `rhub::check_for_cran()`" + [23] "Update `cran-comments.md` accordingly" + [24] "PR and merge `rc-{version}`" + +--- + + Code + .bullets("submit") + Output + [1] "Create a submission branch: `git checkout -b submit-cran-{version}`" + [2] "Bump version: `usethis::use_version('{version_type}')`" + [3] "Check `NEWS.md` file was updated and is correct" + [4] "Update `cran-comments.md` as necessary" + [5] "`devtools::submit_cran()`" + [6] "Approve :email:" + +--- + + Code + .bullets("wait") + Output + [1] "Accepted :tada:" + [2] "`git push public/main` :pushpin:" + [3] "Check that `pkgdown` was deployed to website via GitHub Action" + [4] "Tag release commit with new tag:" + [5] " `git tag tag -a v{version} -m 'Release of v{version}'`" + [6] " `git push public v{version}`" + [7] "Add [Release](https://github.com/SomaLogic/SomaDataIO/releases) from `NEWS.md`" + [8] "Bump version to dev: `usethis::use_dev_version(push = FALSE)`" + [9] "Done! :partying_face:" + +# `.create_checklist()` prints expected output + + Code + .create_checklist("1.0.0") + Output + [1] "## Prepare for release :hot_face:" + [2] "" + [3] "- [ ] Merge final branch(es) to `main`" + [4] "- [ ] Sync forks and `git pull --rebase`" + [5] "- [ ] Create release candidate branch: `git checkout -b rc-1.0.0`" + [6] "- [ ] Review [extrachecks](https://github.com/DavisVaughan/extrachecks)" + [7] "- [ ] Check if any deprecation processes should be advanced:" + [8] " - [ ] [Gradual deprecation](https://lifecycle.r-lib.org/articles/communicate.html#gradual-deprecation)" + [9] "- [ ] [Polish NEWS.md](https://style.tidyverse.org/news.html#news-release)" + [10] " - [ ] `cat(usethis:::news_latest(readLines('NEWS.md')))`" + [11] "- [ ] `devtools::spell_check()`" + [12] "- [ ] `urlchecker::url_check()`" + [13] "- [ ] Build `README`:" + [14] " - [ ] `make readme`" + [15] " - [ ] `devtools::build_readme()`" + [16] "- [ ] Update roxygen docs: `make docs`" + [17] "- [ ] Run local checks: `make check`" + [18] "- [ ] Check revdeps on CRAN" + [19] "- [ ] Remote checks:" + [20] " - [ ] `devtools::check(remote = TRUE, manual = TRUE)`" + [21] " - [ ] `rhub::check(platform = 'ubuntu-rchk')`" + [22] " - [ ] `devtools::check_win_devel()`" + [23] " - [ ] `rhub::check_with_sanitizers()`" + [24] " - [ ] `rhub::check_for_cran()`" + [25] "- [ ] Update `cran-comments.md` accordingly" + [26] "- [ ] PR and merge `rc-1.0.0`" + [27] "" + [28] "## Submit to CRAN :crossed_fingers:" + [29] "" + [30] "- [ ] Create a submission branch: `git checkout -b submit-cran-1.0.0`" + [31] "- [ ] Bump version: `usethis::use_version('major')`" + [32] "- [ ] Check `NEWS.md` file was updated and is correct" + [33] "- [ ] Update `cran-comments.md` as necessary" + [34] "- [ ] `devtools::submit_cran()`" + [35] "- [ ] Approve :email:" + [36] "" + [37] "## Wait for CRAN ... :sleeping:" + [38] "" + [39] "- [ ] Accepted :tada:" + [40] "- [ ] `git push public/main` :pushpin:" + [41] "- [ ] Check that `pkgdown` was deployed to website via GitHub Action" + [42] "- [ ] Tag release commit with new tag:" + [43] " - [ ] `git tag tag -a v1.0.0 -m 'Release of v1.0.0'`" + [44] " - [ ] `git push public v1.0.0`" + [45] "- [ ] Add [Release](https://github.com/SomaLogic/SomaDataIO/releases) from `NEWS.md`" + [46] "- [ ] Bump version to dev: `usethis::use_dev_version(push = FALSE)`" + [47] "- [ ] Done! :partying_face:" + diff --git a/tests/testthat/helper.R b/tests/testthat/helper.R index f7c300f..cad75af 100644 --- a/tests/testthat/helper.R +++ b/tests/testthat/helper.R @@ -76,3 +76,12 @@ with_interactive <- function(lgl, code) { }) force(code) # execute code in new state } + +# temporarily modify internal pkg object +# for testing edge cases +with_pkg_object <- function(new, code, obj = "ver_dict") { + old <- getFromNamespace(obj, ns = "SomaDataIO") # save the old obj + assignInNamespace(obj, new, ns = "SomaDataIO") + on.exit(assignInNamespace(obj, old, ns = "SomaDataIO")) + force(code) +} diff --git a/tests/testthat/test-S3-print.R b/tests/testthat/test-S3-print.R index 0330140..bd41ec9 100644 --- a/tests/testthat/test-S3-print.R +++ b/tests/testthat/test-S3-print.R @@ -4,26 +4,32 @@ # set to FALSE to enable ASCII fallbacks; see `testthat::local_test_context()` # unit tests for print output also don't colors/bold styles {from `pillar`} # Turn all these off for the unit testing context +testthat::local_reproducible_output() +adat <- example_data # Testing ---- -test_that("`soma_adat` S3 print method returns known output", { - testthat::local_reproducible_output() - - adat <- example_data - +test_that("`soma_adat` S3 print method returns expected default output", { # default expect_snapshot_output(adat) +}) +test_that("`soma_adat` S3 print method returns expected head output", { # head expect_snapshot_output(head(adat)) +}) +test_that("`soma_adat` S3 print method returns expected `show_header = TRUE` output", { # show_header is TRUE expect_snapshot_output(print(adat, show_header = TRUE)) +}) +test_that("`soma_adat` S3 print method returns expected `grouped_df` output", { # grouped_df grouped_adat <- dplyr::group_by(adat, SampleType) expect_snapshot_output(grouped_adat) +}) +test_that("`soma_adat` S3 print method returns expected broken attributes output", { # break atts attr(adat, "Header.Meta") <- NULL expect_false(is_intact_attr(adat, verbose = FALSE)) diff --git a/tests/testthat/test-S3-transform.R b/tests/testthat/test-S3-transform.R index c0192ba..9e98d13 100644 --- a/tests/testthat/test-S3-transform.R +++ b/tests/testthat/test-S3-transform.R @@ -19,13 +19,21 @@ df <- data.frame( sample = paste0("sample_", 1:3), seq.1234.56 = c(1, 2, 3), seq.9999.88 = c(4, 5, 6) * 10 - ) %>% # `soma_adat` to invoke S3 method dispatch + ) |> # `soma_adat` to invoke S3 method dispatch addClass("soma_adat") -test_that("transform() dispatches the soma_adat method and correctly scales", { +test_that("`transform()` dispatches the `soma_adat` method and correctly scales (cols)", { trans <- transform(df, v) expect_s3_class(trans, "soma_adat") expect_equal(trans$seq.1234.56, df$seq.1234.56 * 2) expect_equal(trans$seq.9999.88, df$seq.9999.88 * 0.5) expect_named(trans, names(df)) }) + +test_that("`transform()` dispatches the `soma_adat` method and correctly scales (rows)", { + vec <- c(1, 2, 3) + trans <- transform(df, vec, 1L) + expect_s3_class(trans, "soma_adat") + expect_equal(trans$seq.1234.56, df$seq.1234.56 * vec) + expect_equal(trans$seq.9999.88, df$seq.9999.88 * vec) +}) diff --git a/tests/testthat/test-getSomaScanLiftCCC.R b/tests/testthat/test-getSomaScanLiftCCC.R new file mode 100644 index 0000000..d953771 --- /dev/null +++ b/tests/testthat/test-getSomaScanLiftCCC.R @@ -0,0 +1,19 @@ +test_that("`getSomaScanLiftCCC()` returns expected output for plasma", { + plasma <- getSomaScanLiftCCC("plasma") + expect_s3_class(plasma, "tbl_df") + expect_equal(dim(plasma), c(11083, 4)) + expect_equal(names(plasma), c("SeqId", "plasma_11k_to_5k_ccc", + "plasma_11k_to_7k_ccc", "plasma_7k_to_5k_ccc")) +}) + +test_that("`getSomaScanLiftCCC()` returns expected output for serum", { + serum <- getSomaScanLiftCCC("serum") + expect_s3_class(serum, "tbl_df") + expect_equal(dim(serum), c(11083, 4)) + expect_equal(names(serum), c("SeqId", "serum_11k_to_5k_ccc", + "serum_11k_to_7k_ccc", "serum_7k_to_5k_ccc")) +}) + +test_that("`getSomaScanLiftCCC()` errors given invalid matrix type", { + expect_error(getSomaScanLiftCCC("citrate"), "should be one of") +}) diff --git a/tests/testthat/test-groupGenerics.R b/tests/testthat/test-groupGenerics.R index 355d079..a6d8eae 100644 --- a/tests/testthat/test-groupGenerics.R +++ b/tests/testthat/test-groupGenerics.R @@ -101,8 +101,8 @@ test_that("the `Ops()` group generic generates the expected output", { expect_equal((adat >= 2566.2)$seq.1234.56, c(FALSE, TRUE, TRUE, FALSE, FALSE, TRUE)) expect_equal((adat <= 2566.2)$seq.1234.56, c(TRUE, FALSE, FALSE, TRUE, TRUE, TRUE)) - expect_equal(sum(adat > 3000), 10) - expect_equal(sum(adat < 3000), 8) + expect_equal(sum(adat > 3000), 10L) + expect_equal(sum(adat < 3000), 8L) # meta ata untouched ops <- adat + 10 @@ -178,3 +178,66 @@ test_that("the `Summary()` group generic generates the expected output", { expect_equal(max(adat, 4906), 4906) expect_equal(max(adat, Inf), Inf) }) + +test_that("error conditions generate the expected output for deprecated `soma.adat`", { + # old `soma.adat` class + adat2 <- structure(adat, class = c("soma.adat", "data.frame")) + catfile <- "msg.txt" + file.create(catfile) + expect_error( + capture.output(log10(adat2), file = catfile), + paste("`Math.soma.adat()` was deprecated in SomaDataIO (2019-01-31) and", + "is now defunct"), + fixed = TRUE + ) + # test the `cat()` message + expect_snapshot(readLines(catfile)) + unlink(catfile, force = TRUE) +}) + +test_that("error conditions are triggered for non-numerics in RFU block", { + tmp <- mock_adat() + tmp$seq.1234.56 <- "foo" + + # Math + expect_error( + log10(tmp), + paste( + "Non-numeric variable(s) in `soma_adat` object where RFU values should be:", + "'seq.1234.56'"), + fixed = TRUE + ) + + # Summary + expect_warning( + out <- range(tmp), + paste( + "Non-numeric variable(s) detected in `soma_adat` object where", + "RFU values should be. Removing: 'seq.1234.56'" + ), + fixed = TRUE + ) + expect_equal(out, c(2423.9, 4317.8)) + # with bad non-adat expressions via '...' + + expect_error( + range(adat, "a"), + "`range()` is only defined on a `soma_adat` with all numeric-alike variables", + fixed = TRUE + ) + expect_error( + sum(adat, factor("a")), + "`sum()` is only defined on a `soma_adat` with all numeric-alike variables", + fixed = TRUE + ) + expect_error( + max(adat, NULL), + "`max()` is only defined on a `soma_adat` with all numeric-alike variables", + fixed = TRUE + ) + expect_error( + min(adat, list(a = 1)), + "`min()` is only defined on a `soma_adat` with all numeric-alike variables", + fixed = TRUE + ) +}) diff --git a/tests/testthat/test-parseCheck.R b/tests/testthat/test-parseCheck.R new file mode 100644 index 0000000..b9b9fa2 --- /dev/null +++ b/tests/testthat/test-parseCheck.R @@ -0,0 +1,15 @@ + +# Setup ---- +f <- system.file("extdata", "example_data10.adat", + package = "SomaDataIO", mustWork = TRUE) +lines <- .getHeaderLines(f) |> strsplit("\t", fixed = TRUE) + +# Testing ---- +test_that("`parseCheck()` prints expected output", { + specs <- capture.output(suppressMessages(parseCheck(lines))) + expect_snapshot(specs) +}) + +test_that("`parseCheck()` errors given incorrect `all.tokens` argument", { + expect_error(parseCheck(f), "Format is wrong for the `all.tokens` argument.") +}) diff --git a/tests/testthat/test-read-annotations.R b/tests/testthat/test-read-annotations.R index 767ae67..d297e2b 100644 --- a/tests/testthat/test-read-annotations.R +++ b/tests/testthat/test-read-annotations.R @@ -25,3 +25,24 @@ test_that("`read_annotations()` parses the annotations file correctly", { expect_true(ver_dict[[ver]]$col_serum == names(tbl)[ver_dict[[ver]]$which_serum]) expect_true(ver_dict[[ver]]$col_plasma == names(tbl)[ver_dict[[ver]]$which_plasma]) }) + +test_that("error conditions trigger stops when appropriate", { + + expect_error( + read_annotations("foo.txt"), + "Annotations file must be either" + ) + + expect_error( + with_pkg_object(SomaDataIO:::ver_dict[-2L], read_annotations(file)), + "Unknown version of the annotations file:" + ) + + # temp modify md5sha + tmp <- SomaDataIO:::ver_dict + tmp$`SL-12345678-rev0-2021-01`$sha <- "x0x0x0x0x" + expect_warning( + with_pkg_object(tmp, read_annotations(file)), + "Checksum mismatch. 'test-anno.xlsx' may have been modified" + ) +}) diff --git a/tests/testthat/test-utils-read-adat.R b/tests/testthat/test-utils-read-adat.R new file mode 100644 index 0000000..e425c26 --- /dev/null +++ b/tests/testthat/test-utils-read-adat.R @@ -0,0 +1,153 @@ + +# Setup ---- +file <- test_path("testdata", "single_sample.adat") +adat <- read_adat(file) +header <- parseHeader(file) + +# Testing ---- +# checkHeader ---- +test_that("`checkHeader()` prints expected output", { + expect_silent(checkHeader(header, verbose = FALSE)) + expect_snapshot(checkHeader(header, verbose = TRUE)) +}) + +test_that("`checkHeader()` error conditions are met", { + idx <- which(names(header) == "Header.Meta") + expect_error( + checkHeader(header[-idx]), + "Could not find `Header.Meta`" + ) + idx <- which(names(header) == "Col.Meta") + expect_error( + checkHeader(header[-idx]), + "No `Col.Meta` data found in adat" + ) + idx <- which(names(header) == "file_specs") + expect_error( + checkHeader(header[-idx]), + paste( + "No `file_specs` entry found in header ...", + "should be added during file parsing" + ) + ) +}) + +# catchHeaderMeta ---- +test_that("`catchHeaderMeta()` error conditions are met", { + HM <- header$Header.Meta + expect_invisible(catchHeaderMeta(HM)) + + HM$ROW_DATA$Name <- NULL + expect_error( + catchHeaderMeta(HM), + "Could not find `Name` entry in `ROW_DATA` of `Header.Meta`" + ) + + HM$ROW_DATA$Name <- rep("foo", 2L) + expect_error( + catchHeaderMeta(HM), + "Duplicate row (clinical) meta data fields defined in header `ROW_DATA`", + fixed = TRUE + ) + + HM$ROW_DATA <- NULL + expect_warning( + catchHeaderMeta(HM), + "`ROW_DATA` is mising from `Header.Meta`" + ) +}) + +# catchHeaderMeta ---- +test_that("`catchColMeta()` error conditions are met", { + CM <- header$Col.Meta + expect_invisible(catchColMeta(CM)) + + CM$SeqId <- NULL + expect_warning( + catchColMeta(CM), + paste0( + "No `SeqId` row found in Column Meta Data:\n", + "SeqIds will be absent from adat Column Meta AND ", + "`getAnalytes()` cannot function properly" + ), + fixed = TRUE + ) +}) + +# catchFile ---- +test_that("`catchFile()` error conditions are met", { + FS <- header$file_specs + expect_invisible(catchFile(FS)) + FS$empty_adat <- 1L + expect_error( + catchFile(FS), + "The `empty_adat` entry of `file_specs` should be class logical:" + ) + FS <- header$file_specs + FS$table_begin <- "foo" # should be numeric(1) + expect_error( + catchFile(FS), + "The `table_begin` entry of `file_specs` should be class numeric AND length 1:" + ) + FS$table_begin <- numeric(2) # should be numeric(1) + expect_error( + catchFile(FS), + "The `table_begin` entry of `file_specs` should be class numeric AND length 1:" + ) + FS <- header$file_specs + FS$old_adat <- 1L # should be logical(1) + expect_error( + catchFile(FS), + "The `old_adat` entry of `file_specs` should be class logical:" + ) + FS <- header$file_specs + FS$col_meta_start <- "foo" # should be numeric(1) + expect_error( + catchFile(FS), + "The `col_meta_start` entry of `file_specs` should be class numeric AND length 1:" + ) + FS$col_meta_start <- numeric(2) # should be numeric(1) + expect_error( + catchFile(FS), + "The `col_meta_start` entry of `file_specs` should be class numeric AND length 1:" + ) + FS <- header$file_specs + FS$col_meta_shift <- "foo" # should be numeric(1) + expect_error( + catchFile(FS), + "The `col_meta_shift` entry of `file_specs` should be class numeric AND length 1:" + ) + FS$col_meta_shift <- numeric(2) # should be numeric(1) + expect_error( + catchFile(FS), + "The `col_meta_shift` entry of `file_specs` should be class numeric AND length 1:" + ) + FS <- header$file_specs + FS$data_begin <- "foo" # should be numeric(1) + expect_error( + catchFile(FS), + "The `data_begin` entry of `file_specs` should be class numeric AND length 1:" + ) + FS$data_begin <- numeric(2) # should be numeric(1) + expect_error( + catchFile(FS), + "The `data_begin` entry of `file_specs` should be class numeric AND length 1:" + ) +}) + +# catchDims ---- +test_that("`catchDims()` error conditions are met", { + x <- mock_adat() + nc <- ncol(x) + expect_invisible(catchDims(x, nc)) + expect_error( + catchDims(x, nc - 1L), + "Number of columns in `rfu_dat` not equal to (meta + aptamers) length", + fixed = TRUE + ) +}) + +# verbosity ---- +test_that(".verbosity()` prints expected output", { + expect_snapshot(.verbosity(adat, header)) # `adat` is a single sample ADAT +}) diff --git a/tests/testthat/test-utils-release.R b/tests/testthat/test-utils-release.R new file mode 100644 index 0000000..b7651fd --- /dev/null +++ b/tests/testthat/test-utils-release.R @@ -0,0 +1,18 @@ + +# Testing ---- +test_that("`.bullets()` prints expected output", { + expect_snapshot(.bullets("prepare")) + expect_snapshot(.bullets("submit")) + expect_snapshot(.bullets("wait")) +}) + +test_that("`.ver_type()` returns expected release types", { + expect_equal(.ver_type("1.0.0"), "major") + expect_equal(.ver_type("0.1.0"), "minor") + expect_equal(.ver_type("0.0.1"), "patch") + expect_equal(.ver_type("0.0.0.1"), "dev") +}) + +test_that("`.create_checklist()` prints expected output", { + expect_snapshot(.create_checklist("1.0.0")) +})