makeManifest <- function(appDir, appPrimaryDoc = NULL, ...) {
writeManifest(appDir, appPrimaryDoc = appPrimaryDoc, ..., quiet = TRUE)
manifestFile <- file.path(appDir, "manifest.json")
data <- readLines(manifestFile, warn = FALSE, encoding = "UTF-8")
manifestJson <- jsonlite::fromJSON(data)
unlink(manifestFile)
manifestJson
}
test_that("renv.lock is included for renv projects", {
skip_on_cran()
skip_if_not_installed("foreign")
skip_if_not_installed("MASS")
withr::local_options(renv.verbose = FALSE)
app_dir <- local_temp_app(list(app.R = "library(foreign); library(MASS)"))
renv::snapshot(app_dir, prompt = FALSE)
manifest <- makeManifest(app_dir)
# note: we don't see an .Rprofile here because we only renv::snapshot and
# do not fully create an renv project.
expect_named(manifest$files, c("app.R", "renv.lock"))
})
test_that("renv.lock is not included for non-renv projects", {
skip_on_cran()
skip_if_not_installed("foreign")
skip_if_not_installed("MASS")
withr::local_options(renv.verbose = FALSE)
app_dir <- local_temp_app(list(app.R = "library(foreign); library(MASS)"))
manifest <- makeManifest(app_dir)
expect_named(manifest$files, c("app.R"))
})
test_that("Rmd with reticulate as a dependency includes python in the manifest", {
skip_on_cran()
skip_if_not_installed("reticulate")
python <- pythonPathOrSkip()
appDir <- test_path("test-reticulate-rmds")
manifest <- makeManifest(appDir, python = python)
requirements_file <- file.path(appDir, manifest$python$package_manager$package_file)
expect_equal(requirements_file, "test-reticulate-rmds/requirements.txt")
defer(unlink(requirements_file))
expect_equal(manifest$metadata$appmode, "rmd-static")
expect_equal(manifest$metadata$primary_rmd, "index.Rmd")
expect_true(file.exists(requirements_file))
})
test_that("Rmd with reticulate as an inferred dependency includes reticulate and python in the manifest", {
skip_on_cran()
skip_if_not_installed("reticulate")
python <- pythonPathOrSkip()
appDir <- test_path("test-reticulate-rmds")
manifest <- makeManifest(appDir, "implicit.Rmd", python = python)
requirements_file <- file.path(appDir, manifest$python$package_manager$package_file)
expect_equal(requirements_file, "test-reticulate-rmds/requirements.txt")
defer(unlink(requirements_file))
expect_equal(manifest$metadata$appmode, "rmd-static")
expect_equal(manifest$metadata$primary_rmd, "implicit.Rmd")
expect_true(file.exists(requirements_file))
})
test_that("Rmd without a python block doesn't include reticulate or python in the manifest", {
skip_on_cran()
manifest <- makeManifest(test_path("test-rmds"), "simple.Rmd", python = NULL)
expect_equal(manifest$metadata$appmode, "rmd-static")
expect_equal(manifest$metadata$primary_rmd, "simple.Rmd")
expect_null(manifest$python)
})
test_that("Rmd without a python block doesn't include reticulate or python in the manifest even if python specified", {
skip_on_cran()
skip_if_not_installed("reticulate")
python <- pythonPathOrSkip()
manifest <- makeManifest("test-rmds", "simple.Rmd", python = python)
expect_equal(manifest$metadata$appmode, "rmd-static")
expect_equal(manifest$metadata$primary_rmd, "simple.Rmd")
expect_equal(manifest$python, NULL)
# Confirm that we have removed packrat entries from our file listing but
# retain entries for other files.
filenames <- names(manifest$files)
expect_false(any(grepl("^packrat/", filenames, perl = TRUE)), filenames)
expect_true(any(grepl("simple.Rmd", filenames, fixed = TRUE)), filenames)
})
# Quarto Tests
test_that("Quarto website includes quarto in the manifest", {
skip_on_cran()
skip_if_no_quarto()
appDir <- test_path("quarto-website-r")
manifest <- makeManifest(appDir, quarto = TRUE)
expect_equal(manifest$metadata$appmode, "quarto-static")
expect_equal(manifest$quarto$engines, "knitr")
expect_equal(manifest$metadata$primary_rmd, "index.qmd")
})
test_that("Quarto document includes quarto in the manifest", {
skip_on_cran()
skip_if_no_quarto()
appDir <- test_path("quarto-doc-none")
appPrimaryDoc <- "quarto-doc-none.qmd"
manifest <- makeManifest(appDir, appPrimaryDoc, quarto = TRUE)
expect_equal(manifest$metadata$appmode, "quarto-static")
expect_equal(manifest$quarto$engines, "markdown")
expect_equal(manifest$metadata$primary_rmd, "quarto-doc-none.qmd")
})
test_that("Specifying quarto arg includes quarto in the manifest, even with no appPrimaryDoc specified (.qmd)", {
skip_on_cran()
skip_if_no_quarto()
appDir <- test_path("quarto-doc-none")
appPrimaryDoc <- NULL
manifest <- makeManifest(appDir, appPrimaryDoc, quarto = TRUE)
expect_equal(manifest$metadata$appmode, "quarto-static")
expect_equal(manifest$quarto$engines, "markdown")
expect_equal(manifest$metadata$primary_rmd, "quarto-doc-none.qmd")
})
test_that("Specifying quarto arg includes quarto in the manifest, even with no appPrimaryDoc specified (.Rmd)", {
skip_on_cran()
skip_if_no_quarto()
appDir <- test_path("shiny-rmds")
appPrimaryDoc <- NULL
manifest <- makeManifest(appDir, appPrimaryDoc, quarto = TRUE)
expect_equal(manifest$metadata$appmode, "quarto-shiny")
expect_equal(manifest$quarto$engines, "knitr")
expect_equal(manifest$metadata$primary_rmd, "non-shiny-rmd.Rmd")
})
test_that("specifying quarto arg with non-quarto app does not include quarto in the manifest", {
skip_on_cran()
skip_if_no_quarto()
appDir <- test_path("shinyapp-singleR")
appPrimaryDoc <- "single.R"
manifest <- makeManifest(appDir, appPrimaryDoc, quarto = TRUE)
expect_null(manifest$quarto)
})
test_that("Quarto shiny project includes quarto in the manifest", {
skip_on_cran()
skip_if_no_quarto()
appDir <- test_path("quarto-proj-r-shiny")
manifest <- makeManifest(appDir, quarto = TRUE)
expect_equal(manifest$metadata$appmode, "quarto-shiny")
expect_equal(manifest$quarto$engines, "knitr")
expect_equal(manifest$metadata$primary_rmd, "quarto-proj-r-shiny.qmd")
})
test_that("Quarto R + Python website includes quarto and python in the manifest", {
skip_on_cran()
skip_if_not_installed("reticulate")
skip_if_no_quarto()
python <- pythonPathOrSkip()
appDir <- test_path("quarto-website-r-py")
manifest <- makeManifest(appDir, python = python, quarto = TRUE)
expect_equal(manifest$metadata$appmode, "quarto-static")
expect_equal(manifest$quarto$engines, "knitr")
expect_equal(manifest$metadata$primary_rmd, "index.qmd")
expect_true(all(c("quarto", "python") %in% names(manifest)))
expect_true("reticulate" %in% names(manifest$packages))
})
test_that("Quarto Python-only website gets correct manifest data", {
skip_on_cran()
skip_if_not_installed("reticulate")
skip_if_no_quarto()
python <- pythonPathOrSkip()
appDir <- test_path("quarto-website-py")
manifest <- makeManifest(appDir, python = python, quarto = TRUE)
expect_equal(manifest$metadata$appmode, "quarto-static")
expect_equal(manifest$quarto$engines, "jupyter")
expect_equal(manifest$metadata$primary_rmd, "index.qmd")
# We expect Quarto and Python metadata, but no R packages.
expect_true(all(c("quarto", "python") %in% names(manifest)))
expect_null(manifest$packages)
})
test_that("Deploying a Quarto project without Quarto is an error", {
skip_on_cran()
local_mocked_bindings(quarto_path = function() NULL)
appDir <- test_path("quarto-website-r")
expect_snapshot(makeManifest(appDir), error = TRUE)
})
test_that("Deploying R Markdown content with Quarto gives a Quarto app mode", {
skip_on_cran()
skip_if_no_quarto()
manifest <- makeManifest(test_path("test-rmds"), "simple.Rmd", quarto = TRUE)
expect_equal(manifest$metadata$appmode, "quarto-static")
expect_equal(manifest$quarto$engines, "knitr")
expect_equal(manifest$metadata$primary_rmd, "simple.Rmd")
})
test_that("Deploying static content with _quarto.yaml succeeds without quartoInfo", {
skip_on_cran()
manifest <- makeManifest(test_path("static-with-quarto-yaml"))
expect_equal(manifest$metadata$appmode, "static")
})
test_that("environment.image is not set when image is not provided", {
skip_on_cran()
withr::local_options(renv.verbose = TRUE)
appDir <- test_path("shinyapp-simple")
manifest <- makeManifest(appDir)
expect_null(manifest$environment)
})
test_that("TensorFlow models are identified", {
skip_on_cran()
app_dir <- local_temp_app(list(
"1/saved_model.pb" = "fake-saved-model"
))
manifest <- makeManifest(app_dir)
expect_equal(manifest$metadata$appmode, "tensorflow-saved-model")
expect_null(manifest$packages)
expect_named(manifest$files, c("1/saved_model.pb"))
})
test_that("environment.image is set when image is provided", {
skip_on_cran()
withr::local_options(renv.verbose = TRUE)
appDir <- test_path("shinyapp-simple")
manifest <- makeManifest(appDir, image = "rstudio/content-base:latest")
expect_equal(manifest$environment$image, "rstudio/content-base:latest")
})
test_that("environment.image is set and uses a provided image even when RSCONNECT_IMAGE is set", {
skip_on_cran()
withr::local_options(renv.verbose = TRUE)
withr::local_envvar(RSCONNECT_IMAGE = "rstudio/content-base:older")
appDir <- test_path("shinyapp-simple")
manifest <- makeManifest(appDir, image = "rstudio/content-base:latest")
expect_equal(manifest$environment$image, "rstudio/content-base:latest")
})
test_that("environment.image is not set when RSCONNECT_IMAGE is empty", {
skip_on_cran()
withr::local_options(renv.verbose = TRUE)
withr::local_envvar(RSCONNECT_IMAGE = "")
appDir <- test_path("shinyapp-simple")
manifest <- makeManifest(appDir)
expect_null(manifest$environment)
})
test_that("environment.image is set when RSCONNECT_IMAGE is nonempty", {
skip_on_cran()
withr::local_options(renv.verbose = TRUE)
withr::local_envvar(RSCONNECT_IMAGE = "rstudio/content-base:latest")
appDir <- test_path("shinyapp-simple")
manifest <- makeManifest(appDir)
expect_equal(manifest$environment$image, "rstudio/content-base:latest")
})
test_that("Sets environment.environment_management in the manifest if envManagement is defined", {
skip_on_cran()
withr::local_options(renv.verbose = TRUE)
appDir <- test_path("shinyapp-simple")
# test shorthand arg
manifest <- makeManifest(appDir, envManagement = FALSE, envManagementR = TRUE, envManagementPy = TRUE)
expect_equal(manifest$environment$environment_management$r, FALSE)
expect_equal(manifest$environment$environment_management$python, FALSE)
# test R and Python args
manifest <- makeManifest(appDir, envManagementR = TRUE)
expect_equal(manifest$environment$environment_management$r, TRUE)
expect_null(manifest$environment$environment_management$python)
manifest <- makeManifest(appDir, envManagementPy = TRUE)
expect_equal(manifest$environment$environment_management$python, TRUE)
expect_null(manifest$environment$environment_management$r)
# environment_management is not defined when envManagementR and envManagementPy are NULL
manifest <- makeManifest(appDir, image = "rstudio/content-base:latest")
expect_null(manifest$environment$environment_management)
})
# appMode Inference tests
test_that("content type (appMode) is inferred and can be overridden", {
skip_on_cran()
appDir <- local_temp_app(list(
"app.R" = "",
"index.html" = "",
"plumber.R" = "",
"report.Rmd" = ""
))
files <- c("app.R", "index.html", "plumber.R", "report.Rmd")
manifest <- makeManifest(appDir)
expect_equal(manifest$metadata$appmode, "api")
expect_named(manifest$files, files)
manifest <- makeManifest(appDir, appMode = "shiny")
expect_equal(manifest$metadata$appmode, "shiny")
expect_named(manifest$files, files)
manifest <- makeManifest(appDir, appMode = "rmd-static")
expect_equal(manifest$metadata$appmode, "rmd-static")
expect_named(manifest$files, files)
manifest <- makeManifest(appDir, appMode = "static")
expect_equal(manifest$metadata$appmode, "static")
expect_named(manifest$files, files)
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.