skip_on_os(c("mac", "solaris", "linux"))
skip_if_not_installed("ggplot2")
skip_if_not_installed("see")
skip_if_not_installed("vdiffr")
skip_if_not_installed("emmeans")
skip_if_not_installed("marginaleffects", minimum_version = "0.29.0")
skip_on_cran()

test_that("plots emmeans", {
  model <- lm(Sepal.Length ~ Species * Sepal.Width, data = iris)

  # Estimate means -------------------------------------
  x <- estimate_means(model, by = "Species", backend = "emmeans")
  vdiffr::expect_doppelganger(
    "plot-means-1",
    plot(modelbased::visualisation_recipe(x, show_data = FALSE))
  )
  vdiffr::expect_doppelganger(
    "plot-means-1-lines",
    plot(modelbased::visualisation_recipe(x, show_data = FALSE, join_dots = TRUE))
  )
  x <- estimate_means(model, by = "Sepal.Width", backend = "emmeans")
  vdiffr::expect_doppelganger(
    "plot-means-2",
    plot(modelbased::visualisation_recipe(x, show_data = FALSE))
  )
  x <- estimate_means(model, by = c("Sepal.Width", "Species"), backend = "emmeans")
  vdiffr::expect_doppelganger(
    "plot-means-3",
    plot(modelbased::visualisation_recipe(x, show_data = FALSE))
  )
  x <- estimate_means(model, by = c("Species", "Sepal.Width"), backend = "emmeans")
  vdiffr::expect_doppelganger(
    "plot-means-4",
    plot(modelbased::visualisation_recipe(x, show_data = FALSE))
  )
  vdiffr::expect_doppelganger(
    "plot-means-4-lines",
    plot(modelbased::visualisation_recipe(x, show_data = FALSE, join_dots = TRUE))
  )
})


test_that("plots, show_data", {
  model <- lm(Sepal.Length ~ Species * Sepal.Width, data = iris)

  # Estimate means -------------------------------------
  x <- estimate_means(model, by = "Species")
  set.seed(123)
  vdiffr::expect_doppelganger(
    "plot-means-showdata-1",
    plot(modelbased::visualisation_recipe(x, show_data = TRUE))
  )
  x <- estimate_means(model, by = "Sepal.Width")
  set.seed(123)
  vdiffr::expect_doppelganger(
    "plot-means-showdata-2",
    plot(modelbased::visualisation_recipe(x, show_data = TRUE))
  )
  x <- estimate_means(model, by = c("Sepal.Width", "Species"))
  set.seed(123)
  vdiffr::expect_doppelganger(
    "plot-means-showdata-3",
    plot(modelbased::visualisation_recipe(x, show_data = TRUE))
  )
  x <- estimate_means(model, by = c("Species", "Sepal.Width"))
  set.seed(123)
  vdiffr::expect_doppelganger(
    "plot-means-showdata-4",
    plot(modelbased::visualisation_recipe(x, show_data = TRUE))
  )
})


test_that("plots marginalmeans", {
  model <- lm(Sepal.Length ~ Species * Sepal.Width, data = iris)

  # Estimate means -------------------------------------
  x <- estimate_means(model, by = "Species", backend = "marginaleffects")
  vdiffr::expect_doppelganger(
    "plot-me-means-1",
    plot(modelbased::visualisation_recipe(x, show_data = FALSE))
  )
  x <- estimate_means(model, by = "Sepal.Width", backend = "marginaleffects")
  vdiffr::expect_doppelganger(
    "plot-me-means-2",
    plot(modelbased::visualisation_recipe(x, show_data = FALSE))
  )
  x <- estimate_means(
    model,
    by = c("Sepal.Width", "Species"),
    backend = "marginaleffects"
  )
  vdiffr::expect_doppelganger(
    "plot-me-means-3",
    plot(modelbased::visualisation_recipe(x, show_data = FALSE))
  )
  x <- estimate_means(
    model,
    by = c("Species", "Sepal.Width"),
    backend = "marginaleffects"
  )
  vdiffr::expect_doppelganger(
    "plot-me-means-4",
    plot(modelbased::visualisation_recipe(x, show_data = FALSE))
  )
})


