test_that("can recognise intro variants", { expect_true(article_is_intro("package", "package")) expect_true(article_is_intro("articles/package", "package")) expect_true(article_is_intro("pack-age", "pack.age")) expect_true(article_is_intro("articles/pack-age", "pack.age")) }) test_that("links to man/figures are automatically relocated", { # weird path differences that I don't have the energy to dig into skip_on_cran() pkg <- local_pkgdown_site(test_path("assets/man-figures")) expect_snapshot(copy_figures(pkg)) expect_snapshot(build_articles(pkg, lazy = FALSE)) html <- xml2::read_html(path(pkg$dst_path, "articles", "kitten.html")) src <- xpath_attr(html, "//img", "src") expect_equal(src, c( "../reference/figures/kitten.jpg", "../reference/figures/kitten.jpg", "another-kitten.jpg" )) # And files aren't copied expect_false(dir_exists(path(pkg$dst_path, "man"))) }) test_that("warns about missing images", { local_edition(3) pkg <- local_pkgdown_site(test_path("assets/bad-images")) expect_snapshot(build_articles(pkg)) }) test_that("articles don't include header-attrs.js script", { pkg <- as_pkgdown(test_path("assets/articles")) withr::defer(clean_site(pkg, quiet = TRUE)) expect_snapshot(path <- build_article("standard", pkg)) html <- xml2::read_html(path) js <- xpath_attr(html, ".//body//script", "src") # included for pandoc 2.7.3 - 2.9.2.1 improve accessibility js <- js[basename(js) != "empty-anchor.js"] expect_equal(js, character()) }) test_that("can build article that uses html_vignette", { pkg <- local_pkgdown_site(test_path("assets/articles")) # theme is not set since html_vignette doesn't support it expect_snapshot(expect_error(build_article("html-vignette", pkg), NA)) }) test_that("can override html_document() options", { pkg <- local_pkgdown_site(test_path("assets/articles")) expect_snapshot(path <- build_article("html-document", pkg)) # Check that number_sections is respected html <- xml2::read_html(path) expect_equal(xpath_text(html, ".//h2//span"), c("1", "2")) # But title isn't affected expect_equal(xpath_text(html, ".//h1"), "html_document + as_is") # And no links or scripts are inlined expect_equal(xpath_length(html, ".//body//link"), 0) expect_equal(xpath_length(html, ".//body//script"), 0) }) test_that("html widgets get needed css/js", { pkg <- local_pkgdown_site(test_path("assets/articles")) expect_snapshot(path <- build_article("widget", pkg)) html <- xml2::read_html(path) css <- xpath_attr(html, ".//body//link", "href") js <- xpath_attr(html, ".//body//script", "src") expect_true("diffviewer.css" %in% basename(css)) expect_true("diffviewer.js" %in% basename(js)) }) test_that("can override options with _output.yml", { pkg <- local_pkgdown_site(test_path("assets/articles")) expect_snapshot(path <- build_article("html-document", pkg)) # Check that number_sections is respected html <- xml2::read_html(path) expect_equal(xpath_text(html, ".//h2//span"), c("1", "2")) }) test_that("can set width", { pkg <- local_pkgdown_site(test_path("assets/articles"), " code: width: 50 ") expect_snapshot(path <- build_article("width", pkg)) html <- xml2::read_html(path) expect_equal(xpath_text(html, ".//pre")[[2]], "## [1] 50") }) test_that("finds external resources referenced by R code in the article html", { # weird path differences that I don't have the energy to dig into skip_on_cran() pkg <- local_pkgdown_site(test_path("assets", "articles-resources")) expect_snapshot(path <- build_article("resources", pkg)) # ensure that we the HTML references `` directly expect_equal( xpath_attr(xml2::read_html(path), ".//img", "src"), "external.png" ) # expect that `external.png` was copied to the rendered article directory expect_true( file_exists(path(path_dir(path), "external.png")) ) }) test_that("BS5 article laid out correctly with and without TOC", { pkg <- local_pkgdown_site(test_path("assets/articles"), " template: bootstrap: 5 ") suppressMessages(expect_message(init_site(pkg))) expect_snapshot(toc_true_path <- build_article("standard", pkg)) expect_snapshot(toc_false_path <- build_article("toc-false", pkg)) toc_true <- xml2::read_html(toc_true_path) toc_false <- xml2::read_html(toc_false_path) # Always has class col-md-9 expect_equal(xpath_attr(toc_false, ".//main", "class"), "col-md-9") expect_equal(xpath_attr(toc_true, ".//main", "class"), "col-md-9") # The no sidebar without toc expect_equal(xpath_length(toc_true, ".//aside"), 1) expect_equal(xpath_length(toc_false, ".//aside"), 0) }) test_that("articles in vignettes/articles/ are unnested into articles/", { # weird path differences that I don't have the energy to dig into skip_on_cran() pkg <- local_pkgdown_site(test_path("assets/articles")) expect_snapshot(path <- build_article("articles/nested", pkg)) expect_equal( normalizePath(path), normalizePath(file.path(pkg$dst_path, "articles", "nested.html")) ) # Check automatic redirect from articles/articles/foo.html -> articles/foo.html pkg$meta$url <- "https://example.com" expect_snapshot(build_redirects(pkg)) # Check that the redirect file exists in /articles/articles/ redirect_path <- path(pkg$dst_path, "articles", "articles", "nested.html") expect_true(file_exists(redirect_path)) # Check that we redirect to correct location html <- xml2::read_html(redirect_path) expect_match( xpath_attr(html, ".//meta[@http-equiv = 'refresh']", "content"), "https://example.com/articles/nested.html", fixed = TRUE ) }) test_that("pkgdown deps are included only once in articles", { local_edition(3) pkg <- local_pkgdown_site(test_path("assets/articles"), " template: bootstrap: 5 ") suppressMessages(expect_message(init_site(pkg))) expect_snapshot(path <- build_article("html-deps", pkg)) html <- xml2::read_html(path) # jquery is only loaded once, even though it's also added by code in the article expect_equal(xpath_length(html, ".//script[(@src and contains(@src, '/jquery'))]"), 1) # same for bootstrap js and css str_subset_bootstrap <- function(x) { bs_rgx <- "bootstrap-[\\d.]+" # ex: bootstrap-5.1.0 not bootstrap-toc, grep(bs_rgx, x, value = TRUE, perl = TRUE) } bs_js_src <- str_subset_bootstrap( xpath_attr(html, ".//script[(@src and contains(@src, '/bootstrap'))]", "src") ) expect_length(bs_js_src, 1) bs_css_href <- str_subset_bootstrap( xpath_attr(html, ".//link[(@href and contains(@href, '/bootstrap'))]", "href") ) expect_length(bs_css_href, 1) }) test_that("check doesn't include getting started vignette", { pkg <- local_pkgdown_site(test_path("assets/articles-resources")) getting_started <- path(pkg$src_path, "vignettes", paste0(pkg$package, ".Rmd")) file_create(getting_started) withr::defer(unlink(getting_started)) pkg <- local_pkgdown_site(test_path("assets/articles-resources"), meta = " articles: - title: Title contents: resources ") expect_error(data_articles_index(pkg), NA) }) test_that("output is reproducible by default, i.e. 'seed' is respected", { pkg <- local_pkgdown_site(test_path("assets/articles")) suppressMessages(build_article(pkg = pkg, name = "random")) output <- xml2::read_html(file.path(pkg$dst_path, "articles/random.html")) %>% rvest::html_node("div.contents > pre") %>% rvest::html_text() %>% # replace line feeds with whitespace to make output platform independent gsub("\r", "", .) expect_snapshot(cat(output)) })