test_that("albers_vignette() builds an html_vignette with the theme assets", {
skip_if_not_installed("rmarkdown")
fmt <- albers_vignette(family = "teal", preset = "interaction")
expect_s3_class(fmt, "rmarkdown_output_format")
expect_true(isTRUE(fmt$knitr$opts_chunk$collapse))
expect_identical(fmt$knitr$opts_chunk$comment, "#>")
expect_error(albers_vignette(family = "puce"), "albers_vignette(): `family` must be one of \"red\", \"lapis\", \"ochre\", \"teal\", \"green\", \"violet\"; got 'puce'.", fixed = TRUE)
expect_error(albers_vignette(preset = "baroque"), "`preset` must be one of \"homage\", \"interaction\"", fixed = TRUE)
})
test_that("each direction ships only its own fonts", {
homage <- readLines(system.file("format", "albers-fonts-homage.css", package = "albersdown"))
interaction <- readLines(system.file("format", "albers-fonts-interaction.css", package = "albersdown"))
expect_true(any(grepl("Newsreader", homage)))
expect_false(any(grepl("Hanken|JetBrains|Space Grotesk", homage)))
expect_true(any(grepl("Hanken Grotesk", interaction)))
expect_false(any(grepl("Newsreader", interaction)))
# the shipped (minified) core carries no @font-face: fonts come per direction
core <- readLines(system.file("format", "albers-core.min.css", package = "albersdown"), warn = FALSE)
expect_false(any(grepl("@font-face", core, fixed = TRUE)))
# every font the direction files reference is installed
urls <- regmatches(c(homage, interaction), regexpr('fonts/[a-z-]+\\.woff2', c(homage, interaction)))
expect_true(all(nzchar(vapply(urls, function(u) system.file(u, package = "albersdown"), ""))))
})
test_that("a vignette renders self-contained with the family stamped before content", {
skip_on_cran()
skip_if_not_installed("rmarkdown")
skip_if_not(rmarkdown::pandoc_available("2.0"))
dir <- withr::local_tempdir()
rmd <- file.path(dir, "demo.Rmd")
writeLines(c(
"---", "title: Demo", "vignette: >", " %\\VignetteIndexEntry{Demo}",
" %\\VignetteEngine{knitr::rmarkdown}", "---", "",
"## One", "", "```{r}", "getOption('albersdown.family')", "1 + 1", "```"
), rmd)
before <- getOption("albersdown.family")
out <- rmarkdown::render(rmd, output_format = albers_vignette(family = "teal", preset = "homage"), quiet = TRUE)
html <- paste(readLines(out, warn = FALSE), collapse = "\n")
# classes are set by the first script inside
body_start <- regexpr("]*>", html)
stamp <- regexpr('classList.add\\("albers-vignette","palette-teal","preset-homage"', html)
expect_gt(stamp, body_start)
expect_lt(stamp, regexpr(" 0)
expect_identical(albers_discrete("teal", type = "family"), unname(albers_palette("teal")))
withr::local_options(albersdown.family = "violet")
expect_identical(albers_discrete()[1], unname(albers_palette("violet")[["A700"]]))
})
test_that("family ramps step in lightness so nested squares are distinguishable", {
lum <- function(hex) {
rgb <- grDevices::col2rgb(hex)[, 1] / 255
lin <- ifelse(rgb <= 0.04045, rgb / 12.92, ((rgb + 0.055) / 1.055)^2.4)
sum(c(0.2126, 0.7152, 0.0722) * lin)
}
for (f in c("red", "lapis", "ochre", "teal", "green", "violet")) {
l <- vapply(albers_palette(f), lum, numeric(1))
expect_true(all(diff(l) > 0.04), info = f)
}
})
test_that("theme_albers(mode = 'dark') uses the night ground", {
skip_if_not_installed("ggplot2")
light <- theme_albers("teal", "homage")
dark <- theme_albers("teal", "homage", mode = "dark")
expect_false(identical(light$plot.background$fill, dark$plot.background$fill))
expect_identical(dark$plot.background$fill, "#1b1814")
expect_identical(theme_albers("teal", "interaction", mode = "dark")$plot.background$fill, "#14171c")
})
test_that("night palettes are lighter than day palettes", {
lum <- function(hex) mean(grDevices::col2rgb(hex))
for (f in c("red", "lapis", "teal")) {
expect_gt(lum(albers_discrete(f, mode = "dark")[1]), lum(albers_discrete(f)[1]))
}
})
test_that("albers_vignette() emits a dark twin per ggplot and restores knitr", {
skip_on_cran()
skip_if_not_installed("rmarkdown")
skip_if_not_installed("ggplot2")
skip_if_not(rmarkdown::pandoc_available("2.0"))
dir <- withr::local_tempdir()
rmd <- file.path(dir, "twin.Rmd")
writeLines(c(
"---", "title: Twin", "vignette: >", " %\\VignetteIndexEntry{Twin}",
" %\\VignetteEngine{knitr::rmarkdown}", "---", "",
"```{r p1, fig.cap = 'Cap.'}",
"ggplot2::ggplot(mtcars, ggplot2::aes(wt, mpg, colour = factor(cyl))) +",
" ggplot2::geom_point() + albersdown::scale_color_albers()",
"```",
"```{r p2}",
"ggplot2::ggplot(mtcars, ggplot2::aes(wt, mpg)) + ggplot2::geom_point() + ggplot2::theme_bw()",
"```"
), rmd)
out <- rmarkdown::render(rmd, output_format = albers_vignette(family = "teal"), quiet = TRUE)
html <- paste(readLines(out, warn = FALSE), collapse = "\n")
twins <- gregexpr('class="albers-dark-twin"', html)[[1]]
# one twin for the themed plot; none for the plot with its own complete theme
expect_equal(sum(twins > 0), 1)
expect_false(isTRUE(getOption("albersdown.dark_figures")))
out2 <- rmarkdown::render(rmd, output_format = albers_vignette(family = "teal", dark_figures = FALSE),
quiet = TRUE, output_file = "twin-off.html")
# the class name also appears in the inlined script, so match the image markup
expect_false(grepl('class="albers-dark-twin"', paste(readLines(out2, warn = FALSE), collapse = "\n"), fixed = TRUE))
})
test_that("the pkgdown template links the theme on every page", {
partial <- readLines(system.file("pkgdown", "templates", "in-header.html", package = "albersdown"))
expect_true(any(grepl('{{#site}}{{root}}{{/site}}albers.css', partial, fixed = TRUE)))
expect_true(any(grepl('{{#site}}{{root}}{{/site}}albers.js', partial, fixed = TRUE)))
# user includes still flow through
expect_true(any(grepl("{{{in_header}}}", partial, fixed = TRUE)))
})
test_that("use_albersdown() leaves vignettes on albers_vignette() untouched", {
skip_if_not_installed("yaml")
pkg <- withr::local_tempdir()
dir.create(file.path(pkg, "vignettes"))
writeLines(c("Package: toy", "Title: Toy", "Version: 0.0.1", "Description: Toy.",
"License: MIT", "Encoding: UTF-8"), file.path(pkg, "DESCRIPTION"))
vig <- c(
"---", "title: Toy", "output:",
" albersdown::albers_vignette:",
" family: teal # keep this comment",
" pdf_document: default",
"vignette: >", " %\\VignetteIndexEntry{Toy}", " %\\VignetteEngine{knitr::rmarkdown}",
"---", "", "Text."
)
writeLines(vig, file.path(pkg, "vignettes", "toy.Rmd"))
suppressMessages(use_albersdown(path = pkg, family = "teal", apply_to = "all", dry_run = FALSE))
expect_identical(readLines(file.path(pkg, "vignettes", "toy.Rmd")), vig)
expect_true("^pkgdown$" %in% readLines(file.path(pkg, ".Rbuildignore")))
expect_true(any(grepl('family: "teal"', readLines(file.path(pkg, "pkgdown", "extra.js")), fixed = TRUE)))
})
test_that("the class stamp goes after the YAML front matter", {
yaml <- c("---", "title: x", "output:", " a: b", "---", "", "# Hi")
out <- strsplit(.albers_insert_after_front_matter(yaml, "STAMP"), "\n")[[1]]
expect_identical(out[1:5], yaml[1:5])
expect_true(which(out == "STAMP") > 5)
expect_identical(out[1], "---")
# no front matter: stamp first
expect_identical(strsplit(.albers_insert_after_front_matter(c("# Hi"), "S"), "\n")[[1]][1], "S")
})
test_that("the rendered page carries its classes and no MathJax loader without math", {
skip_on_cran()
skip_if_not_installed("rmarkdown")
skip_if_not(rmarkdown::pandoc_available("2.0"))
dir <- withr::local_tempdir()
rmd <- file.path(dir, "m.Rmd")
writeLines(c("---", "title: M", "vignette: >", " %\\VignetteIndexEntry{M}",
" %\\VignetteEngine{knitr::rmarkdown}", "---", "", "No math here."), rmd)
out <- rmarkdown::render(rmd, output_format = albers_vignette(family = "lapis", preset = "interaction"), quiet = TRUE)
html <- paste(readLines(out, warn = FALSE), collapse = "\n")
expect_match(html, '', fixed = TRUE)
expect_false(grepl("mathjax.rstudio.com", html, fixed = TRUE))
writeLines(c("---", "title: M", "vignette: >", " %\\VignetteIndexEntry{M}",
" %\\VignetteEngine{knitr::rmarkdown}", "---", "", "Math: $x^2$."), rmd)
out <- rmarkdown::render(rmd, output_format = albers_vignette(), quiet = TRUE)
expect_match(paste(readLines(out, warn = FALSE), collapse = "\n"), "