if (rstudioapi::isAvailable()) {
# Remove everything
rm(list = ls(all.names = TRUE))
rm(list = ls(all.names = TRUE, envir = globalenv()), envir = globalenv())
if (length(sessionInfo()$otherPkgs) > 0)
invisible(lapply(paste0('package:', names(sessionInfo()$otherPkgs)), detach, character.only = TRUE, unload = TRUE))
# Explicit libraries for manual testing
library(rstudioapi)
library(testthat)
# Helpers. Save in one obj to better control what's in the environment
helpers = list(
# Wait for some variable to be assigned.
# Expect that it isn't assigned to begin with
wait_for_job = function(varname) {
expect_true(exists(varname, envir = parent.frame()) == FALSE)
while (exists(varname, envir = parent.frame()) == FALSE) {
Sys.sleep(0.5)
}
},
pkgs = c("stats", "graphics", "grDevices", "utils", "datasets", "methods", "base")
)
options(job.mainsession = TRUE) # Test whether this is imported to job sessions
#########################
# TEST DEFAULT BEHAVIOR #
#########################
test_that("Default usage with named chunk", {
# Set env
a = 123
b = list(a = a, goat = "baah")
inner_func = function(x) x^2
outer_func = function(x) sum(inner_func(x))
# Launch job
job::job(default = {
vars = ls(all.names = TRUE)
pkgs = .packages()
searchpaths_job = searchpaths() # Test that packages are loaded in the correct order
a_copy = a
b_copy = b
a = 123 # same value as imported; do not return
b = list(a = a, goat = "peep") # imported, but new value; return
na_classed_works = is.character(NA_character_) # Test that NA_character_ is not converted to NA
inner_outer = outer_func(c(0, 2, 4)) # Tests https://github.com/lindeloev/job/issues/49
attached_rstudioapi = exists("isAvailable")
opts = options()
print("output!")
})
# Check result
helpers$wait_for_job("default")
expect_identical(default$vars, c(".__jobsettings__", "a", "b", "inner_func", "outer_func"))
expect_identical(default$pkgs, c("testthat", "rstudioapi", helpers$pkgs))
expect_identical(default$searchpaths_job, searchpaths()[searchpaths() %in% c("devtools_shims", "SciViews:TempEnv") == FALSE])
expect_identical(default$a_copy, a)
expect_identical(default$b_copy, b)
expect_true(default$na_classed_works)
expect_true(default$inner_outer == 20)
expect_true(default$attached_rstudioapi)
expect_identical(names(default), c("inner_func", "b_copy", "pkgs", "b", ".jobcode", "outer_func", "opts", "a_copy", "vars", "searchpaths_job", "inner_outer", "attached_rstudioapi", "na_classed_works"))
expect_true(is.null(default$opts$job.mainsession) == FALSE & default$opts$device == options("device"))
# Cleanup
rm(default, envir = globalenv())
})
######################
# TEST UNQUOTED ARGS #
######################
test_that("Set arguments in job::job()", {
# Set env
a = 123
b = list(a = a, goat = "baah")
q = "some value"
# Launch job
returned = job::job(with_args1 = {
vars = ls(all.names = TRUE)
pkgs = .packages()
b_copy = b
q = list(i_am = "different") # change value of imported
attached_rstudioapi = exists("isAvailable")
opts = options()
print("output!")
}, import = c(b, q), packages = c("job"), title = "something weird: #/(¤", opts = list(job.newopt = 59))
# Check result
helpers$wait_for_job("with_args1")
expect_true(is.character(returned))
expect_identical(with_args1$vars, c(".__jobsettings__", "b", "q"))
expect_identical(with_args1$pkgs, c("job", helpers$pkgs))
expect_identical(with_args1$b_copy, b)
expect_true(with_args1$attached_rstudioapi == FALSE)
expect_identical(names(with_args1), c("b_copy", "pkgs", ".jobcode", "opts", "vars", "q", "attached_rstudioapi"))
expect_true(is.null(with_args1$opts$job.mainsession) == TRUE & with_args1$opts$job.newopt == 59)
# Cleanup
rm(with_args1, envir = globalenv())
})
#################################
# TEST empty() WITH QUOTED ARGS #
#################################
test_that("Set arguments in job::empty()", {
# Set env
a = 123
b = list(a = a, goat = "baah")
q = "some value"
# Launch job
returned = job::empty(with_args2 = {
vars = ls(all.names = TRUE)
pkgs = .packages()
b_copy = b
q = list(i_am = "different") # change value of imported
attached_rstudioapi = exists("isAvailable")
opts = options()
print("output!")
}, import = c("b", "q"), packages = c("job"), title = "something weird: #/(¤", opts = list(job.newopt = 59))
# Check result
helpers$wait_for_job("with_args2")
expect_true(is.character(returned))
expect_identical(with_args2$vars, c(".__jobsettings__", "b", "q"))
expect_identical(with_args2$pkgs, c("job", helpers$pkgs))
expect_identical(with_args2$b_copy, b)
expect_true(with_args2$attached_rstudioapi == FALSE)
expect_identical(names(with_args2), c("b_copy", "pkgs", ".jobcode", "opts", "vars", "q", "attached_rstudioapi"))
expect_true(is.null(with_args2$opts$job.mainsession) == TRUE & with_args2$opts$job.newopt == 59)
# Cleanup
rm(with_args2, envir = globalenv())
})
##############
# TEST EMPTY #
##############
test_that("Empty job via job::job()", {
# Set env
a = 123
b = list(a = a, goat = "baah")
# Launch job
job::job(empty1 = {
vars = ls(all.names = TRUE)
pkgs = .packages()
opts = options()
print("output!")
}, import = NULL, packages = NULL, opts = NULL)
# Check results
helpers$wait_for_job("empty1")
expect_identical(empty1$vars, ".__jobsettings__")
expect_identical(empty1$pkgs, helpers$pkgs)
expect_identical(names(empty1), c("pkgs", ".jobcode", "opts", "vars"))
expect_true(is.null(empty1$opts$job.mainsession) == TRUE)
# Cleanup
rm(empty1, envir = globalenv())
})
test_that("Empty job via job::empty()", {
# Set env
a = 123
b = list(a = a, goat = "baah")
# Launch job
job::empty(empty2 = {
vars = ls(all.names = TRUE)
pkgs = .packages()
opts = options()
print("output!")
})
# Check results
helpers$wait_for_job("empty2")
expect_identical(empty2$vars, ".__jobsettings__")
expect_identical(empty2$pkgs, helpers$pkgs)
expect_identical(names(empty2), c("pkgs", ".jobcode", "opts", "vars"))
expect_true(is.null(empty2$opts$job.mainsession) == TRUE)
# Cleanup
rm(empty2, envir = globalenv())
})
####################
# TEST JOB::EXPORT #
####################
test_that("Default + export('all')", {
# Set env
a = 123
# Launch job
job::job(export_all = {
q = 555
print("output!")
job::export("all")
})
# Check results
helpers$wait_for_job("export_all")
expect_identical(export_all$q, 555)
expect_identical(names(export_all), c("a", ".jobcode", "q"))
# Cleanup
rm(export_all, envir = globalenv())
})
test_that("Default + export(NULL)", {
# Set env
a = 123
# Launch job
job::job(export_none = {
q = 555
print("output!")
job::export(NULL)
})
# Check results
helpers$wait_for_job("export_none")
expect_identical(names(export_none), ".jobcode")
# Cleanup
rm(export_none, envir = globalenv())
})
test_that("Default + export(c(some, vars))", {
# Set env
a = 123
b = list(a = a, goat = "baah")
# Launch job
job::job(export_some = {
q = 555
stuff = "don't return me"
print("output!")
job::export(c(a, q))
})
# Check results
helpers$wait_for_job("export_some")
expect_identical(names(export_some), c("a", ".jobcode", "q"))
# Cleanup
rm(export_some, envir = globalenv())
})
test_that("Default + export('new')", {
# Set env
a = 123
# Launch job
job::job(export_new = {
a = 444
q = 555
print("output!")
job::export("new")
})
# Check results
helpers$wait_for_job("export_new")
expect_identical(export_new$q, 555)
expect_identical(names(export_new), c(".jobcode", "q"))
# Cleanup
rm(export_new, envir = globalenv())
})
test_that("Default + export('changed', file = 'myfile.RData')", {
# Set env
a = 123
# Launch job
job::job(export_file = {
a = 123
q = 555
print("output!")
job::export(file = "mydata.RData")
})
# Check results
helpers$wait_for_job("export_file")
expect_identical(names(export_file), c(".jobcode"))
export_env = new.env()
load("mydata.RData", envir = export_env)
expect_identical(names(export_env), c("q"))
expect_identical(export_env$q, 555)
# Cleanup
rm(export_file, envir = globalenv())
file.remove("mydata.RData")
})
##########################
# TEST UNNAMED ARGUMENTS #
##########################
# These two jobs are identical
test_that("All args are unnamed", {
# Set env
a = 123
b = list(a = a, goat = "baah")
# Launch job
job::job(args_unnamed = {
a = 123
vars = ls(all.names = TRUE)
pkgs = .packages()
opts = options()
print("output!")
}, c(a), c("rstudioapi"), list(job.newopt = 59))
# Check results
helpers$wait_for_job("args_unnamed")
expect_identical(args_unnamed$vars, c(".__jobsettings__", "a"))
expect_identical(args_unnamed$pkgs, c("rstudioapi", helpers$pkgs))
expect_null(args_unnamed$opts$job.mainsession)
expect_identical(args_unnamed$opts$job.newopt, 59)
# Cleanup
rm(args_unnamed, envir = globalenv())
})
test_that("Some args are unnamed", {
# Set env
a = 123
b = list(a = a, goat = "baah")
# Launch job
job::job(args_onenamed = {
a = 123
vars = ls(all.names = TRUE)
pkgs = .packages()
opts = options()
print("output!")
}, c(a), packages = c("rstudioapi"), list(job.newopt = 59))
# Check results
helpers$wait_for_job("args_onenamed")
expect_identical(args_onenamed$vars, c(".__jobsettings__", "a"))
expect_identical(args_onenamed$pkgs, c("rstudioapi", helpers$pkgs))
expect_null(args_onenamed$opts$job.mainsession)
expect_identical(args_onenamed$opts$job.newopt, 59)
# Cleanup
rm(args_onenamed, envir = globalenv())
})
#########################
# TEST RETURN TO GLOBAL #
#########################
test_that("Return to global", {
job::job({
a = 10 # Try assigning new value
newvar1 = 1
newvar5 = 5 * 3
print("output!")
}, packages = NULL) # for speed
helpers$wait_for_job("newvar1")
expect_identical(get("a", envir = globalenv()), 10)
expect_true(newvar1 == 1 & newvar5 == 15)
#expect_identical(ls(envir = globalenv()), c("a", "newvar1", "newvar5")) # b and helpers are in local env.
rm(a, envir = globalenv())
rm(newvar1, envir = globalenv())
rm(newvar5, envir = globalenv())
})
############
# CLEAN UP #
############
rm(list = ls(all.names = TRUE))
rm(list = ls(all.names = TRUE, envir = globalenv()))
} else {
expect_error(job::job({a = 1}), "You must run this from the RStudio main session.")
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.