Nothing
skip_if_fp_study_deps <- function() {
testthat::skip_if_not_installed("ape")
testthat::skip_if_not_installed("phytools")
testthat::skip_if_not_installed("mvMORPH")
testthat::skip_if_not_installed("future")
testthat::skip_if_not_installed("future.apply")
testthat::skip_if_not_installed("progressr")
withr::local_options(list(progressr.enable = FALSE))
}
.fp_template_cache <- new.env(parent = emptyenv())
get_cached_fp_template <- function(key, builder) {
if (!exists(key, envir = .fp_template_cache, inherits = FALSE)) {
assign(key, builder(), envir = .fp_template_cache)
}
unserialize(serialize(get(key, envir = .fp_template_cache, inherits = FALSE), NULL))
}
make_fp_template <- function() {
get_cached_fp_template("fp_template", function() {
set.seed(30)
tr <- ape::rtree(22)
X <- matrix(rnorm(22 * 2), ncol = 2)
rownames(X) <- tr$tip.label
createSimulationTemplate(
baseline_tree = tr,
trait_data = X,
formula = "trait_data ~ 1",
method = "LL"
)
})
}
make_formula_fp_template <- function() {
get_cached_fp_template("formula_fp_template", function() {
set.seed(31)
tr <- ape::rtree(22)
grp <- factor(rep(c("a", "b"), length.out = 22))
size <- rnorm(22)
X <- data.frame(
y1 = 0.4 * size + ifelse(grp == "b", 0.8, 0) + rnorm(22),
y2 = -0.2 * size + ifelse(grp == "b", -0.5, 0) + rnorm(22),
size = size,
grp = grp,
row.names = tr$tip.label
)
createSimulationTemplate(
baseline_tree = tr,
trait_data = X,
formula = cbind(y1, y2) ~ size + grp,
method = "LL"
)
})
}
make_fp_template_with_error <- function() {
get_cached_fp_template("fp_template_with_error", function() {
set.seed(32)
tr <- ape::rtree(18)
X <- matrix(rnorm(18 * 2), ncol = 2)
rownames(X) <- tr$tip.label
createSimulationTemplate(
baseline_tree = tr,
trait_data = X,
formula = "trait_data ~ 1",
method = "LL",
error = TRUE
)
})
}
test_that("simulation searches muffle only the repeated settings advisory", {
skip_if_fp_study_deps()
tree <- ape::rtree(12)
trait_data <- matrix(
rnorm(24),
nrow = 12,
dimnames = list(tree$tip.label, c("trait_1", "trait_2"))
)
settings_warning <- simpleWarning("repeated settings advisory", call = NULL)
class(settings_warning) <- c(
"bifrost_search_settings_warning",
class(settings_warning)
)
search <- function(...) {
warning(settings_warning)
warning("genuine fitting warning", call. = FALSE)
list(
shift_nodes_no_uncertainty = integer(0),
num_candidates = 1L,
candidate_nodes = ape::Ntip(tree) + 2L
)
}
replicate <- list(
sim = list(tree = tree, data = trait_data),
seed = NULL
)
warning_classes <- list()
warning_messages <- character()
results <- withCallingHandlers(
lapply(seq_len(3L), function(i) {
bifrost:::.simulation_study_search(
replicate = replicate,
search_options = list(min_descendant_tips = 2L),
tree_component = "tree",
data_components = "data",
search_optimal_configuration = search,
generate_painted_trees = generatePaintedTrees,
with_replicate_seed = function(seed, code) force(code)
)
}),
warning = function(w) {
warning_classes[[length(warning_classes) + 1L]] <<- class(w)
warning_messages[[length(warning_messages) + 1L]] <<- conditionMessage(w)
invokeRestart("muffleWarning")
}
)
testthat::expect_length(results, 3L)
testthat::expect_false(any(vapply(
warning_classes,
function(classes) "bifrost_search_settings_warning" %in% classes,
logical(1)
)))
testthat::expect_identical(
warning_messages,
rep("genuine fitting warning", 3L)
)
})
test_that("runFalsePositiveSimulationStudy returns study summaries", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
tmpl <- make_fp_template()
study <- runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 1,
tree_tip_count = 18,
search_options = list(
formula = "trait_data ~ 1",
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC",
method = "LL"
),
num_cores = 1,
seed = 6
)
testthat::expect_s3_class(study, "bifrost_simulation_study")
testthat::expect_identical(study$study_type, "false_positive")
testthat::expect_identical(study$generating_scenario, "null")
testthat::expect_identical(study$simulation_generator, "original")
testthat::expect_identical(
unique(study$per_replicate$simulation_generator),
"original"
)
testthat::expect_false("simulation_design" %in% names(study))
testthat::expect_false("simulation_design" %in% names(study$per_replicate))
testthat::expect_false(study$search_options$progress)
testthat::expect_length(study$simdata, 1)
testthat::expect_length(study$results, 1)
testthat::expect_true(all(c(
"replicate", "n_candidates", "n_inferred_shifts", "false_positive_rate",
"status", "error"
) %in% names(study$per_replicate)))
testthat::expect_equal(
study$per_replicate$false_positive_rate,
study$per_replicate$n_inferred_shifts / study$per_replicate$n_candidates
)
testthat::expect_identical(as.data.frame(study), study$per_replicate)
})
test_that("runFalsePositiveSimulationStudy forwards the empirical generator", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
study <- runFalsePositiveSimulationStudy(
make_fp_template(),
n_replicates = 1,
tree_tip_count = 18,
simulation_options = list(simulation_generator = "empirical"),
search_options = list(
formula = "trait_data ~ 1",
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC",
method = "LL"
),
num_cores = 1,
seed = 6
)
testthat::expect_identical(study$simulation_generator, "empirical")
testthat::expect_identical(
study$simdata[[1L]]$simulation_generator,
"empirical"
)
})
test_that("runFalsePositiveSimulationStudy stores compact replicate calls", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
study <- runFalsePositiveSimulationStudy(
make_fp_template(),
n_replicates = 1,
tree_tip_count = 18,
search_options = list(
formula = "trait_data ~ 1",
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "BAD",
method = "LL"
),
num_cores = 1,
seed = 56
)
replicate_call <- study$simdata[[1L]]$user_input
testthat::expect_identical(replicate_call[[1L]], quote(simulateNullDataset))
testthat::expect_identical(
replicate_call$template,
"<bifrost_simulation_template>"
)
testthat::expect_false(is.symbol(replicate_call$template))
testthat::expect_lt(as.numeric(object.size(replicate_call)), 10000)
})
test_that("the false-positive study rejects generator vectors before RNG setup", {
skip_if_fp_study_deps()
tmpl <- make_fp_template()
rng_setup_called <- FALSE
local_rebind(
".simulation_set_seed",
function(...) {
rng_setup_called <<- TRUE
stats::runif(1)
stop("RNG setup reached", call. = FALSE)
},
environment(runFalsePositiveSimulationStudy)
)
set.seed(20260709)
before <- .Random.seed
testthat::expect_error(
runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 1,
simulation_options = list(
simulation_generator = c("original", "empirical")
),
seed = 6
),
"simulation_generator.*original.*empirical"
)
testthat::expect_false(rng_setup_called)
testthat::expect_identical(.Random.seed, before)
})
test_that("runFalsePositiveSimulationStudy rejects per-replicate seeds", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
tmpl <- make_fp_template()
testthat::expect_error(
runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 2,
simulation_options = list(seed = 99),
search_options = list(
formula = "trait_data ~ 1",
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC",
method = "LL"
),
num_cores = 1,
seed = 6
),
"simulation_options\\$seed"
)
})
test_that("runFalsePositiveSimulationStudy uses intercept-only searches for formula-calibrated templates", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
tmpl <- make_formula_fp_template()
study <- runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 1,
tree_tip_count = 20,
search_options = list(
formula = "trait_data ~ 1",
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC",
method = "LL"
),
num_cores = 1,
seed = 123
)
testthat::expect_identical(
study$search_options$formula,
simulationStudyFormulaCases$string
)
testthat::expect_identical(study$per_replicate$status, "ok")
testthat::expect_equal(colnames(study$simdata[[1]]$data), c("y1", "y2"))
testthat::expect_false("mass" %in% colnames(study$simdata[[1]]$data))
})
test_that("runFalsePositiveSimulationStudy inherits the default intercept-only search for data.frame templates", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
tmpl <- make_formula_fp_template()
study <- runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 1,
tree_tip_count = 20,
search_options = list(
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC",
method = "LL"
),
num_cores = 1,
seed = 124
)
testthat::expect_identical(study$search_options$formula, "trait_data ~ 1")
testthat::expect_identical(study$per_replicate$status, "ok")
testthat::expect_true(all(is.na(study$per_replicate$error)))
})
test_that("runFalsePositiveSimulationStudy rejects non-intercept search formulas", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
tmpl <- make_formula_fp_template()
testthat::expect_error(
runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 1,
tree_tip_count = 20,
search_options = list(
formula = "trait_data[, 1:2] ~ trait_data[, 3]",
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC",
method = "LL"
),
num_cores = 1,
seed = 123
),
simulationStudyFormulaErrors$non_intercept
)
})
test_that("runFalsePositiveSimulationStudy validates inputs and inherits template error settings", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
tmpl <- make_fp_template_with_error()
testthat::expect_error(
runFalsePositiveSimulationStudy(list(), n_replicates = 1),
"bifrost_simulation_template"
)
testthat::expect_error(
runFalsePositiveSimulationStudy(tmpl, n_replicates = 0),
"n_replicates"
)
testthat::expect_error(
runFalsePositiveSimulationStudy(tmpl, n_replicates = 1.5),
"n_replicates"
)
testthat::expect_error(
runFalsePositiveSimulationStudy(tmpl, n_replicates = 1, tree_tip_count = 3.5),
"tree_tip_count"
)
testthat::expect_error(
runFalsePositiveSimulationStudy(tmpl, n_replicates = 1, tree_tip_count = tmpl$n_tips + 1L),
"tree_tip_count cannot exceed"
)
testthat::expect_error(
runFalsePositiveSimulationStudy(tmpl, n_replicates = 1, num_cores = 0),
"num_cores"
)
testthat::expect_error(
runFalsePositiveSimulationStudy(tmpl, n_replicates = 1, num_cores = 1.5),
"num_cores"
)
testthat::expect_error(
runFalsePositiveSimulationStudy(tmpl, n_replicates = 1, seed = 1.5),
"seed"
)
testthat::expect_error(
runFalsePositiveSimulationStudy(tmpl, n_replicates = 1, simulation_options = 1),
"must both be lists"
)
study <- runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 1,
search_options = list(
formula = "trait_data ~ 1",
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC",
method = "LL"
),
num_cores = 1,
seed = 33
)
testthat::expect_true(isTRUE(study$search_options$error))
})
test_that("runFalsePositiveSimulationStudy restores the caller RNG state when seeded", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
tmpl <- make_fp_template()
local_rebind(
"simulateNullDataset",
function(template, tree_tip_count = NULL, ...) {
stats::rnorm(1)
list(
tree = template$baseline_tree,
data = template$trait_data
)
},
environment(runFalsePositiveSimulationStudy)
)
local_rebind(
"searchOptimalConfiguration",
function(...) {
stats::rnorm(1)
list(
shift_nodes_no_uncertainty = integer(0),
num_candidates = 3L,
ic_weights = data.frame()
)
},
environment(runFalsePositiveSimulationStudy)
)
expect_global_rng_restored(
runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 2,
tree_tip_count = 18,
search_options = list(
formula = "trait_data ~ 1",
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC",
method = "LL"
),
num_cores = 1,
seed = 6
)
)
})
test_that("runFalsePositiveSimulationStudy inherits evaluated template settings", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
set.seed(36)
tr <- ape::rtree(18)
X <- matrix(rnorm(18 * 2), ncol = 2)
rownames(X) <- tr$tip.label
method_value <- "LL"
error_value <- TRUE
tmpl <- createSimulationTemplate(
baseline_tree = tr,
trait_data = X,
formula = "trait_data ~ 1",
method = method_value,
error = error_value
)
study <- runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 1,
search_options = list(
formula = "trait_data ~ 1",
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC"
),
num_cores = 1,
seed = 37
)
testthat::expect_identical(study$search_options$method, "LL")
testthat::expect_true(isTRUE(study$search_options$error))
testthat::expect_identical(study$per_replicate$status, "ok")
})
test_that("runFalsePositiveSimulationStudy falls back to template call settings when stored values are missing", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
method_value <- "LL"
tmpl <- make_fp_template_with_error()
tmpl$fit_method <- NULL
tmpl$fit_error <- NULL
tmpl$global_model$call$method <- method_value
tmpl$global_model$call$error <- quote(TRUE)
tmpl$search_formula <- NULL
study <- runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 1,
search_options = list(
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC"
),
num_cores = 1,
seed = 39
)
testthat::expect_identical(study$search_options$formula, "trait_data ~ 1")
testthat::expect_identical(study$search_options$method, "LL")
testthat::expect_true(isTRUE(study$search_options$error))
})
test_that("runFalsePositiveSimulationStudy tolerates unevaluable template error calls", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
tmpl <- make_fp_template()
tmpl$fit_method <- NULL
tmpl$fit_error <- NULL
tmpl$global_model$call$method <- "LL"
tmpl$global_model$call$error <- quote(missing_error_flag)
tmpl$search_formula <- NULL
study <- runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 1,
search_options = list(
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC"
),
num_cores = 1,
seed = 40
)
testthat::expect_false("error" %in% names(study$search_options))
testthat::expect_identical(study$per_replicate$status, "ok")
})
test_that("runFalsePositiveSimulationStudy is reproducible with the same seed and workers", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
testthat::skip_on_covr()
tmpl <- make_fp_template()
run_once <- function() {
runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 2,
tree_tip_count = 18,
search_options = list(
formula = "trait_data ~ 1",
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC",
method = "LL"
),
num_cores = 2,
seed = 6
)
}
study_a <- run_once()
study_b <- run_once()
testthat::expect_identical(study_a$per_replicate, study_b$per_replicate)
testthat::expect_true(all(vapply(seq_along(study_a$simdata), function(i) {
isTRUE(all.equal(study_a$simdata[[i]]$data, study_b$simdata[[i]]$data))
}, logical(1))))
testthat::expect_identical(
lapply(study_a$results, `[[`, "shift_nodes_no_uncertainty"),
lapply(study_b$results, `[[`, "shift_nodes_no_uncertainty")
)
})
test_that("runFalsePositiveSimulationStudy gives seeded draws independent of worker count", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
testthat::skip_on_covr()
tmpl <- make_fp_template()
local_rebind(
"simulateNullDataset",
function(template, tree_tip_count = NULL, ...) {
draw <- stats::rnorm(1)
list(
tree = template$baseline_tree,
data = template$trait_data,
random_draw = draw
)
},
environment(runFalsePositiveSimulationStudy)
)
local_rebind(
"searchOptimalConfiguration",
function(...) {
list(
shift_nodes_no_uncertainty = integer(0),
num_candidates = 3L,
ic_weights = data.frame(),
random_draw = stats::rnorm(1)
)
},
environment(runFalsePositiveSimulationStudy)
)
withr::local_envvar(c(
RSTUDIO = "1",
RSTUDIO_SESSION_INITIALIZED = "1"
))
run_once <- function(num_cores) {
runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 2,
tree_tip_count = 18,
search_options = list(
formula = "trait_data ~ 1",
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC",
method = "LL"
),
num_cores = num_cores,
seed = 606
)
}
serial <- run_once(1L)
multisession <- run_once(2L)
testthat::expect_identical(
vapply(serial$simdata, `[[`, numeric(1), "random_draw"),
vapply(multisession$simdata, `[[`, numeric(1), "random_draw")
)
testthat::expect_identical(
vapply(serial$results, `[[`, numeric(1), "random_draw"),
vapply(multisession$results, `[[`, numeric(1), "random_draw")
)
})
test_that("runFalsePositiveSimulationStudy makes outer parallelism override inner cores", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
tmpl <- make_fp_template()
testthat::local_mocked_bindings(
future_lapply = serial_future_lapply,
.package = "future.apply"
)
testthat::local_mocked_bindings(
plan = function(...) list(),
.package = "future"
)
testthat::expect_warning(
study <- runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 1,
search_options = list(
formula = "trait_data ~ 1",
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 2,
IC = "GIC",
method = "LL"
),
num_cores = 2,
seed = 34
),
"forcing each search to use one core"
)
testthat::expect_identical(study$search_options$num_cores, 1L)
})
test_that("runFalsePositiveSimulationStudy does not capture simdata in future workers", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
worker_environments <- list()
testthat::local_mocked_bindings(
future_lapply = function(X, FUN, ...) {
worker_environments[[length(worker_environments) + 1L]] <<- environment(FUN)
serial_future_lapply(X, FUN, ...)
},
.package = "future.apply"
)
testthat::local_mocked_bindings(
plan = function(...) list(),
.package = "future"
)
local_rebind(
"searchOptimalConfiguration",
function(...) {
list(
shift_nodes_no_uncertainty = integer(0),
num_candidates = 3L,
ic_weights = data.frame()
)
},
environment(runFalsePositiveSimulationStudy)
)
runFalsePositiveSimulationStudy(
make_fp_template(),
n_replicates = 1,
tree_tip_count = 18,
search_options = list(
formula = "trait_data ~ 1",
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC",
method = "LL"
),
num_cores = 2,
seed = 54
)
testthat::expect_length(worker_environments, 1L)
testthat::expect_false(any(vapply(worker_environments, function(worker_env) {
exists("simdata", envir = worker_env, inherits = FALSE)
}, logical(1L))))
})
test_that("runFalsePositiveSimulationStudy validates formula types and can choose multisession plans", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
tmpl <- make_fp_template()
testthat::expect_error(
runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 1,
search_options = list(
formula = 1,
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC"
),
num_cores = 1,
seed = 41
),
simulationStudyFormulaErrors$invalid_type
)
plans <- list()
old_rstudio <- Sys.getenv("RSTUDIO", unset = NA_character_)
old_rstudio_init <- Sys.getenv("RSTUDIO_SESSION_INITIALIZED", unset = NA_character_)
Sys.setenv(RSTUDIO = "1", RSTUDIO_SESSION_INITIALIZED = "1")
on.exit({
if (is.na(old_rstudio)) Sys.unsetenv("RSTUDIO") else Sys.setenv(RSTUDIO = old_rstudio)
if (is.na(old_rstudio_init)) Sys.unsetenv("RSTUDIO_SESSION_INITIALIZED") else Sys.setenv(RSTUDIO_SESSION_INITIALIZED = old_rstudio_init)
}, add = TRUE)
testthat::local_mocked_bindings(
future_lapply = serial_future_lapply,
.package = "future.apply"
)
testthat::local_mocked_bindings(
plan = function(strategy, workers = NULL, ...) {
if (missing(strategy)) {
return("old_plan")
}
plans[[length(plans) + 1L]] <<- list(strategy = strategy, workers = workers)
invisible("mock_plan")
},
.package = "future"
)
runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 1,
search_options = list(
formula = "trait_data ~ 1",
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC",
method = "LL"
),
num_cores = 2,
seed = 42
)
testthat::expect_true(any(vapply(plans, function(x) identical(x$strategy, future::multisession), logical(1))))
})
test_that("runFalsePositiveSimulationStudy accepts formula objects in search options", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
tmpl <- make_fp_template()
study <- runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 1,
search_options = list(
formula = simulationStudyFormulaCases$formula,
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC",
method = "LL"
),
num_cores = 1,
seed = 43
)
testthat::expect_s3_class(study$search_options$formula, "formula")
testthat::expect_identical(
study$search_options$formula,
simulationStudyFormulaCases$formula
)
testthat::expect_identical(study$per_replicate$status, "ok")
})
test_that("runFalsePositiveSimulationStudy records search fallback errors", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
tmpl <- make_fp_template()
study <- runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 1,
search_options = list(
formula = "trait_data ~ 1",
min_descendant_tips = 3,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "BAD",
method = "LL"
),
num_cores = 1,
seed = 35
)
testthat::expect_identical(study$per_replicate$status, "error")
testthat::expect_match(study$per_replicate$error, "IC must be GIC or BIC")
testthat::expect_true(is.na(study$per_replicate$n_inferred_shifts))
testthat::expect_true(is.na(study$per_replicate$false_positive_rate))
testthat::expect_identical(study$study_summary$n_completed, 0L)
testthat::expect_identical(study$study_summary$n_failed, 1L)
testthat::expect_identical(study$study_summary$n_evaluable_replicates, 0L)
testthat::expect_equal(study$study_summary$completion_rate, 0)
testthat::expect_equal(study$study_summary$failure_rate, 1)
testthat::expect_true(is.na(study$study_summary$mean_false_positive_rate))
testthat::expect_true(is.na(study$study_summary$median_false_positive_rate))
testthat::expect_equal(
study$results[[1]]$num_candidates,
max(length(generatePaintedTrees(ape::as.phylo(study$simdata[[1]]$tree), min_tips = 3)) - 1L, 0L)
)
})
test_that("runFalsePositiveSimulationStudy reports NA summaries when no replicate is evaluable", {
testthat::skip_on_cran()
skip_if_fp_study_deps()
tmpl <- make_fp_template()
study <- runFalsePositiveSimulationStudy(
tmpl,
n_replicates = 1,
search_options = list(
formula = "trait_data ~ 1",
min_descendant_tips = 100,
shift_acceptance_threshold = 5,
num_cores = 1,
IC = "GIC",
method = "LL"
),
num_cores = 1,
seed = 38
)
testthat::expect_equal(study$per_replicate$n_candidates, 0)
testthat::expect_true(is.na(study$per_replicate$false_positive_rate))
testthat::expect_identical(study$study_summary$n_evaluable_replicates, 0L)
testthat::expect_true(is.na(study$study_summary$mean_false_positive_rate))
testthat::expect_true(is.na(study$study_summary$median_false_positive_rate))
})
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.