test_that("plots marginalmeans, show_data", {
  model <- lm(Sepal.Length ~ Species * Sepal.Width, data = iris)

  # Estimate means -------------------------------------
  x <- estimate_means(model, by = "Species", backend = "marginaleffects")
  set.seed(123)
  vdiffr::expect_doppelganger(
    "plot-me-means-showdata-1",
    plot(modelbased::visualisation_recipe(x, show_data = TRUE))
  )
  x <- estimate_means(model, by = "Sepal.Width", backend = "marginaleffects")
  set.seed(123)
  vdiffr::expect_doppelganger(
    "plot-me-means-showdata-2",
    plot(modelbased::visualisation_recipe(x, show_data = TRUE))
  )
  x <- estimate_means(
    model,
    by = c("Sepal.Width", "Species"),
    backend = "marginaleffects"
  )
  set.seed(123)
  vdiffr::expect_doppelganger(
    "plot-me-means-showdata-3",
    plot(modelbased::visualisation_recipe(x, show_data = TRUE))
  )
  x <- estimate_means(
    model,
    by = c("Species", "Sepal.Width"),
    backend = "marginaleffects"
  )
  set.seed(123)
  vdiffr::expect_doppelganger(
    "plot-me-means-showdata-4",
    plot(modelbased::visualisation_recipe(x, show_data = TRUE))
  )
})


test_that("plots relation", {
  model <- lm(Sepal.Length ~ Species * Sepal.Width, data = iris)

  # Estimate means -------------------------------------
  x <- estimate_relation(model, by = "Species")
  vdiffr::expect_doppelganger(
    "plot-relation-1",
    plot(modelbased::visualisation_recipe(x, show_data = FALSE))
  )
  x <- estimate_relation(model, by = "Sepal.Width")
  vdiffr::expect_doppelganger(
    "plot-relation-2",
    plot(modelbased::visualisation_recipe(x, show_data = FALSE))
  )
  x <- estimate_relation(model, by = c("Sepal.Width", "Species"))
  vdiffr::expect_doppelganger(
    "plot-relation-3",
    plot(modelbased::visualisation_recipe(x, show_data = FALSE))
  )
  x <- estimate_relation(model, by = c("Species", "Sepal.Width"))
  vdiffr::expect_doppelganger(
    "plot-relation-4",
    plot(modelbased::visualisation_recipe(x, show_data = FALSE))
  )
})


test_that("plots, relation show_data", {
  model <- lm(Sepal.Length ~ Species * Sepal.Width, data = iris)

  # Estimate means -------------------------------------
  x <- estimate_relation(model, by = "Species")
  set.seed(123)
  vdiffr::expect_doppelganger(
    "plot-relation-showdata-1",
    plot(modelbased::visualisation_recipe(x, show_data = TRUE))
  )
  x <- estimate_relation(model, by = "Sepal.Width")
  set.seed(123)
  vdiffr::expect_doppelganger(
    "plot-relation-showdata-2",
    plot(modelbased::visualisation_recipe(x, show_data = TRUE))
  )
  x <- estimate_relation(model, by = c("Sepal.Width", "Species"))
  set.seed(123)
  vdiffr::expect_doppelganger(
    "plot-relation-showdata-3",
    plot(modelbased::visualisation_recipe(x, show_data = TRUE))
  )
  x <- estimate_relation(model, by = c("Species", "Sepal.Width"))
  set.seed(123)
  vdiffr::expect_doppelganger(
    "plot-relation-showdata-4",
    plot(modelbased::visualisation_recipe(x, show_data = TRUE))
  )
})


test_that("plots, relation, percentage for logistic", {
  # required for penguins data, which was added in 4.5.0
  skip_if(getRversion() < "4.5.0")
  data(penguins, package = "datasets")

  out <- suppressWarnings(estimate_relation(glm(
    sex ~ body_mass,
    data = penguins,
    family = "binomial"
  )))

  set.seed(123)
  vdiffr::expect_doppelganger(
    "plot-relation-logistic-percentage-1",
    plot(modelbased::visualisation_recipe(out))
  )
})


