context("dependencies")
format.html_dependency <- function(x, ...) {
sprintf("%s v%s @ %s", x$name, x$version, format(x$src))
}
print.html_dependency <- function(x, ...) {
cat(format(x), "\n")
invisible(x)
}
expect_resolved_deps <- function(input, output) {
expect_identical(resolveDependencies(input), output)
}
test_that("Dependency resolution works", {
a1.1 <- htmlDependency("a", "1.1", c(href="/"))
a1.2 <- htmlDependency("a", "1.2", c(href="/"))
a1.2.1 <- htmlDependency("a", "1.2.1", c(href="/"))
b1.0.0 <- htmlDependency("b", "1.0.0", c(href="/"))
b1.0.1 <- htmlDependency("b", "1.0.1", c(href="/"))
c1.0 <- htmlDependency("c", "1.0", c(href="/"))
expect_resolved_deps(
list(a1.1, b1.0.0, b1.0.1, a1.2, a1.2.1, b1.0.0, b1.0.1, c1.0),
list(a1.2.1, b1.0.1, c1.0)
)
expect_resolved_deps(
list(tagFunction(function() { NULL })),
list()
)
expect_resolved_deps(
list(tagFunction(function() { a1.2 })),
list(a1.2)
)
expect_resolved_deps(
list(a1.1, tagFunction(function() { NULL })),
list(a1.1)
)
expect_resolved_deps(
list(a1.1, tagFunction(function() { a1.2 })),
list(a1.2)
)
expect_resolved_deps(
list(a1.1, tagFunction(function() { list(a1.2, a1.2.1) })),
list(a1.2.1)
)
expect_warning(expect_resolved_deps(
list(a1.1, tagFunction(function() { div("foo", a1.2, a1.2.1) })),
list(a1.2.1)
))
expect_warning(expect_resolved_deps(
list(a1.1, tagFunction(function() { tagList(a1.2, a1.2.1) })),
list(a1.2.1)
))
expect_warning(expect_resolved_deps(
list(a1.1, tagFunction(function() {
tagList(div("foo", a1.2), div("foo", a1.2.1))
})),
list(a1.2.1)
))
expect_warning(expect_resolved_deps(
list(a1.1, tagFunction(function() {
tagList(div("foo", a1.2), div("foo", tagFunction(function() { a1.2.1 }))) }
)),
list(a1.2.1)
))
res <- subtractDependencies(list(a1.2.1, b1.0.1), list(a1.1), warnOnConflict = FALSE)
expect_identical(res, list(b1.0.1))
expect_warning(subtractDependencies(list(a1.2.1, b1.0.1), list(a1.1)))
})
expect_html_deps <- function(x, html, deps) {
expect_identical(as.character(renderTags(x)$html), html)
expect_output(print(as.tags(x)), html)
expect_identical(findDependencies(x), deps)
}
test_that("Inline dependencies", {
# Test out renderTags and findDependencies when tags are inline
a1.1 <- htmlDependency("a", "1.1", c(href="/"))
a1.2 <- htmlDependency("a", "1.2", c(href="/"))
# tagLists ----------------------------------------------------------
x <- tagList(a1.1, div("foo"), "bar")
expect_html_deps(x, "
foo
\nbar", list(a1.1))
x <- tagList(a1.1, div("foo"), a1.2, "bar")
expect_html_deps(x, "foo
\nbar", list(a1.1, a1.2))
x <- tagList(a1.1, div("foo"), "bar", tagFunction(function() { a1.2 }))
expect_html_deps(x, "foo
\nbar", list(a1.1, a1.2))
x <- tagList(a1.1, div("foo"), "bar", tagFunction(function() { div("baz", a1.2) }))
expect_html_deps(x, "foo
\nbar\nbaz
", list(a1.1, a1.2))
# Mixing inline and attribute dependencies
x <- attachDependencies(
tagList(a1.1, div("foo"), "bar"),
a1.2, append = TRUE
)
expect_html_deps(x, "foo
\nbar", list(a1.1, a1.2))
x <- attachDependencies(
tagList(a1.1, div("foo"), "bar"),
tagFunction(function() { a1.2 }),
append = TRUE
)
expect_html_deps(x, "foo
\nbar", list(a1.1, a1.2))
x <- attachDependencies(
tagList(div("foo"), "bar", tagFunction(function() { a1.1 })),
tagFunction(function() { a1.2 }),
append = TRUE
)
expect_html_deps(x, "foo
\nbar", list(a1.1, a1.2))
# tags with children ------------------------------------------------
x <- div(a1.1, div("foo"), "bar")
expect_html_deps(x, "", list(a1.1))
x <- div(
tagFunction(function() { a1.1 }),
tagFunction(function() { div("foo") }),
tagFunction(function() { "bar" })
)
expect_html_deps(x, "", list(a1.1))
x <- tagFunction(function() {
div(div("foo"), a1.2, tagFunction(function() { "bar"}), a1.1)
})
expect_html_deps(x, "", list(a1.2, a1.1))
x <- attachDependencies(div(a1.1, div("foo"), "bar"), a1.2, append = TRUE)
expect_html_deps(x, "", list(a1.1, a1.2))
x <- attachDependencies(div(a1.1, div("foo"), "bar"), tagFunction(function() { a1.2 }), append = TRUE)
expect_html_deps(x, "", list(a1.1, a1.2))
# Passing normal lists to tagLists and tag functions ---------------
x <- tagList(list(a1.1, div("foo")), "bar")
expect_html_deps(x, "foo
\nbar", list(a1.1))
x <- tagList(list(tagFunction(function() { a1.1 }), div("foo")), "bar")
expect_html_deps(x, "foo
\nbar", list(a1.1))
x <- div(list(a1.1, div("foo")), "bar")
expect_html_deps(x, "", list(a1.1))
x <- div(list(tagFunction(function() { a1.1 }), div("foo")), "bar")
expect_html_deps(x, "", list(a1.1))
# Top-level lists -----------------------------------
x <- list(div("ab"), "cd", a1.1)
expect_html_deps(x, "ab
\ncd", list(a1.1))
x <- structure(list(div("ab"), "cd", a1.1), class = "foo")
expect_html_deps(x, "ab
\ncd", list(a1.1))
x <- tagList(tagFunction(function() { list(div("ab"), "cd", a1.1) }), "bar")
expect_html_deps(x, "ab
\ncd\nbar", list(a1.1))
})
test_that("Modifying children using dependencies", {
a1.1 <- htmlDependency("a", "1.1", c(href="/"))
a1.2 <- htmlDependency("a", "1.2", c(href="/"))
x <- tagAppendChild(div(a1.1), a1.2)
expect_identical(findDependencies(x), list(a1.1, a1.2))
x <- tagAppendChild(div(a1.1), tagFunction(function() { a1.2 }))
expect_identical(findDependencies(x), list(a1.1, a1.2))
x <- tagAppendChild(div(a1.1), list(a1.2))
expect_identical(findDependencies(x), list(a1.1, a1.2))
x <- tagAppendChildren(div(), a1.1, list(a1.2))
expect_identical(findDependencies(x), list(a1.1, a1.2))
x <- tagAppendChildren(div(), a1.1, tagFunction(function() { list(a1.2) }))
expect_identical(findDependencies(x), list(a1.1, a1.2))
x <- tagSetChildren(div("foo", a1.1), a1.2)
expect_identical(findDependencies(x), list(a1.2))
x <- tagSetChildren(div("foo", a1.1), tagFunction(function() { a1.2 }))
expect_identical(findDependencies(x), list(a1.2))
})
test_that("able to resolve HTML scripts supplied with & without integrity", {
src1 <- "https://cdn.com/libs/p1/0.1/"
src2 <- "https://cdn/libs/p2/0.2/"
deps <- list(
htmlDependency(
name = "p1",
version = "0.1",
src = list(href = src1),
script = list(
src = "p1.min.js",
integrity = "longhash",
crossorigin = "anonymous",
defer = NA
)
),
htmlDependency(
"p2", version = "0.2",
src = list(href = src2),
script = "p2.min.js"
)
)
expect1 <- paste(
'',
sep = ''
)
expect2 <- paste(
'',
sep = ''
)
expect <- paste(expect1, expect2, sep = '\n')
class(expect) <- c("html", "character")
actual <- renderDependencies(deps)
expect_equal(!!strsplit(actual, "\n"), !!strsplit(expect, "\n"))
})
test_that(
"can render scripts given as lists of nested lists + scalar strings", {
src = "https://cdn.com/libs/p1/0.1"
nm <- "p1.js"
d1 <- htmlDependency(
"p1", "0.1", src = list(href = src),
script = list(src = nm)
)
deps1 <- list(
d1,
htmlDependency(
"p1", "0.2", src = list(href = src),
script = nm
),
htmlDependency(
"p1", "0.3", src = list(href = src),
script = list(list(src = nm))
)
)
out <- renderDependencies(deps1)
deps2 <- list(
d1,
d1,
d1
)
expect_length(unique(unlist(strsplit(out, "\n"))), 1)
expect_equal(renderDependencies(deps1), renderDependencies(deps2))
nm2 <- "p1-0.1.js"
deps3 <- list(
htmlDependency(
"p1", "0.1", src = list(href = src),
script = c(nm, nm2)
)
)
out <- renderDependencies(deps3)
src_urls <- c(
file.path(src, nm),
file.path(src, nm2)
)
expect <- paste(
'\n',
'',
sep = "")
expect_equal(!!as.character(out), !!expect)
deps4 <- list(
htmlDependency(
"p1", "0.1", src = list(href = src),
script = list(list(src = nm, integrity = "hash"), nm2)
)
)
out <- renderDependencies(deps4)
expect <- paste(
'\n',
'',
sep = "")
expect_equal(!!as.character(out), !!expect)
})
test_that("html escaping is carried out correctly in script rendering", {
src = "https://cdn.com/libs/p1/0.1"
nm <- "p1.js"
funky_hash <- ""
deps <- list(
htmlDependency(
"p1", "0.1", src = list(href = src),
script = list(src = nm, integrity = funky_hash)
)
)
src_url <- file.path(src, nm)
expect <- paste(
'',
sep = ""
)
out <- renderDependencies(deps)
expect_equal(!!as.character(out), !!expect)
})
test_that("copyDependencyToDir() doesn't create an empty directory", {
tmp_dep <- tempfile("dep")
dir.create(tmp_dep)
on.exit(unlink(tmp_dep))
tmp_rmd <- tempfile("rmd_files")
dir.create(tmp_rmd)
on.exit(unlink(tmp_rmd), add = TRUE)
empty <- htmltools::htmlDependency(
name = "empty",
version = "9.9.9",
src = tmp_dep,
head = "",
all_files = FALSE
)
copied_dep <- copyDependencyToDir(empty, tmp_rmd)
# no directory is created for the empty dep
expect_equal(dir(tmp_rmd), character())
# copied dependency src points to folder where files should be so that
# to keep relativeTo() from throwing an error later in Rmd render process
expect_match(copied_dep$src$file, normalizePath(tmp_rmd, "/", TRUE), fixed = TRUE)
})
test_that("copyDependencyToDir() creates recursive output directories", {
tmp_dep <- tempfile("dep")
dir.create(tmp_dep)
on.exit(unlink(tmp_dep, recursive = TRUE))
writeLines(
c("alert('boo')"),
file.path(tmp_dep, "script.js")
)
dep <- htmltools::htmlDependency(
name = "simple",
version = "9.9.9",
src = tmp_dep,
script = "script.js",
all_files = FALSE
)
tmp_outputDir <- file.path(tempfile("outputDir"), "subdir")
on.exit(unlink(tmp_outputDir, recursive = TRUE), add = TRUE)
expect_silent(copyDependencyToDir(dep, tmp_outputDir))
# copyDependencyToDir() creates the nested outputDir
expect_true(dir_exists(file.path(tmp_outputDir)))
# it moves the dependency into this dir
expect_true(dir_exists(file.path(tmp_outputDir, "simple-9.9.9")))
expect_true(file.exists(file.path(tmp_outputDir, "simple-9.9.9", "script.js")))
})
test_that("copyDependencyToDir() handles attributes", {
tmp_dep <- tempfile("dep")
dir.create(tmp_dep)
on.exit(unlink(tmp_dep))
tmp_txt <- "temp.txt"
path <- file.path(tmp_dep, tmp_txt)
writeLines("Some text in the text/plain dep", path)
tmp_js <- "javascript.js"
path <- file.path(tmp_dep, tmp_js)
writeLines('console.log("log message");', path)
tmp_rmd <- tempfile("rmd_files")
dir.create(tmp_rmd)
on.exit(unlink(tmp_rmd), add = TRUE)
dep_with_attributes <- htmltools::htmlDependency(
name = "textPlain",
version = "9.9.9",
src = tmp_dep,
script = list(src = tmp_txt, type = "text/plain"),
all_files = FALSE
)
dep_without <- htmltools::htmlDependency(
name = "textPlain",
version = "9.9.9",
src = tmp_dep,
script = tmp_js,
all_files = FALSE
)
dep_with_both <- htmltools::htmlDependency(
name = "textPlain",
version = "9.9.9",
src = tmp_dep,
script = list(tmp_js,
list(src = tmp_txt, type = "text/plain")),
all_files = FALSE
)
dep_with_one_nested <- htmltools::htmlDependency(
name = "textPlain",
version = "9.9.9",
src = tmp_dep,
script = list(list(src = tmp_txt, type = "text/plain")),
all_files = FALSE
)
dep_with_missings <- htmltools::htmlDependency(
name = "textPlain",
version = "9.9.9",
src = tmp_dep,
script = list(tmp_js,
"foobar1",
list(src = "foobar2")),
all_files = FALSE
)
# None of these except the last should trigger errors as
# the first two did in issue #320
copyDependencyToDir(dep_with_attributes, tmp_rmd)
expect_equal(dir(tmp_rmd, recursive = TRUE),
"textPlain-9.9.9/temp.txt")
unlink(dir(tmp_rmd, recursive = TRUE))
copyDependencyToDir(dep_with_both, tmp_rmd)
expect_equal(dir(tmp_rmd, recursive = TRUE),
c("textPlain-9.9.9/javascript.js",
"textPlain-9.9.9/temp.txt"))
unlink(dir(tmp_rmd, recursive = TRUE))
copyDependencyToDir(dep_without, tmp_rmd)
expect_equal(dir(tmp_rmd, recursive = TRUE),
"textPlain-9.9.9/javascript.js")
unlink(dir(tmp_rmd, recursive = TRUE))
copyDependencyToDir(dep_with_one_nested, tmp_rmd)
expect_equal(dir(tmp_rmd, recursive = TRUE),
"textPlain-9.9.9/temp.txt")
expect_error(copyDependencyToDir(dep_with_missings, tmp_rmd))
})