Nothing
skip_on_cran()
library(knitr)
# This code mocks functions that have long execution times so that unit tests
# complete more quickly. Initial tests suggest that the mocks need to be defined
# in the file in which the tests are executed. `source`ing the mocks does not
# work.
#
# The persistent objects that are loaded are created by
# /testthat/fixtures/make_persistent_objects_for_mocked_constructors.R.
testthat::local_mocked_bindings(
.DefaultDASimulations = function(...) {
readRDS(testthat::test_path("fixtures", "default_da_simulations.Rds"))
}
)
testthat::local_mocked_bindings(
.DefaultSimulations = function(...) {
readRDS(testthat::test_path("fixtures", "default_simulations.Rds"))
}
)
testthat::local_mocked_bindings(
.DefaultDualSimulations = function(...) {
readRDS(testthat::test_path(
"fixtures",
"default_dual_simulations.Rds"
))
}
)
# End of mocks
# h_custom_method_exists could be removed once all necessary knit_print methods
# have been defined
#' Test if a Class-Specific S3 Generic Exists
#'
#' @param generic (`name`)\cr The unquoted name of the generic, which must exist
#' @param obj (`ANY`)\cr An S3 or S4 object
#' @return TRUE if S3 method `<method_name>.<class_name>` exists, FALSE otherwise
#' @example h_custom_method_exists(knit_print, "CohortSizeConst") # TRUE
#' @example h_custom_method_exists(knot_print, "Validate") # FALSE
#' @internal
h_custom_method_exists <- function(generic, obj) {
# See https://stackoverflow.com/questions/42738851/r-how-to-find-what-s3-method-will-be-called-on-an-object
generic_name <- deparse(substitute(generic))
f <- X <- function(x, obj) UseMethod("X")
for (m in methods(generic_name)) {
assign(sub(generic_name, "X", m, fixed = TRUE), "body<-"(f, value = m))
}
method_name <- X(obj)
(method_name != paste0(generic_name, ".default"))
}
test_that("h_custom_method_exists works correctly", {
withr::with_environment(
.GlobalEnv,
{
foo <<- function(x, ...) UseMethod("foo")
bar <<- NA
class(bar) <- "bar"
baz <<- NA
class(baz) <- "baz"
foo.default <<- function(x, ...) "I don't know what to do" # nolint
foo.bar <<- function(x, ...) "I am bar" # nolint
withr::defer(rm(foo, bar, baz, foo.default, foo.bar, envir = .GlobalEnv))
expect_true(h_custom_method_exists(foo, bar))
expect_false(h_custom_method_exists(foo, baz))
}
)
})
test_that("Global environment is clean after testing h_custom_method_exists", {
expect_false(exists("foo"))
expect_false(exists("bar"))
expect_false(exists("baz"))
expect_false(exists("foo.bar"))
expect_false(exists("foo.default"))
})
crmpack_class_list <- getClasses(asNamespace("crmPack"))
exclusions <- c(
"CohortSize",
"CrmPackClass",
"DualEndpoint",
"GeneralData",
"GeneralModel",
"GeneralSimulationsSummary",
"Increments",
"ModelEff",
"ModelPseudo",
"ModelTox",
"NextBest",
"positive_number",
"PseudoSimulations",
"PseudoDualSimulations",
"PseudoDualSimulationsSummary",
"PseudoDualFlexiSimulations",
"PseudoFlexiSimulations",
"PseudoSimulationsSummary",
"SimulationsSummary",
"Report",
"SafetyWindow",
"Stopping",
"Validate",
# The following classes have no constructors
"DualSimulationsSummary"
)
crmpack_class_list <- setdiff(crmpack_class_list, exclusions)
test_that("knit_print methods exist for all relevant classes and produce consistent output", {
for (cls in crmpack_class_list) {
if (!isClassUnion(cls)) {
# If the default knit_print method has been overridden, test it
if (
h_custom_method_exists(
knit_print,
do.call(paste0(".Default", cls), list())
)
) {
outFileName <- paste0("knit_print_", cls, ".html")
# with_file guarantees that the test file will be deleted automatically
# once the snapshot has been compared with the previous version, which
# can be found in /_snaps/helpers_knitr
withr::with_file(
test_path("fixtures", outFileName),
{
# Code run in the template does not contribute to test coverage
tryCatch(
{
rmarkdown::render(
input = test_path("fixtures", "knit_print_template.Rmd"),
params = list("class_name" = cls),
output_file = outFileName,
output_dir = test_path("fixtures"),
quiet = TRUE
)
expect_snapshot_file(test_path("fixtures", outFileName))
},
error = function(e) {
warning(paste0("Error for class ", cls, ": "), geterrmessage())
}
)
}
)
}
} else {
warning(paste0("No default constructor for ", cls))
}
}
})
test_that("asis parameter works correctly for all implemented methods", {
for (cls in crmpack_class_list) {
if (!isClassUnion(cls)) {
startTime <- Sys.time()
obj <- do.call(paste0(".Default", cls), list())
endTime <- Sys.time()
if (unclass(endTime - startTime) > 2) {
print(paste0("Long initialisation for ", cls))
}
# If the default knit_print method has been overridden, test it
if (h_custom_method_exists(knit_print, obj)) {
# Default behaviour
rv <- knit_print(obj)
if (is.null(rv)) {
print(paste0("knit_print(obj) returns NULL for class ", cls, "."))
}
expect_class(rv, "knit_asis")
# Explicit behaviours
rv <- knit_print(obj, asis = TRUE)
if (is.null(rv)) {
print(paste0(
"knit_print(obj, asis = TRUE) returns NULL for class ",
cls,
"."
))
}
expect_class(rv, "knit_asis")
rv <- knit_print(obj, asis = FALSE)
if (is.null(rv)) {
print(paste0(
"knit_print(obj, asis = FALSE) returns NULL for class ",
cls,
"."
))
}
# Most objects return a character, but not all. For example,
# CohortSizeDLT returns a knitr_table
if ("knit_asis" %in% class(rv)) {
print(cls)
}
expect_true(!("knit_asis" %in% class(rv)))
# Invalid value
errorThrown <- FALSE
tryCatch(
{
knit_print(obj, asis = "badValue")
},
error = function(e) errorThrown <<- TRUE
)
if (!errorThrown) {
print(paste0("No error thrown for ", cls, "."))
}
expect_error(knit_print(obj, asis = "badValue"))
}
}
}
})
test_that("knit_print output is suffixed by two newlines for all implemented methods", {
for (cls in crmpack_class_list) {
if (!isClassUnion(cls)) {
obj <- do.call(paste0(".Default", cls), list())
# If the default knit_print method has been overridden, test it
if (h_custom_method_exists(knit_print, obj)) {
rv <- knit_print(obj, asis = FALSE)
if (is.null(rv)) {
print(paste0(
"knit_print(obj, asis = TRUE) returns NULL for class ",
cls,
"."
))
}
ok <- identical(stringr::str_sub(rv, -2), "\n\n")
if (!ok) {
print(paste0("Double newline missing for ", cls))
}
expect_true(ok)
}
}
}
})
# CohortSize ---
# CohortSizeConst
test_that("knit_print.CohortSizeConst works correctly", {
x <- CohortSizeConst(3)
rv <- knit_print(x)
expect_equal(rv, "A constant size of 3 participants.\n\n", ignore_attr = TRUE)
x <- CohortSizeConst(2)
rv <- knit_print(x, label = "subject")
expect_equal(rv, "A constant size of 2 subjects.\n\n", ignore_attr = TRUE)
x <- CohortSizeConst(1)
rv <- knit_print(x, label = "subject")
expect_equal(rv, "A constant size of 1 subject.\n\n", ignore_attr = TRUE)
x <- CohortSizeConst(3)
rv <- knit_print(x, asis = FALSE)
expect_equal(rv, "A constant size of 3 participants.\n\n")
})
# CohortSizeParts
test_that("knit_print.CohortSizeParts works correctly", {
x <- CohortSizeParts(c(1, 3))
rv <- knit_print(x)
expect_equal(
rv,
"A size of 1 participant in the first part and 3 participants in the second.\n\n",
ignore_attr = TRUE
)
x <- CohortSizeParts(c(1, 3))
rv <- knit_print(x, label = "subject")
expect_equal(
rv,
"A size of 1 subject in the first part and 3 subjects in the second.\n\n",
ignore_attr = TRUE
)
x <- CohortSizeParts(c(1, 3))
rv <- knit_print(x, label = "subject")
expect_equal(
rv,
"A size of 1 subject in the first part and 3 subjects in the second.\n\n",
ignore_attr = TRUE
)
x <- CohortSizeParts(c(1, 3))
rv <- knit_print(x, asis = FALSE)
expect_equal(
rv,
"A size of 1 participant in the first part and 3 participants in the second.\n\n"
)
})
# Increments ----
test_that("knit_print.IncrementsRelativeParts works correctly", {
testList <- list(
"knit_print_IncrementsRelativeParts1.html" = IncrementsRelativeParts(
clean_start = -1,
dlt_start = -2
),
"knit_print_IncrementsRelativeParts2.html" = IncrementsRelativeParts(
clean_start = 0,
dlt_start = -1
),
"knit_print_IncrementsRelativeParts3.html" = IncrementsRelativeParts(
clean_start = 2,
dlt_start = 1
),
"knit_print_IncrementsRelativeParts4.html" = IncrementsRelativeParts(
clean_start = 2,
dlt_start = -1
),
"knit_print_IncrementsRelativeParts5.html" = IncrementsRelativeParts(
clean_start = 1,
dlt_start = 0,
intervals = c(0, 20, 100),
increments = c(2, 1.5, 0.33)
)
)
for (name in names(testList)) {
withr::with_file(
test_path("fixtures", name),
{
rmarkdown::render(
input = test_path(
"fixtures",
"knit_print_object_specific_template.Rmd"
),
params = list("obj" = testList[[name]]),
output_file = name,
output_dir = test_path("fixtures"),
quiet = TRUE
)
expect_snapshot_file(test_path("fixtures", name))
}
)
}
# This test checks that the labels parameter is correctly substituted and that
# capitalisation in the table header is correctly handled.
expect_equal(
stringr::str_count(
knit_print(
.DefaultIncrementsRelativeParts(),
tox_label = "DLT"
),
"DLTs"
),
5
)
})
# Data ----
test_that("summarise option works correctly for Data classes", {
testList <- list(
"knit_print_Data_summarise.html" = .DefaultData(),
"knit_print_DataDA_summarise.html" = .DefaultDataDA(),
"knit_print_DataGrouped_summarise.html" = .DefaultDataDual(),
"knit_print_DataGrouped_summarise.html" = .DefaultDataGrouped(),
"knit_print_DataMixture_summarise.html" = .DefaultDataMixture()
# "knit_print_DataOrdinal_summarise.html" = .DefaultDataOrdinal() # nolint
)
for (name in names(testList)) {
withr::with_file(
test_path("fixtures", name),
{
rmarkdown::render(
input = test_path("fixtures", "knit_print_data_classes_template.Rmd"),
params = list("obj" = testList[[name]]),
output_file = name,
output_dir = test_path("fixtures"),
quiet = TRUE
)
expect_snapshot_file(test_path("fixtures", name))
}
)
# For test coverage stats
rv <- knit_print(testList[[name]], summarise = "dose")
expect_snapshot_value(rv, style = "serialize")
rv <- knit_print(testList[[name]], summarise = "cohort")
expect_snapshot_value(rv, style = "serialize")
}
})
test_that("h_get_formatted_dosegrid works correctly", {
expect_equal(
h_get_formatted_dosegrid(1:2),
"1 and 2.\n\n"
)
expect_equal(
h_get_formatted_dosegrid(1:3),
"1, 2 and 3.\n\n"
)
expect_equal(
h_get_formatted_dosegrid(1:3, units = "mg"),
"1 mg, 2 mg and 3 mg.\n\n"
)
expect_equal(
h_get_formatted_dosegrid(1:3, units = "mg", fmt = "%.2f"),
"1.00 mg, 2.00 mg and 3.00 mg.\n\n"
)
expect_equal(
h_get_formatted_dosegrid(1:3, fmt = "%.2f"),
"1.00, 2.00 and 3.00.\n\n"
)
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.