test_that("run_kronx works on a small numeric return series", { skip_on_cran() set.seed(123) x <- rnorm(120, mean = 0, sd = 0.01) res <- run_kronx( x = x, K = 2L, n_starts = 1L, max_iter = 10L, tol = 1e-4, tail_alpha = 0.05, ruin_horizon = 25L, verbose = FALSE, output_dir = NULL ) expect_type(res, "list") expect_named( res, c( "close_px", "ret", "K", "gauss_fit", "t_fit", "A_gauss", "A_t", "epsilon", "Q", "K_mat", "N_mat", "pi_qs", "pi_res", "loss_threshold", "q_state", "bar_q", "bar_lambda", "ruin_bound", "tail_alpha", "ruin_horizon", "state_summary", "vpath_t", "output_files", "input_source" ), ignore.order = TRUE ) expect_null(res$close_px) expect_equal(res$K, 2L) expect_equal(length(res$ret), length(x)) expect_identical(res$output_files, NULL) expect_identical(res$input_source, "supplied numeric return series") }) test_that("run_kronx returns matrices and vectors with consistent dimensions", { skip_on_cran() set.seed(456) x <- rnorm(150, mean = 0, sd = 0.012) res <- run_kronx( x = x, K = 2L, n_starts = 1L, max_iter = 10L, tol = 1e-4, tail_alpha = 0.05, ruin_horizon = 20L, verbose = FALSE, output_dir = NULL ) expect_equal(dim(res$A_gauss), c(2L, 2L)) expect_equal(dim(res$A_t), c(2L, 2L)) expect_equal(dim(res$Q), c(2L, 2L)) expect_equal(dim(res$K_mat), c(2L, 2L)) expect_equal(dim(res$N_mat), c(2L, 2L)) expect_length(res$epsilon, 2L) expect_length(res$pi_qs, 2L) expect_length(res$pi_res, 2L) expect_length(res$q_state, 2L) expect_length(res$vpath_t, length(x)) expect_true(is.data.frame(res$state_summary)) expect_equal(nrow(res$state_summary), 2L) }) test_that("run_kronx returns finite scalar risk summaries", { skip_on_cran() set.seed(789) x <- rnorm(100, mean = 0, sd = 0.01) res <- run_kronx( x = x, K = 2L, n_starts = 1L, max_iter = 8L, tol = 1e-4, tail_alpha = 0.05, ruin_horizon = 15L, verbose = FALSE, output_dir = NULL ) expect_true(is.numeric(res$loss_threshold)) expect_true(length(res$loss_threshold) == 1L) expect_true(is.finite(res$loss_threshold)) expect_true(is.numeric(res$bar_q)) expect_true(length(res$bar_q) == 1L) expect_true(is.finite(res$bar_q)) expect_gte(res$bar_q, 0) expect_true(is.numeric(res$bar_lambda)) expect_true(length(res$bar_lambda) == 1L) expect_true(is.finite(res$bar_lambda)) expect_gte(res$bar_lambda, 0) expect_true(is.numeric(res$ruin_bound)) expect_true(length(res$ruin_bound) == 1L) expect_true(is.finite(res$ruin_bound)) expect_gte(res$ruin_bound, 0) expect_lte(res$ruin_bound, 1) }) test_that("run_kronx returns probability-like weights that sum to one", { skip_on_cran() set.seed(321) x <- rnorm(120, mean = 0, sd = 0.009) res <- run_kronx( x = x, K = 2L, n_starts = 1L, max_iter = 10L, tol = 1e-4, tail_alpha = 0.05, ruin_horizon = 25L, verbose = FALSE, output_dir = NULL ) expect_equal(sum(res$pi_qs), 1, tolerance = 1e-6) expect_equal(sum(res$pi_res), 1, tolerance = 1e-6) expect_true(all(is.finite(res$pi_qs))) expect_true(all(is.finite(res$pi_res))) expect_true(all(res$pi_qs >= 0)) expect_true(all(res$pi_res >= 0)) }) test_that("run_kronx rejects missing inputs", { expect_error( run_kronx(verbose = FALSE, output_dir = NULL), "Provide either 'file' or 'x'" ) }) test_that("run_kronx rejects too-short numeric input", { expect_error( run_kronx( x = c(0.01, -0.02, 0.03), verbose = FALSE, output_dir = NULL ), "at least 10" ) }) test_that("run_kronx rejects invalid tail_alpha", { set.seed(111) x <- rnorm(50, 0, 0.01) expect_error( run_kronx( x = x, tail_alpha = 1, verbose = FALSE, output_dir = NULL ), "tail_alpha" ) expect_error( run_kronx( x = x, tail_alpha = 0, verbose = FALSE, output_dir = NULL ), "tail_alpha" ) }) test_that("run_kronx can write outputs when requested", { skip_on_cran() set.seed(222) x <- rnorm(100, mean = 0, sd = 0.01) outdir <- file.path(tempdir(), "kronx_test_output") if (dir.exists(outdir)) { unlink(outdir, recursive = TRUE, force = TRUE) } res <- run_kronx( x = x, K = 2L, n_starts = 1L, max_iter = 8L, tol = 1e-4, tail_alpha = 0.05, ruin_horizon = 20L, verbose = FALSE, output_dir = outdir ) expect_true(dir.exists(outdir)) expect_true(is.character(res$output_files)) expect_true(length(res$output_files) >= 1L) expect_true(all(file.exists(res$output_files))) unlink(outdir, recursive = TRUE, force = TRUE) })