tests/testthat/test-qqhn.R

library(testthat)
library(ggplot2)

test_that("stat_qqhn computes half-normal theoretical quantiles and absolute sample", {
  df <- data.frame(value = c(-2, -1, 0, 1, 2))

  p <- ggplot(df, aes(sample = value)) +
    stat_qqhn()

  layer <- ggplot_build(p)$data[[1]]

  expect_equal(layer$y, sort(abs(df$value)))

  expected_x <- stats::qnorm((stats::ppoints(length(df$value)) + 1) / 2)
  expect_equal(layer$x, expected_x)
})

test_that("stat_qqhn_line returns a 2-point reference line", {
  df <- data.frame(value = c(-4, -2, -1, 0, 1, 2, 4))

  p <- ggplot(df, aes(sample = value)) +
    stat_qqhn_line()

  layer <- ggplot_build(p)$data[[1]]

  expect_equal(nrow(layer), 2)
  expect_true(is.finite(layer$x[1]))
  expect_true(is.finite(layer$y[1]))
  expect_gt(diff(layer$x), 0)
  expect_gt(diff(layer$y), 0)
})

test_that("stat_qqhn_line accepts origin-anchored line.p and passes through origin", {
  df <- data.frame(value = c(-4, -2, -1, 0, 1, 2, 4))

  p <- ggplot(df, aes(sample = value)) +
    stat_qqhn_line(line.p = c(0, 0.25))
  layer <- ggplot_build(p)$data[[1]]

  slope <- diff(layer$y) / diff(layer$x)
  intercept <- layer$y[1] - slope * layer$x[1]
  expect_equal(as.numeric(intercept), 0, tolerance = 1e-10)
})

test_that("stat_qqhn_line rejects length-2 line.p when first value is not zero", {
  df <- data.frame(value = c(-4, -2, -1, 0, 1, 2, 4))
  p <- ggplot(df, aes(sample = value)) + stat_qqhn_line(line.p = c(0.1, 0.25))

  expect_error(ggplot_build(p), "first value must be 0")
})

test_that("geom_qqhn_line works when labels aesthetics are present", {
  df <- data.frame(
    value = c(-4, -2, -1, 0, 1, 2, 4),
    lbl = letters[1:7]
  )

  p <- ggplot(df, aes(sample = value, labels = lbl)) +
    geom_qqhn_line()

  layer <- ggplot_build(p)$data[[1]]
  expect_equal(nrow(layer), 2)
})

test_that("geom_qqhn labels largest values and removes their points", {
  df <- data.frame(value = c(1, 4, 2, 5, 3))

  p <- ggplot(df, aes(sample = value)) +
    geom_qqhn(label_n = 2)

  built <- ggplot_build(p)$data
  point_layer <- built[[1]]
  label_layer <- built[[2]]

  expect_equal(nrow(point_layer), 3)
  expect_equal(sort(label_layer$label), c("4", "5"))
})

test_that("geom_qqhn uses `labels` aesthetic for labeled points", {
  df <- data.frame(
    value = c(1, 4, 2, 5, 3),
    lbl = c("a", "b", "c", "d", "e")
  )

  p <- ggplot(df, aes(sample = value, labels = lbl)) +
    geom_qqhn(label_n = 2)

  label_layer <- ggplot_build(p)$data[[2]]
  expect_equal(sort(label_layer$label), c("b", "d"))
})

test_that("geom_qqhn sets default axis labels", {
  df <- data.frame(value = c(1, 2, 3))
  p <- ggplot(df, aes(sample = value)) + geom_qqhn()

  expect_equal(p$labels$x, "Theoretical quantiles")
  expect_equal(p$labels$y, "Sample quantiles for value")
})

test_that("geom_qqhn and geom_qqhn_line support grouped series", {
  df <- data.frame(
    value = c(-2, -1, 0, 1, 2, -3, -2, 0, 2, 3),
    grp = rep(c("g1", "g2"), each = 5)
  )

  p <- ggplot(df, aes(sample = value, colour = grp, group = grp)) +
    geom_qqhn() +
    geom_qqhn_line()

  built <- ggplot_build(p)$data
  point_layer <- built[[1]]
  line_layer <- built[[2]]

  expect_equal(length(unique(point_layer$group)), 2)
  expect_equal(length(unique(line_layer$group)), 2)
})

test_that("stat_qqhn_band returns a valid envelope", {
  df <- data.frame(value = c(-3, -2, -1, 0, 1, 2, 3))
  p <- ggplot(df, aes(sample = value)) + stat_qqhn_band()
  layer <- ggplot_build(p)$data[[1]]

  expect_gt(nrow(layer), 0)
  expect_true(all(layer$ymax >= layer$ymin))
})

test_that("stat_qqhn_band rejects length-2 line.p when first value is not zero", {
  df <- data.frame(value = c(-3, -2, -1, 0, 1, 2, 3))
  p <- ggplot(df, aes(sample = value)) + stat_qqhn_band(line.p = c(0.1, 0.25))

  expect_error(ggplot_build(p), "first value must be 0")
})

test_that("geom_qqhn_band works without explicit group mapping", {
  df <- data.frame(value = c(-3, -2, -1, 0, 1, 2, 3))
  p <- ggplot(df, aes(sample = value)) + geom_qqhn_band()
  layer <- ggplot_build(p)$data[[1]]

  expect_gt(nrow(layer), 0)
  expect_equal(length(unique(layer$group)), 1)
})

Try the adas.utils package in your browser

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

adas.utils documentation built on Feb. 27, 2026, 5:08 p.m.