## --------------------------------------------------------- ## Tests for plot refactoring: pre/post colors, esplot(fect), ## harmonized defaults ## --------------------------------------------------------- ## Shared fixture out_fect <- NULL setup_once <- function() { if (is.null(out_fect)) { set.seed(9001) data(simdata, package = "fect") out_fect <<- fect::fect(Y ~ D + X1 + X2, data = simdata, index = c("id", "time"), method = "fe", se = TRUE, nboots = 30, parallel = FALSE) } } ## ========================================================= ## Section A: Pre/Post Color Distinction ## ========================================================= test_that("A1: default gap plot has pre.color=gray50, post.color=black", { skip_on_cran() setup_once() p <- plot(out_fect, type = "gap") expect_true(inherits(p, "gg") || inherits(p, "ggplot")) ## Extract the geom layers — should have separate pre and post pointranges layers <- p$layers expect_true(length(layers) >= 3, info = "Gap plot should have at least hline + pre-pointrange + post-pointrange") }) test_that("A2: connected gap plot uses dashed pre-treatment line", { skip_on_cran() setup_once() p <- plot(out_fect, type = "gap", connected = TRUE) expect_true(inherits(p, "gg")) layers <- p$layers ## Should have ribbon + line layers for both pre and post expect_true(length(layers) >= 4, info = "Connected gap should have hline + pre-ribbon/line + post-ribbon/line") }) test_that("A3: custom pre.color and post.color", { skip_on_cran() setup_once() p <- plot(out_fect, pre.color = "steelblue", post.color = "firebrick") expect_true(inherits(p, "gg")) }) test_that("A4: pre.color = post.color = color reproduces single-color behavior", { skip_on_cran() setup_once() p <- plot(out_fect, pre.color = "red", post.color = "red", color = "red") expect_true(inherits(p, "gg")) }) ## ========================================================= ## Section B: esplot() Accepts fect Objects ## ========================================================= test_that("B1: esplot(fect_object) produces a valid plot", { skip_on_cran() setup_once() p <- esplot(out_fect, main = "esplot(fect)") expect_true(inherits(p, "gg")) }) test_that("B2: esplot(fect_object) matches plot.fect gap output structure", { skip_on_cran() setup_once() p1 <- plot(out_fect, type = "gap") p2 <- esplot(out_fect) ## Both should be ggplot objects with similar layer count expect_true(inherits(p1, "gg")) expect_true(inherits(p2, "gg")) ## Both should have the same number of data points d1 <- suppressWarnings(ggplot2::ggplot_build(p1)$data) d2 <- suppressWarnings(ggplot2::ggplot_build(p2)$data) ## At least the point data should have similar row counts ## (exact match may differ due to count bars, but should be close) expect_true(length(d1) > 0) expect_true(length(d2) > 0) }) test_that("B3: esplot(fect_object) with custom colors", { skip_on_cran() setup_once() p <- esplot(out_fect, pre.color = "blue", post.color = "darkred") expect_true(inherits(p, "gg")) }) test_that("B4: esplot(fect_object) with connected = TRUE", { skip_on_cran() setup_once() p <- esplot(out_fect, connected = TRUE) expect_true(inherits(p, "gg")) }) ## ========================================================= ## Section C: esplot() Backward Compatibility (data.frame input) ## ========================================================= test_that("C1: esplot(data.frame) still works", { skip_on_cran() df <- data.frame( Period = -3:3, ATT = c(-0.1, 0.05, -0.02, 0.01, 1.5, 2.0, 2.5), CI.lower = c(-0.1, 0.05, -0.02, 0.01, 1.5, 2.0, 2.5) - 0.5, CI.upper = c(-0.1, 0.05, -0.02, 0.01, 1.5, 2.0, 2.5) + 0.5 ) p <- esplot(df, show.count = FALSE) expect_true(inherits(p, "gg")) }) test_that("C2: esplot(data.frame) with pre/post colors", { skip_on_cran() df <- data.frame( Period = -3:3, ATT = c(-0.1, 0.05, -0.02, 0.01, 1.5, 2.0, 2.5), CI.lower = c(-0.1, 0.05, -0.02, 0.01, 1.5, 2.0, 2.5) - 0.5, CI.upper = c(-0.1, 0.05, -0.02, 0.01, 1.5, 2.0, 2.5) + 0.5 ) p <- esplot(df, show.count = FALSE, pre.color = "gray70", post.color = "black") expect_true(inherits(p, "gg")) }) test_that("C3: esplot(data.frame) connected with pre/post", { skip_on_cran() df <- data.frame( Period = -3:3, ATT = c(-0.1, 0.05, -0.02, 0.01, 1.5, 2.0, 2.5), CI.lower = c(-0.1, 0.05, -0.02, 0.01, 1.5, 2.0, 2.5) - 0.5, CI.upper = c(-0.1, 0.05, -0.02, 0.01, 1.5, 2.0, 2.5) + 0.5 ) p <- esplot(df, connected = TRUE, show.count = FALSE) expect_true(inherits(p, "gg")) }) ## ========================================================= ## Section D: Harmonized Defaults ## ========================================================= test_that("D1: esplot show.points defaults to TRUE", { skip_on_cran() expect_equal(formals(esplot)$show.points, TRUE) }) test_that("D2: esplot show.count defaults to TRUE", { skip_on_cran() expect_equal(formals(esplot)$show.count, TRUE) }) test_that("D3: plot.fect count.color uses 'gray' not 'grey'", { skip_on_cran() ## Check that the default is set consistently ## (This is a static check; the actual default is resolved at runtime) setup_once() ## Just verify the plot works with default colors p <- plot(out_fect, type = "gap") expect_true(inherits(p, "gg")) }) ## ========================================================= ## Section E: Highlight / Placebo Overlay on Pre/Post ## ========================================================= test_that("E1: placebo test plot with pre/post colors", { skip_on_cran() data(simdata, package = "fect") out_p <- suppressWarnings(fect::fect( Y ~ D, data = simdata, index = c("id", "time"), method = "fe", se = TRUE, nboots = 30, parallel = FALSE, placeboTest = TRUE, placebo.period = c(-2, 0), CV = FALSE )) p <- plot(out_p) expect_true(inherits(p, "gg")) }) test_that("E2: esplot highlight.periods overlays on pre/post", { skip_on_cran() df <- data.frame( Period = -3:3, ATT = c(-0.1, 0.05, -0.02, 0.01, 1.5, 2.0, 2.5), CI.lower = c(-0.1, 0.05, -0.02, 0.01, 1.5, 2.0, 2.5) - 0.5, CI.upper = c(-0.1, 0.05, -0.02, 0.01, 1.5, 2.0, 2.5) + 0.5 ) p <- esplot(df, show.count = FALSE, highlight.periods = c(-2, -1, 0), highlight.colors = rep("blue", 3)) expect_true(inherits(p, "gg")) }) ## ========================================================= ## Section F: Edge Cases ## ========================================================= test_that("F1: all-pre data (only.pre = TRUE)", { skip_on_cran() setup_once() p <- esplot(out_fect, only.pre = TRUE) expect_true(inherits(p, "gg")) }) test_that("F2: all-post data (only.post = TRUE)", { skip_on_cran() setup_once() p <- esplot(out_fect, only.post = TRUE) expect_true(inherits(p, "gg")) }) test_that("F3: esplot errors on fect object without se", { skip_on_cran() data(simdata, package = "fect") out_nose <- fect::fect(Y ~ D, data = simdata, index = c("id", "time"), method = "fe", se = FALSE, CV = FALSE) expect_error(esplot(out_nose)) }) test_that("F4: equiv plot with pre/post colors", { skip_on_cran() setup_once() p <- plot(out_fect, type = "equiv") expect_true(inherits(p, "gg")) })