test_that("plots, grouplevel lme4", {
  skip_if_not_installed("lme4")
  d <- rbind(lme4::sleepstudy, lme4::sleepstudy)
  d$Newfactor <- rep(c("A", "B", "C", "D"))
  model <- lme4::lmer(Reaction ~ Days + (1 + Days | Subject) + (1 | Newfactor), data = d)
  set.seed(123)
  vdiffr::expect_doppelganger("plot-grouplevel-lme4-1", plot(estimate_grouplevel(model)))
  out <- estimate_grouplevel(model)
  vr <- visualisation_recipe(out, pointrange = list(color = "black"))
  set.seed(123)
  vdiffr::expect_doppelganger("plot-grouplevel-lme4-2", plot(vr))
})


test_that("plots, relation, multiple CI", {
  data(mtcars)
  m <- lm(mpg ~ qsec, data = mtcars)
  em <- estimate_relation(m, ci = c(0.5, 0.8, 0.9))
  set.seed(123)
  vdiffr::expect_doppelganger("plot-relation-multiple-ci-1", plot(em, show_data = TRUE))
})


test_that("plots, estimate_means works with Poisson", {
  set.seed(123)
  dat <- data.frame(y = rpois(100, 3), fa = gl(4, 20, 100))
  dat_glm <- glm(y ~ fa, data = dat, family = poisson(link = "log"))
  x <- estimate_means(dat_glm, "fa", backend = "emmeans")
  set.seed(123)
  vdiffr::expect_doppelganger("plot-means-poisson-1", plot(x, show_data = TRUE))
  set.seed(123)
  vdiffr::expect_doppelganger(
    "plot-means-poisson-1-lines",
    plot(x, show_data = TRUE, join_dots = TRUE)
  )
  x <- estimate_means(dat_glm, "fa", backend = "marginaleffects")
  set.seed(123)
  vdiffr::expect_doppelganger("plot-means-poisson-2", plot(x, show_data = TRUE))
})


test_that("plots, estimate_means, order of predictors", {
  data(iris)
  model <- lm(Petal.Length ~ Sepal.Width * Species, data = iris)
  pr <- estimate_means(model, by = c("Species", "Sepal.Width"), backend = "emmeans")
  set.seed(123)
  vdiffr::expect_doppelganger("plot-means-predictor-order-1", plot(pr, show_data = FALSE))
  pr <- estimate_means(model, by = c("Sepal.Width", "Species"), backend = "emmeans")
  set.seed(123)
  vdiffr::expect_doppelganger("plot-means-predictor-order-2", plot(pr, show_data = FALSE))
  pr <- estimate_means(
    model,
    by = c("Species", "Sepal.Width"),
    backend = "marginaleffects"
  )
  set.seed(123)
  vdiffr::expect_doppelganger("plot-means-predictor-order-3", plot(pr, show_data = FALSE))
  pr <- estimate_means(
    model,
    by = c("Sepal.Width", "Species"),
    backend = "marginaleffects"
  )
  set.seed(123)
  vdiffr::expect_doppelganger("plot-means-predictor-order-4", plot(pr, show_data = FALSE))
})


