context("wflow_publish")
# Setup ------------------------------------------------------------------------
library("git2r")
# Setup workflowr project for testing
site_dir <- tempfile("test-wflow_publish-")
suppressMessages(wflow_start(site_dir, change_wd = FALSE))
# Delete workflowr project on exit
on.exit(unlink(site_dir, recursive = TRUE, force = TRUE))
site_dir <- workflowr:::absolute(site_dir)
s <- wflow_status(project = site_dir)
r <- repository(s$root)
rmd <- file.path(s$analysis, c("about.Rmd", "index.Rmd", "license.Rmd"))
html <- workflowr:::to_html(rmd, outdir = s$docs)
rmd_to_fail <- file.path(s$analysis, "error.Rmd")
file.copy(from = "files/test-wflow_build/error.Rmd",
to = rmd_to_fail)
# Test wflow_publish -----------------------------------------------------------
test_that("wflow_publish works in a simple case", {
expect_message(o <- wflow_publish(rmd, view = FALSE, project = site_dir),
rmd[1])
expect_true(all(file.exists(html)))
s <- wflow_status(project = site_dir)
expect_true(all(s$status[rmd, "published"]))
})
# Create decoy file that should not be built since it is unpublished
rmd_decoy <- file.path(s$analysis, "decoy.Rmd")
file.create(rmd_decoy)
html_decoy <- workflowr:::to_html(rmd_decoy, outdir = s$docs)
test_that("wflow_publish can `republish`", {
mtime_pre <- file.mtime(html)
Sys.sleep(2)
# Change the theme
config <- file.path(s$analysis, "_site.yml")
config_lines <- readLines(config)
config_lines <- stringr::str_replace(config_lines,
" theme: cosmo",
" theme: readable")
writeLines(config_lines, con = config)
# Republish with new theme
expect_message(o <- wflow_publish(config, republish = TRUE, view = FALSE,
project = site_dir),
rmd[1])
mtime_post <- file.mtime(html)
expect_true(all(mtime_post > mtime_pre))
expect_true(config == o$step1$commit_files)
expect_true(all(html %in% o$step3$commit_files))
expect_false(file.exists(html_decoy))
expect_false(html_decoy %in% o$step3$commit_files)
})
# Commit decoy file. Should not be affected by `update = TRUE` b/c it has not
# been published.
wflow_commit(rmd_decoy, "Commit decoy Rmd", project = site_dir)
test_that("wflow_publish can `update`", {
# Edit and manually commit a published Rmd file, then use `update` to publish.
cat("edit", file = rmd[1], append = TRUE)
wflow_commit(rmd[1], "Draft edit", project = site_dir)
# Update
expect_message(o <- wflow_publish(update = TRUE, view = FALSE, project = site_dir),
rmd[1])
expect_true(is.null(o$step1))
expect_true(html[1] == o$step3$commit_files)
expect_false(file.exists(html_decoy))
expect_false(html_decoy %in% o$step3$commit_files)
})
test_that("wflow_publish can be used to commit non-Rmd files instead of wflow_commit", {
f_test <- file.path(s$root, "test.txt")
file.create(f_test)
expect_silent(o <- wflow_publish(f_test, view = FALSE, project = site_dir))
expect_true(f_test == o$step1$commit_files)
expect_true(is.null(o$step2))
expect_true(is.null(o$step3))
})
test_that("wflow_publish automatically removes unused figure files", {
# Publish a file that has 2 plots from 2 unnamed chunks
file_w_figs <- file.path(s$analysis, "fig.Rmd")
file.copy("files/test-wflow_build/figure-v01.Rmd", file_w_figs)
publish_v01 <- wflow_publish(file_w_figs, view = FALSE, project = site_dir)
figs_analysis_v01 <- file.path(s$analysis, "figure", basename(file_w_figs),
c("unnamed-chunk-1-1.png", "unnamed-chunk-2-1.png"))
expect_true(all(file.exists(figs_analysis_v01)))
figs_docs_v01 <- file.path(s$docs, "figure", basename(file_w_figs),
c("unnamed-chunk-1-1.png", "unnamed-chunk-2-1.png"))
expect_true(all(file.exists(figs_docs_v01)))
expect_true(all(figs_docs_v01 %in% publish_v01$step3$commit_files))
# Update the file such that the previous 2 chunks are now named, plus add a
# 3rd plot chunk
file.copy("files/test-wflow_build/figure-v02.Rmd", file_w_figs, overwrite = TRUE)
publish_v02 <- wflow_publish(file_w_figs, view = FALSE, project = site_dir)
expect_false(all(file.exists(figs_analysis_v01)))
expect_false(all(file.exists(figs_docs_v01)))
figs_analysis_v02 <- file.path(s$analysis, "figure", basename(file_w_figs),
c("named1-1.png", "named2-1.png", "named3-1.png"))
expect_true(all(file.exists(figs_analysis_v02)))
figs_docs_v02 <- file.path(s$docs, "figure", basename(file_w_figs),
c("named1-1.png", "named2-1.png", "named3-1.png"))
expect_true(all(file.exists(figs_docs_v02)))
expect_true(all(figs_docs_v02 %in% publish_v02$step3$commit_files))
# The v01 files should also be listed in the commit_files b/c they are removed
# in this commit
expect_true(all(figs_docs_v01 %in% publish_v02$step3$commit_files))
# The Git status should have no staged or unstaged changes, which would occur
# if the files were deleted but not committed
current_status <- status(r)
expect_false(length(current_status$staged) > 0)
expect_false(length(current_status$unstaged) > 0)
# Cleanup
file.remove(file_w_figs)
unlink(file.path(s$analysis, "figure", basename(file_w_figs)),
recursive = TRUE, force = TRUE)
unlink(file.path(s$docs, "figure", basename(file_w_figs)),
recursive = TRUE, force = TRUE)
})
# This tests the edge case where a file had one or more figures but then gets
# reduced to zero. While Git is able to "add" a non-existent directory to stage
# deleted files, git2r chokes if the non-existent directory is a relative path.
# git2r requires the non-existent directory to either be an absolute path or a
# relative path from the root of the Git repo.
test_that("wflow_publish removes unused figure files even if directory no longer exists", {
# Publish a file that has 2 plots from 2 unnamed chunks
file_w_figs <- file.path(s$analysis, "fig.Rmd")
file.copy("files/test-wflow_build/figure-v01.Rmd", file_w_figs)
publish_v01 <- wflow_publish(file_w_figs, view = FALSE, project = site_dir)
figs_analysis_v01 <- file.path(s$analysis, "figure", basename(file_w_figs),
c("unnamed-chunk-1-1.png", "unnamed-chunk-2-1.png"))
expect_true(all(file.exists(figs_analysis_v01)))
figs_docs_v01 <- file.path(s$docs, "figure", basename(file_w_figs),
c("unnamed-chunk-1-1.png", "unnamed-chunk-2-1.png"))
expect_true(all(file.exists(figs_docs_v01)))
expect_true(all(figs_docs_v01 %in% publish_v01$step3$commit_files))
# Update the file to have no plots
file.copy("files/test-wflow_build/seed.Rmd", file_w_figs, overwrite = TRUE)
publish_v02 <- wflow_publish(file_w_figs, view = FALSE, project = site_dir)
expect_false(all(file.exists(figs_analysis_v01)))
expect_false(all(file.exists(figs_docs_v01)))
# The old figure files should also be listed in the commit_files b/c they are
# removed in this commit
expect_true(all(figs_docs_v01 %in% publish_v02$step3$commit_files))
# The Git status should have no staged or unstaged changes, which would occur
# if the files were deleted but not committed
current_status <- status(r)
expect_false(length(current_status$staged) > 0)
expect_false(length(current_status$unstaged) > 0)
# Cleanup
file.remove(file_w_figs)
})
# Test error handling ----------------------------------------------------------
test_that("wflow_publish resets Git repo to previous commit if build fails", {
commit_pre <- commits(r, n = 1)[[1]]
expect_error(utils::capture.output(
wflow_publish(rmd_to_fail, view = FALSE, project = site_dir)),
"There was an error")
commit_post <- commits(r, n = 1)[[1]]
expect_identical(commit_post, commit_pre)
})
test_that("wflow_publish restores previous docs/ if build fails", {
md5sum_pre <- tools::md5sum(rmd)
mtime_pre <- file.mtime(rmd)
Sys.sleep(2)
expect_error(utils::capture.output(
wflow_publish(c(rmd, rmd_to_fail), view = FALSE, project = site_dir)),
"There was an error")
md5sum_post <- tools::md5sum(rmd)
mtime_post <- file.mtime(rmd)
expect_identical(md5sum_post, md5sum_pre)
expect_identical(mtime_post, mtime_pre)
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.