# Tests for visualization functions # Test file: tests/testthat/test-visualization.R # Skip if ggplot2 not available skip_if_not_installed("ggplot2") # Helper function generate_test_data <- function(n = 200, changepoints = 100, means = c(0, 3), sd = 1) { c(rnorm(changepoints, means[1], sd), rnorm(n - changepoints, means[2], sd)) } # ============================================================================= # Basic Plot Tests # ============================================================================= test_that("plot.regime_result returns ggplot object", { set.seed(123) data <- generate_test_data() result <- detect_regimes(data) p <- plot(result) expect_s3_class(p, "ggplot") }) test_that("plot type 'data' works", { set.seed(123) data <- generate_test_data() result <- detect_regimes(data) p <- plot(result, type = "data") expect_s3_class(p, "ggplot") }) test_that("plot type 'segments' works", { set.seed(123) data <- generate_test_data() result <- detect_regimes(data) p <- plot(result, type = "segments") expect_s3_class(p, "ggplot") }) test_that("plot type 'posterior' works for Bayesian methods", { set.seed(123) data <- generate_test_data() result <- detect_regimes(data, method = "bocpd") p <- plot(result, type = "posterior") expect_s3_class(p, "ggplot") }) test_that("plot type 'diagnostic' works for CUSUM", { set.seed(123) data <- generate_test_data() result <- detect_regimes(data, method = "cusum") p <- plot(result, type = "diagnostic") expect_s3_class(p, "ggplot") }) # ============================================================================= # Plot Options Tests # ============================================================================= test_that("show_ci option works", { set.seed(123) data <- generate_test_data() result <- detect_regimes(data, uncertainty = TRUE, bootstrap_reps = 20) p <- plot(result, show_ci = TRUE) expect_s3_class(p, "ggplot") }) test_that("show_segments option works", { set.seed(123) data <- generate_test_data() result <- detect_regimes(data) p <- plot(result, show_segments = TRUE) expect_s3_class(p, "ggplot") }) test_that("custom title works", { set.seed(123) data <- generate_test_data() result <- detect_regimes(data) p <- plot(result, title = "Custom Title") expect_s3_class(p, "ggplot") # Check title is in the plot expect_true(grepl("Custom", p$labels$title)) }) # ============================================================================= # Run Length Plot Tests # ============================================================================= test_that("plot type 'runlength' works for BOCPD", { set.seed(123) data <- generate_test_data() result <- detect_regimes(data, method = "bocpd") p <- plot(result, type = "runlength") expect_s3_class(p, "ggplot") }) # ============================================================================= # Summary Plot Tests # ============================================================================= test_that("plot_summary creates multi-panel plot", { skip_if_not_installed("patchwork") set.seed(123) data <- generate_test_data() result <- detect_regimes(data, method = "bocpd") p <- plot_summary(result) expect_s3_class(p, c("patchwork", "ggplot")) }) # ============================================================================= # Comparison Plot Tests # ============================================================================= test_that("plot_compare works", { set.seed(123) data <- generate_test_data() result1 <- detect_regimes(data, method = "pelt") result2 <- detect_regimes(data, method = "binseg") p <- plot_compare(list(pelt = result1, binseg = result2)) expect_s3_class(p, "ggplot") }) # ============================================================================= # Interactive Plot Tests # ============================================================================= test_that("plot_interactive returns plotly object", { skip_if_not_installed("plotly") set.seed(123) data <- generate_test_data() result <- detect_regimes(data) p <- plot_interactive(result) expect_s3_class(p, "plotly") }) # ============================================================================= # Edge Cases # ============================================================================= test_that("plot handles no changepoints", { set.seed(123) data <- rnorm(100) result <- detect_regimes(data, method = "pelt", penalty = 100) # Should not error even with no changepoints p <- plot(result) expect_s3_class(p, "ggplot") }) test_that("plot handles single changepoint", { set.seed(123) data <- generate_test_data() result <- detect_regimes(data) p <- plot(result) expect_s3_class(p, "ggplot") }) test_that("plot handles many changepoints", { set.seed(123) # Data with many changepoints n_segments <- 10 segment_length <- 30 data <- unlist(lapply(1:n_segments, function(i) { rnorm(segment_length, mean = ifelse(i %% 2 == 0, 0, 3)) })) result <- detect_regimes(data, method = "pelt", min_segment = 10) p <- plot(result) expect_s3_class(p, "ggplot") }) # ============================================================================= # Theme and Aesthetics Tests # ============================================================================= test_that("plot respects ggplot2 theme additions", { set.seed(123) data <- generate_test_data() result <- detect_regimes(data) p <- plot(result) + ggplot2::theme_minimal() expect_s3_class(p, "ggplot") }) test_that("plot can be modified with ggplot2 layers", { set.seed(123) data <- generate_test_data() result <- detect_regimes(data) p <- plot(result) + ggplot2::labs(x = "Time Index", y = "Value") expect_s3_class(p, "ggplot") }) # ============================================================================= # Data Visualization Helper Tests # ============================================================================= test_that("segment coloring is correct", { set.seed(123) data <- generate_test_data() result <- detect_regimes(data) p <- plot(result, type = "segments") # Check that plot has segment information expect_s3_class(p, "ggplot") }) test_that("changepoint lines are added", { set.seed(123) data <- generate_test_data() result <- detect_regimes(data) p <- plot(result, type = "data") # Plot should have vertical line geoms if changepoints detected if (length(result$changepoints) > 0) { layer_classes <- sapply(p$layers, function(l) class(l$geom)[1]) expect_true("GeomVline" %in% layer_classes || any(grepl("line", tolower(layer_classes)))) } })