test_that("plots, numeric or categorical predictors are detected", {
  data(mtcars)
  dat <- mtcars
  dat$cyl <- factor(dat$cyl)
  m_cat <- lm(mpg ~ cyl, data = dat)
  pr <- estimate_expectation(m_cat, by = "cyl")
  set.seed(123)
  vdiffr::expect_doppelganger("plot-cat-num-predictor-1", plot(pr, show_data = FALSE))
  pr <- estimate_means(m_cat, by = "cyl", backend = "marginaleffects")
  set.seed(123)
  vdiffr::expect_doppelganger("plot-cat-num-predictor-2", plot(pr, show_data = FALSE))
  m_cat <- lm(mpg ~ cyl, data = mtcars)
  pr <- estimate_expectation(m_cat, by = "cyl")
  set.seed(123)
  vdiffr::expect_doppelganger("plot-cat-num-predictor-3", plot(pr, show_data = FALSE))
  pr <- estimate_means(m_cat, by = "cyl", backend = "marginaleffects")
  set.seed(123)
  vdiffr::expect_doppelganger("plot-cat-num-predictor-4", plot(pr, show_data = FALSE))
  pr <- estimate_expectation(m_cat, by = "cyl", range = "grid")
  set.seed(123)
  vdiffr::expect_doppelganger("plot-cat-num-predictor-5", plot(pr, show_data = FALSE))

  data(efc, package = "modelbased")
  m <- lm(neg_c_7 ~ barthtot, data = efc)
  pr <- estimate_means(m, by = "barthtot", backend = "marginaleffects")
  set.seed(123)
  vdiffr::expect_doppelganger("plot-cat-num-predictor-6", plot(pr, show_data = FALSE))
  pr <- estimate_means(m, by = "barthtot", range = "grid", backend = "marginaleffects")
  set.seed(123)
  vdiffr::expect_doppelganger("plot-cat-num-predictor-7", plot(pr, show_data = FALSE))
})


test_that("plots, at special values", {
  data(iris)
  model <- lm(Sepal.Width ~ Petal.Length + Species * Petal.Width, data = iris)
  pr <- estimate_expectation(
    model,
    by = c("Species", "Petal.Width = [fivenum]"),
    preserve_range = FALSE
  )
  set.seed(123)
  vdiffr::expect_doppelganger("plot-expectation-fivenum", plot(pr, show_data = FALSE))
  set.seed(123)
  vdiffr::expect_doppelganger(
    "plot-expectation-fivenum.2",
    plot(pr, show_data = FALSE, numeric_as_discrete = FALSE)
  )
})


test_that("plots, estimate_slope", {
  skip_if(packageVersion("see") <= "0.10.0")
  data(iris)

  model <- lm(Sepal.Width ~ Species * Petal.Length, data = iris)
  slopes <- estimate_slopes(
    model,
    trend = "Petal.Length",
    by = "Species",
    backend = "emmeans"
  )
  set.seed(123)
  vdiffr::expect_doppelganger("plot-slopes-1", plot(slopes))

  model <- lm(Sepal.Width ~ Petal.Width * Petal.Length, data = iris)
  slopes <- estimate_slopes(
    model,
    trend = "Petal.Length",
    by = "Petal.Width",
    backend = "emmeans"
  )
  set.seed(123)
  vdiffr::expect_doppelganger("plot-slopes-2", plot(slopes))

  model <- lm(Sepal.Width ~ Species * Petal.Length, data = iris)
  slopes <- estimate_slopes(
    model,
    trend = "Petal.Length",
    by = "Species",
    backend = "marginaleffects"
  )
  set.seed(123)
  vdiffr::expect_doppelganger("plot-slopes-3", plot(slopes))

  model <- lm(Sepal.Width ~ Petal.Width * Petal.Length, data = iris)
  slopes <- estimate_slopes(
    model,
    trend = "Petal.Length",
    by = "Petal.Width",
    length = 200,
    backend = "marginaleffects"
  )
  set.seed(123)
  vdiffr::expect_doppelganger("plot-slopes-4", plot(slopes))

  data(iris)
  x <- iris
  x$fac <- rep_len(c("A", "B"), 150)
  x$fac2 <- rep_len(c("X", "X", "X", "Y", "Y", "Y"), 150)
  model <- lm(Sepal.Length ~ Species * fac * Sepal.Width * fac2, data = x)
  slopes <- estimate_slopes(
    model,
    trend = "Species",
    by = "Sepal.Width",
    backend = "marginaleffects"
  )
  set.seed(123)
  vdiffr::expect_doppelganger("plot-slopes-5", plot(slopes))
})


