tests/testthat/test-plot-refactor.R

## ---------------------------------------------------------
## 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"))
})

Try the fect package in your browser

Any scripts or data that you put into this service are public.

fect documentation built on April 30, 2026, 9:06 a.m.