diff --git a/R/has_columns.R b/R/has_columns.R index 3317b80f6..464d019a0 100644 --- a/R/has_columns.R +++ b/R/has_columns.R @@ -206,20 +206,23 @@ has_columns <- function( allow_empty = FALSE, call = .call), error = function(cnd) cnd ) - ## Check for error from {tidyselect} + ## If error from {tidyselect}, counts as no selection if (rlang::is_error(columns)) { cnd <- columns # Rethrow error if genuine evaluation error if (inherits(cnd, "resolve_eval_err")) { rlang::cnd_signal(cnd) } - # 0-vector if "column not found" or "0 columns" error + # Return length-0 vector if "column not found" or "0 columns" error return(character(0L)) + } else { + ## If columns succesfully resolved to character, return only existing ones + return(intersect(columns, colnames(x))) } - # vector of selections if successful - return(columns) } + # A list of columns (character vector) selected by elements of `columns` + # - Ex: `c(a, b:c)` becomes `list("a", c("b", "c"))` if data has those columns columns_list <- lapply(column_quos, has_column) all(lengths(columns_list) > 0L) diff --git a/tests/testthat/test-has_columns.R b/tests/testthat/test-has_columns.R index 10b4e76d9..820ac84b3 100644 --- a/tests/testthat/test-has_columns.R +++ b/tests/testthat/test-has_columns.R @@ -9,8 +9,12 @@ test_that("the `has_columns()` function works when used directly with data", { expect_true(small_table %>% has_columns(c(vars(a, b), vars(c)))) # Expect FALSE when *any* of the given column names is absent - expect_false(small_table %>% has_columns(vars(a, h))) - expect_false(small_table %>% has_columns(vars(h, j))) + expect_false(small_table %>% has_columns(vars(z))) + expect_false(small_table %>% has_columns("z")) + expect_false(small_table %>% has_columns(vars(a, z))) + expect_false(small_table %>% has_columns(vars(z, zz))) + expect_false(small_table %>% has_columns(c("a", "z"))) + expect_false(small_table %>% has_columns(c("z", "zz"))) # Expect that using inputs that are not tabular result in errors expect_error(has_columns(list(a = "2"), "a")) @@ -34,6 +38,9 @@ test_that("the `has_columns()` function works with tidyselect", { expect_false(small_table %>% has_columns(last_col() + 1)) expect_false(small_table %>% has_columns(matches("z"))) + # Expect FALSE when *any* of the given column names is absent + expect_false(small_table %>% has_columns(c(a, z))) + # Genuine evaluation errors are re-thrown and short-circuits expect_error(small_table %>% has_columns(stop("Oh no!")), "Oh no!") expect_error(small_table %>% has_columns(c(stop("Oh no!"))), "Oh no!")