test_that("plots, automatically join dots", {
  data(iris)
  m <- lm(Sepal.Width ~ Petal.Length + Species * Petal.Width, data = iris)
  out <- estimate_expectation(m, by = c("Species", "Petal.Width"))
  set.seed(123)
  vdiffr::expect_doppelganger("plot-join-dots-1", plot(out, show_data = TRUE))
  out <- estimate_expectation(m, by = c("Species", "Petal.Width"), preserve_range = FALSE)
  set.seed(123)
  vdiffr::expect_doppelganger("plot-join-dots-2", plot(out, show_data = TRUE))
})


test_that("plots, logistic regression", {
  data(mtcars)
  model <- glm(vs ~ wt, data = mtcars, family = "binomial")
  out <- estimate_means(model, "wt", length = 100, backend = "marginaleffects")
  set.seed(123)
  vdiffr::expect_doppelganger("plot-glm-logistic-1", plot(out, show_data = TRUE))
  out <- estimate_means(
    model,
    "wt",
    length = 100,
    predict = "link",
    backend = "marginaleffects"
  )
  set.seed(123)
  vdiffr::expect_doppelganger("plot-glm-logistic-2", plot(out, show_data = TRUE))
})


test_that("plots, 4-way with numeric", {
  data(efc, package = "modelbased")
  # make categorical
  efc <- datawizard::to_factor(efc, c("c161sex", "c172code", "e16sex"))
  levels(efc$c172code) <- c("low", "mid", "high")
  m <- lm(neg_c_7 ~ e16sex + c161sex + c172code * barthtot + c12hour, data = efc)
  by <- c("c12hour", "c161sex", "c172code", "barthtot = [fivenum]")
  estim <- estimate_means(m, by = by, backend = "marginaleffects")
  set.seed(123)
  vdiffr::expect_doppelganger("plot-4way-numeric-1", plot(estim, show_data = FALSE))
})


test_that("plots, glm logistic inside bound", {
  set.seed(5)
  data <- data.frame(
    outcome = rbinom(100, 1, 0.5),
    var1 = as.factor(rbinom(100, 1, 0.1)),
    var2 = rnorm(100, 10, 7)
  )
  m <- glm(outcome ~ var1 * var2, data = data, family = binomial(link = "logit"))
  out1 <- estimate_means(m, c("var2 = [sd]", "var1"), backend = "marginaleffects")
  set.seed(123)
  vdiffr::expect_doppelganger("plot-logistic-bounds-1", plot(out1, show_data = FALSE))
  set.seed(123)
  vdiffr::expect_doppelganger(
    "plot-logistic-bounds-2",
    plot(out1, show_data = FALSE, numeric_as_discrete = FALSE)
  )
})


test_that("plots no CI", {
  model <- lm(Sepal.Length ~ Species * Sepal.Width, data = iris)

  # Estimate means -------------------------------------
  x <- estimate_means(model, by = "Species", backend = "marginaleffects")
  vdiffr::expect_doppelganger(
    "plot-means-no-ci-1",
    plot(modelbased::visualisation_recipe(x, pointrange = list(geom = "point")))
  )
  vdiffr::expect_doppelganger(
    "plot-means-no-ci-2",
    plot(modelbased::visualisation_recipe(
      x,
      pointrange = list(geom = "point"),
      join_dots = FALSE
    ))
  )
  x <- estimate_means(model, by = "Sepal.Width", backend = "marginaleffects")
  vdiffr::expect_doppelganger(
    "plot-means-no_ci-3",
    plot(modelbased::visualisation_recipe(x, show_data = FALSE, ribbon = "none"))
  )
})


test_that("interaction of numerics (Johnson-Neyman)", {
  skip_if(packageVersion("see") <= "0.10.0")
  data(mtcars)
  model <- lm(mpg ~ hp * wt, data = mtcars)
  slopes <- estimate_slopes(model, trend = "hp", by = "wt", length = 200)
  set.seed(123)
  vdiffr::expect_doppelganger("plot-jonhson-neyman-1", plot(slopes))
})
