Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
1e10511
Moved to 3e and removed context calls
VisruthSK Mar 24, 2026
5115c34
LLMd testthat 3e syntax changes
VisruthSK Mar 24, 2026
a91cff8
Tweak some minor testing things
VisruthSK Mar 24, 2026
c98740e
Fixed tests
VisruthSK Mar 24, 2026
e1399ba
Refresh test binaries
VisruthSK Mar 24, 2026
ce5f289
Use withr for tests
VisruthSK Mar 24, 2026
2970907
Fix LF issue in tests
VisruthSK Mar 25, 2026
a46a125
Using more withr and testthat 3e features; setting up parallelization…
VisruthSK Mar 25, 2026
e5e7de5
Stabilize parallel test runs
VisruthSK Mar 25, 2026
c66a807
Avoid pak local install in CI
VisruthSK Mar 25, 2026
e2d2e5f
Serialize test model compilation
VisruthSK Mar 25, 2026
8d926bb
Run stateful tests sequentially
VisruthSK Mar 25, 2026
6797833
Stabilize OpenCL test
VisruthSK Mar 25, 2026
86bfac6
Trim unstable OpenCL checks
VisruthSK Mar 25, 2026
29d75db
Run threaded tests sequentially
VisruthSK Mar 25, 2026
1366910
Simplify test harness
VisruthSK Mar 25, 2026
773ca2b
Use repo pak on macOS devel
VisruthSK Mar 25, 2026
159335c
Use devel pak on macOS devel
VisruthSK Mar 25, 2026
dfaee86
Install local package outside pak on macOS devel
VisruthSK Mar 25, 2026
09c3fcd
No parallel tests
VisruthSK Mar 25, 2026
6a01a93
Cleaning tests up; more snapshots
VisruthSK Mar 25, 2026
faf24a8
More snapshots
VisruthSK Mar 25, 2026
08ef444
Small changes
VisruthSK Mar 25, 2026
b7cb687
Bump testthat requirement
VisruthSK Mar 25, 2026
e55042f
Removed brittle snapshots
VisruthSK Mar 25, 2026
d684bc3
Transform windows snapshots to remove .exe
VisruthSK Mar 26, 2026
d0348c6
More snapshots
VisruthSK Mar 26, 2026
8e83d74
Revert function
VisruthSK Mar 31, 2026
9431bca
Removed snapshots
VisruthSK Mar 31, 2026
5618ad8
Fix a test regression
VisruthSK Mar 31, 2026
6673e38
expect_known_output was deprecated so swapping those to equivalent snaps
VisruthSK Mar 31, 2026
4d5b9aa
Deleted obviated answers directory
VisruthSK Mar 31, 2026
f7868cc
Use more withr functions to not rely on on.exit()
VisruthSK Mar 31, 2026
4753a71
Cleaned up teardown
VisruthSK Apr 2, 2026
4270f68
Added silent assertion in test
VisruthSK Apr 2, 2026
d066c70
Bumped jsonlite version
VisruthSK Apr 2, 2026
e010022
Test cleanup
VisruthSK Apr 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Depends:
Imports:
checkmate,
data.table,
jsonlite (>= 1.2.0),
jsonlite (>= 1.8.7),
posterior (>= 1.5.0),
processx (>= 3.5.0),
R6 (>= 2.4.0),
Expand All @@ -55,6 +55,7 @@ Suggests:
loo (>= 2.0.0),
qs2,
rmarkdown,
testthat (>= 2.1.0),
testthat (>= 3.3.0),
Rcpp
VignetteBuilder: knitr
Config/testthat/edition: 3
21 changes: 21 additions & 0 deletions tests/testthat/_snaps/model-code-print.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# code() and print() methods work

data {
int<lower=0> N;
array[N] int<lower=0, upper=1> y;
}
parameters {
real<lower=0, upper=1> theta;
}
model {
theta ~ beta(1, 1); // uniform prior on interval 0,1
y ~ bernoulli(theta);
}

---

c("data {", " int<lower=0> N;", " array[N] int<lower=0, upper=1> y;",
"}", "parameters {", " real<lower=0, upper=1> theta;", "}",
"model {", " theta ~ beta(1, 1); // uniform prior on interval 0,1",
" y ~ bernoulli(theta);", "}")

Binary file removed tests/testthat/answers/model-code-output.rds
Binary file not shown.
11 changes: 0 additions & 11 deletions tests/testthat/answers/model-print-output.stan

