Nothing
# R MATCHES A NAMED ARGUMENT BY PREFIX, NOT BY STRING EQUALITY.
#
# For a named argument that is not an exact formal, R looks for a prefix that is
# unambiguous among the formals the call has not matched yet. Neither `library()`
# nor `require()` has a `...`, and only `character.only` starts with "char", so
# `library(pkgvar, char = TRUE)` runs with character.only effectively TRUE.
#
# Matching the flag by string equality therefore misses the abbreviated spelling
# and reads the variable's own symbol as the package name, which is the very
# defect of #143. And matching the `package` argument by string equality misses
# `library(pack = "jsonlite")`, a real dependency, the same cause turned the other
# way round.
pkgs_of <- function(lines) {
script <- tempfile(fileext = ".R")
writeLines(lines, script)
return(att_from_rscript(path = script))
}
test_that("an abbreviated character.only is honoured, whatever the abbreviation", {
for (flag in c("character.only", "character.onl", "character", "char", "c")) {
res <- pkgs_of(sprintf("library(pkgvar, %s = TRUE)", flag))
expect_false("pkgvar" %in% res, info = flag)
}
})
test_that("an abbreviated character.only is honoured on require() too", {
for (flag in c("character.only", "character.o", "char", "c")) {
res <- pkgs_of(sprintf("require(pkgvar, %s = TRUE)", flag))
expect_false("pkgvar" %in% res, info = flag)
}
})
test_that("an abbreviated character.only set to FALSE still reads the symbol", {
res <- pkgs_of("library(findme1, char = FALSE)")
expect_true("findme1" %in% res)
})
test_that("an abbreviated package argument is matched", {
expect_true("jsonlite" %in% pkgs_of('library(pack = "jsonlite")'))
expect_true("jsonlite" %in% pkgs_of('require(packa = "jsonlite")'))
expect_true("jsonlite" %in% pkgs_of('requireNamespace(pack = "jsonlite", quietly = TRUE)'))
expect_true("jsonlite" %in% pkgs_of('loadNamespace(pac = "jsonlite")'))
})
test_that("an abbreviated ns argument of getFromNamespace is matched", {
expect_true("jsonlite" %in% pkgs_of('getFromNamespace("f", n = "jsonlite")'))
})
test_that("an ambiguous prefix is not matched, and nothing crashes", {
# `library()` has both `package` and `pos`, so "p" names neither. R would stop
# on this call; the parser must simply decline to guess.
expect_silent(res <- pkgs_of('library(pkgvar, p = TRUE)'))
expect_true(is.character(res))
})
test_that("the exact spellings keep working", {
expect_false("pkgvar" %in% pkgs_of("library(pkgvar, character.only = TRUE)"))
expect_true("jsonlite" %in% pkgs_of('library(package = "jsonlite")'))
expect_true("jsonlite" %in% pkgs_of('requireNamespace(package = "jsonlite", quietly = TRUE)'))
expect_true("findme1" %in% pkgs_of("library(findme1)"))
expect_true("findme2" %in% pkgs_of("require(findme2)"))
expect_false("pkg" %in% pkgs_of("requireNamespace(pkg, quietly = TRUE)"))
})
test_that("the formals come from the running R, not from a table written here", {
f <- pkg_intro_formals("library")
expect_identical(f, names(formals(base::library)))
expect_true("character.only" %in% f)
})
test_that("an unknown call yields no formals, so no partial matching is attempted", {
expect_identical(pkg_intro_formals("il.n.existe.pas"), character(0))
expect_true(is.na(match_named_arg(
c("", "cha"), arg_name = "character.only", formals_names = character(0)
)))
})
test_that("a formal placed after ... is matched by its exact name only", {
# R's own rule, not a precaution: anything shorter falls into the dots.
# `requireNamespace()` is `(package, ..., quietly)` on current R.
f <- pkg_intro_formals("requireNamespace")
skip_if_not("..." %in% f, "this R has no ... in requireNamespace()")
expect_gt(match("quietly", table = f), match("...", table = f))
expect_true(is.na(match_named_arg(
c("", "quiet"), arg_name = "quietly", formals_names = f
)))
expect_equal(
match_named_arg(c("", "quietly"), arg_name = "quietly", formals_names = f),
2L
)
# `package` sits before the dots, so it does abbreviate.
expect_equal(
match_named_arg(c("pack"), arg_name = "package", formals_names = f), 1L
)
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.