library(organik) testthat::test_that("organik returns the expected structure", { testthat::skip_on_cran() set.seed(1001) y <- 10 + cumsum(rnorm(150, sd = 0.4)) # smooth positive-ish series obj <- organik( ts = y, horizon = 3L, n_variants = 4L, n_testing = 15L, seed = 123 ) # Class and top-level fields testthat::expect_s3_class(obj, "organik") testthat::expect_true(is.list(obj$model_list)) testthat::expect_true(is.list(obj$growth_pred_funs)) testthat::expect_true(is.list(obj$level_pred_funs)) testthat::expect_true(is.matrix(obj$cor_mat)) # One predictive object per horizon; qfun works testthat::expect_equal(length(obj$growth_pred_funs), 3L) qg <- obj$growth_pred_funs[[1]]$qfun(c(0.1, 0.5, 0.9)) ql <- obj$level_pred_funs[[2]]$qfun(c(0.1, 0.5, 0.9)) testthat::expect_true(is.numeric(qg) && length(qg) == 3L && all(is.finite(qg))) testthat::expect_true(is.numeric(ql) && length(ql) == 3L && all(is.finite(ql))) }) testthat::test_that("organik path_prediction (Gaussian copula) has correct shapes and monotone quantiles", { testthat::skip_on_cran() set.seed(2002) y <- 5 + cumsum(rnorm(150, sd = 0.3)) obj <- organik( ts = y, horizon = 4L, n_variants = 3L, n_testing = 5L, seed = 42 ) path <- obj$path_prediction( n_paths = 1000L, probs = c(0.1, 0.5, 0.9), copula = "gaussian", seed = 99 ) # Shapes: paths are n_paths x horizon testthat::expect_equal(dim(path$level_paths), c(1000L, 4L)) testthat::expect_equal(dim(path$cum_growth_paths), c(1000L, 4L)) # Quantile matrices: rows = horizons, columns = q10,q50,q90 (as constructed) testthat::expect_equal(nrow(path$level_quants), 4L) testthat::expect_equal(ncol(path$level_quants), 3L) # Monotonic quantiles for each horizon for (h in seq_len(4L)) { qs <- path$level_quants[h, ] testthat::expect_true(qs[1] <= qs[2] && qs[2] <= qs[3]) } # last_level was echoed back testthat::expect_equal(path$last_level, tail(y, 1)) }) testthat::test_that("organik path_prediction works with t-copula and validates df", { testthat::skip_on_cran() set.seed(3003) y <- 7 + cumsum(rnorm(160, sd = 0.35)) obj <- organik( ts = y, horizon = 3L, n_variants = 3L, n_testing = 15L, seed = 11 ) # df must be > 1 testthat::expect_error( obj$path_prediction(n_paths = 200L, copula = "t", df = 1), "df must be > 1", fixed = TRUE ) path_t <- obj$path_prediction(n_paths = 500L, copula = "t", df = 5, seed = 202) testthat::expect_equal(path_t$copula, "t") testthat::expect_equal(path_t$df, 5) # correlation used is positive-definite (small eigenvalue > 0) ev <- eigen(path_t$cor_used, symmetric = TRUE, only.values = TRUE)$values testthat::expect_true(min(ev) > 0) }) testthat::test_that("organik is reproducible under a fixed seed", { testthat::skip_on_cran() set.seed(4004) y <- 12 + cumsum(rnorm(170, sd = 0.25)) obj1 <- organik( ts = y, horizon = 3L, n_variants = 3L, n_testing = 15L, seed = 777 ) obj2 <- organik( ts = y, horizon = 3L, n_variants = 3L, n_testing = 15L, seed = 777 ) # correlation matrices identical testthat::expect_equal(obj1$cor_mat, obj2$cor_mat, tolerance = 0) # Path summaries identical with same seed p1 <- obj1$path_prediction(n_paths = 600L, probs = c(0.05, 0.5, 0.95), seed = 999) p2 <- obj2$path_prediction(n_paths = 600L, probs = c(0.05, 0.5, 0.95), seed = 999) testthat::expect_equal(p1$level_quants, p2$level_quants, tolerance = 0) testthat::expect_equal(p1$cum_growth_quants, p2$cum_growth_quants, tolerance = 0) })