This file was deleted.

29 changes: 24 additions & 5 deletions tests/testthat/helper-custom-expectations.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ expect_compilation <- function(mod, ...) {
}
if(!is.null(before_mtime)) {
after_mtime <- file.mtime(mod$exe_file())
expect(before_mtime != after_mtime, sprintf("Exe file '%s' has NOT changed, despite expecting (re)compilation", mod$exe_file()))
expect_gt(
after_mtime,
before_mtime,
sprintf("Exe file '%s' has NOT changed, despite expecting (re)compilation", mod$exe_file())
)
}
invisible(mod)
}
Expand All @@ -26,7 +30,11 @@ expect_call_compilation <- function(constructor_call) {
fail(sprint("Model executable '%s' does not exist after compilation.", mod$exe_file()))
}
after_mtime <- file.mtime(mod$exe_file())
expect(before_time <= after_mtime, sprintf("Exe file '%s' has old timestamp, despite expecting (re)compilation", mod$exe_file()))
expect_gt(
after_mtime,
before_time,
sprintf("Exe file '%s' has old timestamp, despite expecting (re)compilation", mod$exe_file())
)
invisible(mod)
}

Expand All @@ -40,7 +48,7 @@ expect_no_recompilation <- function(mod, ...) {
before_mtime <- file.mtime(mod$exe_file())
expect_interactive_message(mod$compile(...), "Model executable is up to date!")
after_mtime <- file.mtime(mod$exe_file())
expect(before_mtime == after_mtime, sprintf("Model executable '%s' has changed, despite expecting no recompilation", mod$exe_file()))
expect_true(before_mtime == after_mtime, sprintf("Model executable '%s' has changed, despite expecting no recompilation", mod$exe_file()))
invisible(mod)
}

Expand Down Expand Up @@ -92,8 +100,19 @@ expect_gq_output <- function(object, num_chains = NULL) {
}

expect_interactive_message <- function(object, regexp = NULL) {
rlang::with_interactive(value = TRUE,
expect_message(object = object, regexp = regexp))
object <- substitute(object)
env <- parent.frame()
value <- NULL
rlang::with_interactive(value = TRUE, {
expect_message(
object = {
value <- rlang::eval_bare(object, env)
value
},
regexp = regexp
)
})
invisible(value)
}

