Nothing
# tests/testthat/test-xi_acf.R
test_that("xi_acf function works and returns correct structure", {
# Generate synthetic data
set.seed(42)
x <- rnorm(100)
max_lag <- 10
n_surr <- 10
# Execute the main function
res <- xiacf::xi_acf(x, max_lag = max_lag, n_surr = n_surr)
# Verify the returned S3 class
expect_s3_class(res, "xi_acf")
expect_equal(res$max_lag, max_lag)
expect_equal(res$n_surr, n_surr)
expect_equal(res$n, length(x))
# Verify the structure and contents of the data frame
expect_true("data.frame" %in% class(res$data))
expected_cols <- c("Lag", "ACF", "Xi", "Xi_Threshold", "ACF_CI", "Xi_Excess")
expect_true(all(expected_cols %in% names(res$data)))
expect_equal(nrow(res$data), max_lag)
})
test_that("xi_acf handles input errors gracefully", {
# Edge case 1: Time series is too short
expect_error(xiacf::xi_acf(c(1, 2, 3)), "too short")
# Edge case 2: Constant series (zero variance)
expect_error(xiacf::xi_acf(rep(1, 100)), "zero variance")
# Edge case 3: Handling of NA values (should throw an error)
x_na <- c(rnorm(10), NA)
expect_error(
xiacf::xi_acf(x_na, max_lag = 5, n_surr = 5),
"NA values"
)
})
test_that("xi_test wrapper throws deprecation warning but returns xi_acf object", {
set.seed(42)
x <- rnorm(100)
# Verify that the wrapper function throws a deprecation warning and returns the correct object type
expect_warning(
res <- xiacf::xi_test(x, max_lag = 5, n_surr = 5),
"deprecated"
)
expect_s3_class(res, "xi_acf")
})
test_that("print method produces correct output", {
x <- rnorm(50)
res <- xiacf::xi_acf(x, max_lag = 5, n_surr = 5)
# Capture the output of the print method
out <- capture.output(print(res))
# Verify that specific keywords are present in the console output
expect_true(any(grepl("Chatterjee's Xi-ACF Test", out)))
expect_true(any(grepl("Data length:", out)))
})
test_that("autoplot.xi_acf returns a ggplot object", {
set.seed(42)
x <- rnorm(100)
res <- xiacf::xi_acf(x, max_lag = 5, n_surr = 5)
# Verify that autoplot.xi_acf returns a ggplot object
p <- ggplot2::autoplot(res)
expect_s3_class(p, "ggplot")
})
test_that("run_rolling_xi_analysis works with sequential execution and time_index", {
# Test with a small synthetic dataset
set.seed(42)
x <- rnorm(50)
dates <- seq(as.Date("2020-01-01"), by = "1 day", length.out = 50)
# Execute sequentially to keep the automated test lightweight
res_df <- xiacf::run_rolling_xi_analysis(
x = x,
time_index = dates,
window_size = 20,
step_size = 10,
max_lag = 5,
n_surr = 10,
n_cores = 1 # Avoid parallel overhead in CRAN checks
)
# Verify the type of the result
expect_s3_class(res_df, "data.frame")
expect_true("Xi_Excess" %in% names(res_df))
expect_true(nrow(res_df) > 0)
# Verify the time_index columns are properly mapped
expect_true(all(c("Window_Start_Time", "Window_End_Time") %in% names(res_df)))
expect_s3_class(res_df$Window_Start_Time, "Date")
expect_s3_class(res_df$Window_End_Time, "Date")
})
test_that("run_rolling_xi_analysis handles invalid time_index correctly", {
set.seed(42)
x <- rnorm(50)
dates_short <- seq(as.Date("2020-01-01"), by = "1 day", length.out = 30)
# When lengths differ
expect_error(
xiacf::run_rolling_xi_analysis(
x,
time_index = dates_short,
window_size = 20,
max_lag = 5
),
"exact same length"
)
})
test_that("run_rolling_xi_analysis saves and loads intermediate results correctly", {
# 1. Prepare small dummy data for quick calculation
set.seed(42)
x_test <- rnorm(100)
window_size <- 80
step_size <- 10
# This setting results in exactly 3 windows: (100 - 80) / 10 + 1 = 3
# 2. Create a temporary directory for testing
tmp_dir <- tempfile("xi_rolling_test")
dir.create(tmp_dir)
# Ensure the directory is automatically deleted after the test finishes
on.exit(unlink(tmp_dir, recursive = TRUE))
# 3. Initial run (Test if files are saved properly)
res_initial <- run_rolling_xi_analysis(
x = x_test,
window_size = window_size,
step_size = step_size,
max_lag = 2,
n_surr = 10,
n_cores = 1, # Sequential execution is sufficient for this test
save_dir = tmp_dir
)
# Check: Are exactly 3 .rds files created?
saved_files <- list.files(tmp_dir, pattern = "\\.rds$")
expect_length(saved_files, 3)
# 4. Restart run (Test if calculation is skipped when files exist)
# Intentionally overwrite the first window's file with dummy data
dummy_df <- data.frame(
Window_ID = 1,
Window_Start_Idx = 9999, # Impossible index to prove it was loaded from disk
Window_End_Idx = 9999,
Lag = 1,
Xi_Original = 1,
Xi_Threshold = 1,
Xi_Excess = 1
)
saveRDS(dummy_df, file = file.path(tmp_dir, "window_000001.rds"))
# Run again with the exact same conditions
res_restarted <- run_rolling_xi_analysis(
x = x_test,
window_size = window_size,
step_size = step_size,
max_lag = 2,
n_surr = 10,
n_cores = 1,
save_dir = tmp_dir
)
# Check: The first result should be replaced by the dummy data (proving it skipped calculation)
expect_equal(res_restarted$Window_Start_Idx[1], 9999)
# Check: The second window should be loaded normally and match the initial run
idx_win2_restarted <- res_restarted$Window_Start_Idx[
res_restarted$Window_ID == 2
][1]
idx_win2_initial <- res_initial$Window_Start_Idx[res_initial$Window_ID == 2][
1
]
expect_equal(idx_win2_restarted, idx_win2_initial)
})
test_that("sig_level dynamically adjusts thresholds and CIs", {
set.seed(42)
x <- rnorm(100)
# Compare calculations between 95% and 99% significance levels
res_95 <- xiacf::xi_acf(x, max_lag = 5, n_surr = 50, sig_level = 0.95)
res_99 <- xiacf::xi_acf(x, max_lag = 5, n_surr = 50, sig_level = 0.99)
# The ACF confidence interval should be wider (larger) for 99%
expect_gt(res_99$data$ACF_CI[1], res_95$data$ACF_CI[1])
# The surrogate thresholds should be generally higher for 99%
# Compare the means to ensure robustness against random noise
expect_gt(mean(res_99$data$Xi_Threshold), mean(res_95$data$Xi_Threshold))
})
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.