test_that("basic assert is idempotent", {
x <- new_vctr(1:4)
expect_true(vec_is(x))
expect_identical(vec_assert(x), x)
expect_identical(vec_assert(x), new_vctr(1:4))
expect_false(withVisible(vec_assert(x))$visible)
expect_true(vec_is(1:4))
expect_identical(vec_assert(1:4), 1:4)
})
test_that("asserting ptype", {
x <- new_vctr(1:4)
good <- new_vctr(integer())
expect_true(vec_is(x, good))
expect_error(vec_assert(x, good), NA)
# Is this the correct error message?
bad <- new_vctr(double())
expect_false(vec_is(x, bad))
expect_error(vec_assert(x, bad), class = "vctrs_error_assert_ptype")
})
test_that("asserting size", {
x <- new_vctr(1:4)
expect_true(vec_is(x, size = 4))
expect_error(vec_assert(x, size = 4), NA)
expect_false(vec_is(x, size = 5))
expect_error(vec_assert(x, size = 5), class = "vctrs_error_assert_size")
})
test_that("vec_assert() labels input", {
expect_error(
vec_assert(new_vctr(1:4), size = 5),
regexp = "`new_vctr\\(1:4\\)` must have",
class = "vctrs_error_assert_size"
)
expect_error(
vec_assert(new_vctr(1:4), size = 5, arg = "foobar"),
regexp = "`foobar` must have",
class = "vctrs_error_assert_size"
)
})
test_that("bare atomic vectors are vectors but not recursive", {
expect_true(obj_is_vector(TRUE))
expect_true(obj_is_vector(1L))
expect_true(obj_is_vector(1))
expect_true(obj_is_vector(1i))
expect_true(obj_is_vector("foo"))
expect_true(obj_is_vector(as.raw(1)))
})
test_that("S3 atomic vectors are vectors", {
expect_true(obj_is_vector(foobar(TRUE)))
expect_true(obj_is_vector(foobar(1L)))
expect_true(obj_is_vector(foobar(1)))
expect_true(obj_is_vector(foobar(1i)))
expect_true(obj_is_vector(foobar("foo")))
expect_true(obj_is_vector(foobar(as.raw(1))))
})
test_that("bare lists are vectors", {
expect_true(obj_is_vector(list()))
})
test_that("S3 lists are not vectors by default", {
expect_false(obj_is_vector(foobar()))
expect_false(obj_is_list(foobar()))
local_foobar_proxy()
# TODO: These seem inconsistent.
# Should we require that S3 list proxies satisfy `obj_is_list()`?
# (i.e. unclass themselves or explicitly inherit from `"list"`?)
expect_true(obj_is_vector(foobar()))
expect_false(obj_is_list(foobar()))
})
test_that("data frames and records are vectors", {
expect_true(obj_is_vector(mtcars))
expect_true(obj_is_vector(new_rcrd(list(x = 1, y = 2))))
})
test_that("non-vector base types are scalars", {
expect_identical(vec_typeof(quote(foo)), "scalar")
expect_identical(vec_typeof(pairlist("")), "scalar")
expect_identical(vec_typeof(function() NULL), "scalar")
expect_identical(vec_typeof(env()), "scalar")
expect_identical(vec_typeof(quote(foo)), "scalar")
expect_identical(vec_typeof(~foo), "scalar")
expect_identical(vec_typeof(base::`{`), "scalar")
expect_identical(vec_typeof(base::c), "scalar")
expect_identical(vec_typeof(expression()), "scalar")
expect_false(obj_is_vector(quote(foo)))
expect_false(obj_is_vector(pairlist("")))
expect_false(obj_is_vector(function() NULL))
expect_false(obj_is_vector(env()))
expect_false(obj_is_vector(~foo))
expect_false(obj_is_vector(base::`{`))
expect_false(obj_is_vector(base::c))
expect_false(obj_is_vector(expression()))
expect_false(vec_is(quote(foo)))
expect_false(vec_is(pairlist("")))
expect_false(vec_is(function() NULL))
expect_false(vec_is(env()))
expect_false(vec_is(~foo))
expect_false(vec_is(base::`{`))
expect_false(vec_is(base::c))
expect_false(vec_is(expression()))
expect_error(vec_assert(quote(foo)), class = "vctrs_error_scalar_type")
expect_error(vec_assert(pairlist("")), class = "vctrs_error_scalar_type")
expect_error(vec_assert(function() NULL), class = "vctrs_error_scalar_type")
expect_error(vec_assert(env()), class = "vctrs_error_scalar_type")
expect_error(vec_assert(~foo), class = "vctrs_error_scalar_type")
expect_error(vec_assert(base::`{`), class = "vctrs_error_scalar_type")
expect_error(vec_assert(base::c), class = "vctrs_error_scalar_type")
expect_error(vec_assert(expression()), class = "vctrs_error_scalar_type")
})
test_that("non-vector types can be proxied", {
x <- new_proxy(1:3)
expect_identical(vec_typeof(x), "scalar")
expect_false(obj_is_vector(x))
expect_false(vec_is(x))
expect_error(vec_assert(x), class = "vctrs_error_scalar_type")
local_env_proxy()
expect_identical(vec_typeof(x), "integer")
expect_true(obj_is_vector(x))
expect_true(vec_is(x))
expect_error(regexp = NA, vec_assert(x))
})
test_that("obj_check_vector() is silent on vectors", {
expect_null(obj_check_vector(1))
expect_null(obj_check_vector(data_frame()))
})
test_that("obj_check_vector() errors on scalars", {
expect_snapshot(error = TRUE, {
obj_check_vector(quote(foo))
})
expect_snapshot(error = TRUE, {
obj_check_vector(foobar())
})
})
test_that("obj_check_vector() error respects `arg` and `call`", {
my_check_vector <- function(foo) {
obj_check_vector(foo)
}
expect_snapshot(error = TRUE, {
my_check_vector(foobar())
})
})
test_that("vec_assert() uses friendly type in error messages", {
# Friendly type will be generated in rlang in the future. Upstream
# changes should not cause CRAN failures.
skip_on_cran()
expect_error(vec_assert(function() NULL), class = "vctrs_error_scalar_type")
})
test_that("vec_typeof() handles all types", {
for (i in seq_along(empty_types)) {
expect_identical(vec_typeof(!!empty_types[[i]]), !!names(empty_types)[[i]])
}
})
test_that("bare prototypes don't act as partial types", {
expect_false(vec_is(foobar(1), dbl()))
expect_error(vec_assert(foobar(1), dbl()), class = "vctrs_error_assert_ptype")
})
test_that("data frames are always classified as such even when dispatch is off", {
expect_identical(vec_typeof_bare(mtcars), "dataframe")
})
test_that("assertion is not applied on proxy", {
local_methods(
vec_proxy.vctrs_foobar = function(x, ...) unclass(x),
vec_restore.vctrs_foobar = function(x, ...) foobar(x),
`[.vctrs_foobar` = function(x, i) vec_slice(x, i)
)
x <- foobar(list())
expect_true(vec_is(x, x))
expect_false(vec_is(x, list()))
expect_error(vec_assert(x, list()), class = "vctrs_error_assert_ptype")
expect_error(vec_assert(x, x), regexp = NA)
})
test_that("attributes of unclassed vectors are asserted", {
x <- structure(FALSE, foo = "bar")
y <- structure(TRUE, foo = "bar")
expect_false(vec_is(x, FALSE))
expect_false(vec_is(FALSE, x))
expect_true(vec_is(y, x))
expect_true(vec_is(x, y))
})
test_that("unspecified is finalised before assertion", {
expect_true(vec_is(NA, TRUE))
expect_true(vec_is(data.frame(x = NA), data.frame(x = lgl())))
expect_error(regexp = NA, vec_assert(NA, TRUE))
expect_error(regexp = NA, vec_assert(data.frame(x = NA), data.frame(x = lgl())))
})
test_that("assertion failures are explained", {
local_no_stringsAsFactors()
local_options(rlang_backtrace_on_error = "none")
expect_snapshot(error = TRUE, vec_assert(lgl(), chr()))
expect_snapshot(error = TRUE, vec_assert(lgl(), factor()))
expect_snapshot(error = TRUE, vec_assert(lgl(), factor(levels = "foo")))
expect_snapshot(error = TRUE, vec_assert(factor(levels = "bar"), factor(levels = "foo")))
expect_snapshot(error = TRUE, vec_assert(factor(), chr()))
expect_snapshot(error = TRUE, vec_assert(lgl(), data.frame()))
expect_snapshot(error = TRUE, vec_assert(lgl(), data.frame(x = 1)))
expect_snapshot(error = TRUE, vec_assert(lgl(), data.frame(x = 1, y = 2)))
expect_snapshot(error = TRUE, vec_assert(data.frame(), chr()))
expect_snapshot(error = TRUE, vec_assert(data.frame(x = 1), chr()))
expect_snapshot(error = TRUE, vec_assert(data.frame(x = 1), data.frame(x = "foo")))
expect_snapshot(error = TRUE, vec_assert(data.frame(x = 1), data.frame(x = "foo", y = 2)))
expect_snapshot(error = TRUE, vec_assert(data.frame(x = 1, y = 2), chr()))
expect_snapshot(error = TRUE, vec_assert(data.frame(x = 1, y = 2), data.frame(x = "foo")))
expect_snapshot(error = TRUE, vec_assert(data.frame(x = 1, y = 2), data.frame(x = "foo", y = 2)))
})
test_that("vec_assert() validates `size` (#1470)", {
expect_snapshot({
(expect_error(vec_assert(1, size = c(2, 3))))
(expect_error(vec_assert(1, size = 1.5)))
(expect_error(vec_assert(1, size = "x")))
})
})
test_that("NULL is not a vector", {
expect_false(obj_is_vector(NULL))
expect_false(vec_is(NULL))
})
test_that("names and row names do not influence type identity (#707)", {
expect_true(vec_is(c(a = TRUE), logical()))
expect_true(vec_is(TRUE, c(a = TRUE)))
expect_true(vec_is(structure(mtcars, row.names = 1:32), mtcars))
expect_true(vec_is(mtcars, structure(mtcars, row.names = 1:32)))
})
# vec_check_size --------------------------------------------------------
test_that("vec_check_size() is silent if the size is right", {
expect_null(vec_check_size(1:5, size = 5L))
expect_null(vec_check_size(data_frame(.size = 10L), size = 10L))
})
test_that("vec_check_size() errors on the wrong size", {
expect_snapshot(error = TRUE, {
vec_check_size(1:5, size = 1L)
})
expect_snapshot(error = TRUE, {
vec_check_size(1:5, size = 10L)
})
})
test_that("vec_check_size() errors on scalars", {
expect_snapshot(error = TRUE, {
vec_check_size(quote(foo), size = 1L)
})
expect_snapshot(error = TRUE, {
vec_check_size(foobar(), size = 1L)
})
})
test_that("vec_check_size() error respects `arg` and `call`", {
my_check_size <- function(foo, size) {
vec_check_size(foo, size)
}
expect_snapshot(error = TRUE, {
my_check_size(1L, size = 5L)
})
expect_snapshot(error = TRUE, {
my_check_size(foobar(), size = 5L)
})
})
test_that("vec_check_size() validates `size`", {
expect_snapshot(error = TRUE, {
vec_check_size(1, size = "x")
})
expect_snapshot(error = TRUE, {
vec_check_size(1, size = c(1L, 2L))
})
expect_snapshot(error = TRUE, {
vec_check_size(1, size = 1.5)
})
})
# obj_is_list -----------------------------------------------------------
test_that("bare lists are lists", {
expect_true(obj_is_list(list()))
})
test_that("AsIs lists are lists (#1463)", {
expect_true(obj_is_list(I(list())))
expect_true(obj_is_list(I(list_of(1))))
expect_false(obj_is_list(I(double())))
})
test_that("list_of are lists", {
expect_true(obj_is_list(new_list_of()))
})
test_that("Vectors with a non-VECSXP type are not lists", {
expect_false(obj_is_list(1))
expect_false(obj_is_list("a"))
expect_false(obj_is_list(quote(name)))
})
test_that("explicitly classed lists are lists", {
x <- structure(list(), class = "list")
expect_true(obj_is_list(x))
expect_true(obj_is_list(subclass(x)))
})
test_that("explicit inheritance must be in the base class", {
x <- structure(1:2, class = c("list", "foobar"))
expect_false(obj_is_list(x))
})
test_that("POSIXlt are not considered a list", {
expect_false(obj_is_list(as.POSIXlt(new_datetime())))
})
test_that("rcrd types are not lists", {
expect_false(obj_is_list(new_rcrd(list(x = 1))))
})
test_that("scalars are not lists", {
expect_false(obj_is_list(foobar()))
})
test_that("S3 types can't lie about their internal representation", {
x <- structure(1:2, class = c("foobar", "list"))
expect_false(obj_is_list(x))
})
test_that("data frames of all types are not lists", {
expect_false(obj_is_list(data.frame()))
expect_false(obj_is_list(subclass(data.frame())))
expect_false(obj_is_list(tibble::tibble()))
})
test_that("S3 list with non-list proxy is still a list (#1208)", {
x <- structure(list(), class = c("foobar", "list"))
local_methods(vec_proxy.foobar = function(x) 1)
# This used to be an error (#1003)
# expect_error(obj_is_list(x), "`x` inherits")
expect_true(obj_is_list(x))
})
test_that("list-rcrds with data frame proxies are considered lists (#1208)", {
x <- structure(
list(1:2, "x"),
special = c("a", "b"),
class = c("list_rcrd", "list")
)
local_methods(
vec_proxy.list_rcrd = function(x) {
special <- attr(x, "special")
data <- unstructure(x)
new_data_frame(list(data = data, special = special))
}
)
expect_true(obj_is_list(x))
})
test_that("list_all_vectors() works", {
expect_true(list_all_vectors(list(1)))
expect_true(list_all_vectors(list_of(1)))
expect_false(list_all_vectors(list(1, env())))
expect_snapshot((expect_error(list_all_vectors(env()))))
})
test_that("obj_check_list() works", {
expect_null(obj_check_list(list(1)))
expect_null(obj_check_list(list_of(1)))
expect_snapshot({
my_function <- function(my_arg) obj_check_list(my_arg)
(expect_error(my_function(env())))
})
})
test_that("obj_check_list() uses a special error when `arg` is the empty string (#1604)", {
expect_snapshot(error = TRUE, {
obj_check_list(1, arg = "")
})
})
test_that("obj_check_list() and list_check_all_vectors() work", {
expect_null(list_check_all_vectors(list()))
expect_null(list_check_all_vectors(list(1, mtcars)))
expect_snapshot({
my_function <- function(my_arg) list_check_all_vectors(my_arg)
(expect_error(my_function(env())))
(expect_error(my_function(list(1, env()))))
(expect_error(my_function(list(1, name = env()))))
(expect_error(my_function(list(1, foo = env()))))
})
})
test_that("list_all_size() works", {
expect_true(list_all_size(list(), 2))
expect_true(list_all_size(list(integer()), 0))
expect_true(list_all_size(list(NULL), 0))
expect_true(list_all_size(list(1:2, 2:3), 2))
expect_false(list_all_size(list(1:2, 1:3), 2))
expect_false(list_all_size(list(NULL, 1:2), 2))
expect_true(list_all_size(list_of(1:3, 2:4), 3))
expect_false(list_all_size(list_of(1:3, 2:4), 4))
})
test_that("list_check_all_size() works", {
expect_null(list_check_all_size(list(), 2))
expect_null(list_check_all_size(list(integer()), 0))
expect_null(list_check_all_size(list(NULL), 0))
expect_null(list_check_all_size(list(1:2, 2:3), 2))
expect_snapshot({
my_function <- function(my_arg, size) list_check_all_size(my_arg, size)
# Validates sizes
(expect_error(list_check_all_size(list(1:2, 1:3), 2)))
(expect_error(my_function(list(1:2, 1:3), 2)))
# `NULL` is not ignored
(expect_error(my_function(list(NULL, 1:2), 2)))
})
})
test_that("list_all_size() and list_check_all_size() error on scalars", {
x <- list(env())
expect_snapshot({
# Error considered internal to `list_all_size()`
(expect_error(list_all_size(x, 2)))
my_function <- function(my_arg, size) list_check_all_size(my_arg, size)
(expect_error(my_function(x, 2)))
})
})
test_that("list_all_size() and list_check_all_size() throw error using internal call on non-list input", {
expect_snapshot({
(expect_error(list_all_size(1, 2)))
# `arg` and `call` are ignored
(expect_error(list_check_all_size(1, 2, arg = "arg", call = call("foo"))))
})
})
test_that("list_all_size() and list_check_all_size() validate `size`", {
expect_snapshot({
(expect_error(list_all_size(list(), size = "x")))
(expect_error(list_check_all_size(list(), size = "x")))
})
})
test_that("informative messages when 1d array doesn't match vector", {
x <- array(1:3)
expect_snapshot((expect_error(vec_assert(x, int()))))
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.