expect_noninteractive_silent <- function(object) {
Expand Down
10 changes: 7 additions & 3 deletions tests/testthat/helper-mock-cli.R
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
real_wcr <- wsl_compatible_run

with_mocked_cli <- function(code, compile_ret, info_ret) {
with_mocked_bindings(
code,
code <- substitute(code)
caller <- parent.frame()
local_mocked_bindings(
wsl_compatible_run = function(command, args, ...) {
if (
!is.null(command)
Expand All @@ -17,8 +18,11 @@ with_mocked_cli <- function(code, compile_ret, info_ret) {
} else {
real_wcr(command = command, args = args, ...)
}
}
},
.package = "cmdstanr",
.env = caller
)
rlang::eval_bare(code, env = caller)
}

######## Mock Compile Expectations #######
Expand Down
17 changes: 17 additions & 0 deletions tests/testthat/setup.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
cleanup_stan_artifacts <- function() {
all_files_in_stan <- list.files(
test_path("resources", "stan"),
full.names = TRUE,
recursive = TRUE
)
files_to_remove <- all_files_in_stan[!grepl("\\.stan$", all_files_in_stan)]

if (length(files_to_remove) > 0) {
unlink(files_to_remove, force = TRUE)
}

invisible(files_to_remove)
}

cleanup_stan_artifacts()
withr::defer(cleanup_stan_artifacts(), testthat::teardown_env())
8 changes: 0 additions & 8 deletions tests/testthat/teardown-remove-files.R

This file was deleted.

7 changes: 3 additions & 4 deletions tests/testthat/test-csv.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
context("read_cmdstan_csv")

set_cmdstan_path()
fit_bernoulli_optimize <- testing_fit("bernoulli", method = "optimize", seed = 1234)
fit_bernoulli_variational <- testing_fit("bernoulli", method = "variational", seed = 123)
Expand Down Expand Up @@ -519,9 +517,10 @@ test_that("returning time works for read_cmdstan_csv", {

test_that("time from read_cmdstan_csv matches time from fit$time()", {
fit <- fit_bernoulli_thin_1
expect_equivalent(
expect_equal(
read_cmdstan_csv(fit$output_files())$time$chains,
fit$time()$chains
fit$time()$chains,
ignore_attr = TRUE
)
})

Expand Down
2 changes: 0 additions & 2 deletions tests/testthat/test-data.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
context("data-utils")

set_cmdstan_path()
fit <- testing_fit("bernoulli", method = "sample", seed = 123)
fit_vb <- testing_fit("bernoulli", method = "variational", seed = 123)
Expand Down
60 changes: 23 additions & 37 deletions tests/testthat/test-example.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
context("cmdstanr_example")
stan_program <- "
data {
int<lower=0> N;
array[N] int<lower=0,upper=1> y;
}
parameters {
real<lower=0,upper=1> theta;
}
model {
y ~ bernoulli(theta);
}
"

test_that("cmdstanr_example works", {
fit_mcmc <- cmdstanr_example("logistic", chains = 2, force_recompile = TRUE)
Expand All @@ -13,26 +24,10 @@ test_that("cmdstanr_example works", {

fit_vb <- cmdstanr_example("logistic", method = "variational")
checkmate::expect_r6(fit_vb, "CmdStanVB")

expect_output(print_example_program("schools"), "vector[J] theta", fixed=TRUE)
expect_output(print_example_program("schools_ncp"), "vector[J] theta_raw", fixed=TRUE)
})


# used in multiple tests below
stan_program <- "
data {
int<lower=0> N;
array[N] int<lower=0,upper=1> y;
}
parameters {
real<lower=0,upper=1> theta;
}
model {
y ~ bernoulli(theta);
}
"

test_that("write_stan_file writes Stan file correctly", {
skip_if_not_installed("rlang")
f1 <- write_stan_file(stan_program)
Expand All @@ -47,17 +42,16 @@ test_that("write_stan_file writes Stan file correctly", {
})

test_that("write_stan_file writes to specified directory and filename", {
dir <- file.path(test_path(), "answers")
dir <- withr::local_tempdir()
explicit_dir <- withr::local_tempdir()
expect_equal(dirname(f1 <- write_stan_file(stan_program, dir = dir, basename = "pasta")),
absolute_path(dir))
expect_equal(f2 <- write_stan_file(stan_program, dir = dir, basename = "fruit.stan"),
absolute_path(file.path(dir, "fruit.stan")))
expect_equal(f3 <- write_stan_file(stan_program, dir = dir, basename = "vegetable"),
absolute_path(file.path(dir, "vegetable.stan"))) # should add .stan extension if missing
expect_equal(f4 <- write_stan_file(stan_program, dir = tempdir(), basename = "test"),
absolute_path(file.path(tempdir(), "test.stan")))

try(file.remove(f1, f2, f3, f4), silent = TRUE)
expect_equal(f4 <- write_stan_file(stan_program, dir = explicit_dir, basename = "test"),
absolute_path(file.path(explicit_dir, "test.stan")))
})

test_that("write_stan_file creates dir if necessary", {
Expand All @@ -69,7 +63,7 @@ test_that("write_stan_file creates dir if necessary", {

test_that("write_stan_file by default creates the same file for the same Stan model", {
skip_if_not_installed("rlang")
dir <- file.path(test_path(), "answers")
dir <- withr::local_tempdir()

f1 <- write_stan_file(stan_program, dir = dir)
mtime1 <- file.info(f1)$mtime
Expand All @@ -95,24 +89,16 @@ test_that("write_stan_file by default creates the same file for the same Stan mo

mtime5 <- file.info(f5)$mtime
expect_true(mtime1 < mtime5)


try(file.remove(f1, f2, f4), silent = TRUE)
})

test_that("cmdstanr_write_stan_file_dir option works", {
base_dir <- tempdir()
test_dir <- file.path(base_dir, "option_test")
if (!dir.exists(test_dir)) {
dir.create(test_dir)
}
options("cmdstanr_write_stan_file_dir" = test_dir)
file <- write_stan_file(stan_program)
expect_equal(repair_path(dirname(file)), repair_path(test_dir))
options("cmdstanr_write_stan_file_dir" = NULL)
test_dir <- withr::local_tempdir(pattern = "option_test")
local({
withr::local_options(list("cmdstanr_write_stan_file_dir" = test_dir))
file <- write_stan_file(stan_program)
expect_equal(repair_path(dirname(file)), repair_path(test_dir))
})
file <- write_stan_file(stan_program)
expect_equal(repair_path(dirname(file)), repair_path(base_dir))
if (!dir.exists(test_dir)) {
file.remove(test_dir)
}
})
1 change: 0 additions & 1 deletion tests/testthat/test-failed-chains.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
context("failed chains")
set_cmdstan_path()
stan_program <- testing_stan_file("chain_fails")
stan_program_init_warnings <- testing_stan_file("init_warnings")
Expand Down
4 changes: 1 addition & 3 deletions tests/testthat/test-fit-gq.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
context("fitted-gq")

set_cmdstan_path()
fit <- testing_fit("bernoulli", method = "sample", seed = 123)
fit_gq <- testing_fit("bernoulli_ppc", method = "generate_quantities", seed = 123, fitted_params = fit)
Expand Down Expand Up @@ -78,7 +76,7 @@ test_that("print() method works after gq", {
fit_gq$print(variable = "unknown", max_rows = 20),
"Can't find the following variable(s): unknown",
fixed = TRUE
) # unknown parameter
)

out <- capture.output(fit_gq$print("y_rep"))
expect_length(out, 11) # columns names + 1 y_rep
Expand Down
1 change: 0 additions & 1 deletion tests/testthat/test-fit-init.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
context("fitted-inits")
set_cmdstan_path()

data_list_schools <- testing_data("schools")
Expand Down
2 changes: 0 additions & 2 deletions tests/testthat/test-fit-laplace.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
context("fitted-laplace")

set_cmdstan_path()
fit_laplace <- testing_fit("logistic", method = "laplace", seed = 100)
PARAM_NAMES <- c("alpha", "beta[1]", "beta[2]", "beta[3]")
Expand Down
17 changes: 6 additions & 11 deletions tests/testthat/test-fit-mcmc.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
context("fitted-mcmc")

set_cmdstan_path()
fit_mcmc <- testing_fit("logistic", method = "sample",
seed = 123, chains = 2)
Expand Down Expand Up @@ -139,7 +137,7 @@ test_that("print() method works after mcmc", {
fit$print(variable = "unknown", max_rows = 20),
"Can't find the following variable(s): unknown",
fixed = TRUE
) # unknown parameter
)

out <- capture.output(fit$print("theta"))
expect_length(out, 9) # columns names + 8 thetas
Expand Down Expand Up @@ -331,23 +329,20 @@ test_that("loo works for all draws storage formats", {
skip_if_not_installed("loo")
fit <- testing_fit("bernoulli_log_lik")

options(cmdstanr_draws_format = "draws_array")
withr::local_options(list(cmdstanr_draws_format = "draws_array"))
expect_s3_class(suppressWarnings(fit$loo()), "loo")

options(cmdstanr_draws_format = "draws_df")
withr::local_options(list(cmdstanr_draws_format = "draws_df"))
expect_s3_class(suppressWarnings(fit$loo()), "loo")

options(cmdstanr_draws_format = "draws_matrix")
withr::local_options(list(cmdstanr_draws_format = "draws_matrix"))
expect_s3_class(suppressWarnings(fit$loo()), "loo")

options(cmdstanr_draws_format = "draws_list")
withr::local_options(list(cmdstanr_draws_format = "draws_list"))
expect_s3_class(suppressWarnings(fit$loo()), "loo")

options(cmdstanr_draws_format = "draws_rvars")
withr::local_options(list(cmdstanr_draws_format = "draws_rvars"))
expect_s3_class(suppressWarnings(fit$loo()), "loo")

# reset option
options(cmdstanr_draws_format = NULL)
})

test_that("draws() works for different formats", {
Expand Down
2 changes: 0 additions & 2 deletions tests/testthat/test-fit-mle.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
context("fitted-mle")

set_cmdstan_path()
fit_mle <- testing_fit("logistic", method = "optimize", seed = 123)
mod <- testing_model("bernoulli")
Expand Down
2 changes: 0 additions & 2 deletions tests/testthat/test-fit-shared.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
context("fitted-shared-methods")

set_cmdstan_path()
fits <- list()
fits[["sample"]] <- testing_fit("logistic", method = "sample",
Expand Down
2 changes: 0 additions & 2 deletions tests/testthat/test-fit-vb.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
context("fitted-vb")

set_cmdstan_path()
fit_vb <- testing_fit("logistic", method = "variational", seed = 123)
fit_vb_sci_not <- testing_fit("logistic", method = "variational", seed = 123, iter = 200000, adapt_iter = 100000)
Expand Down
Loading
Loading