feat(search): add basket-mode argument validator
Internal .validate_basket_args() handles length validation and recycling of state/type from length 1. Foundation for basket mode.
This commit is contained in:
+38
@@ -120,3 +120,41 @@ cog_gov_search <- function(name = NULL, state = NULL, type = NULL) {
|
||||
WV = "54", WI = "55", WY = "56",
|
||||
AS = "60", GU = "66", MP = "69", PR = "72", VI = "78"
|
||||
)
|
||||
|
||||
# Validate basket-mode inputs. Returns a list with normalized character
|
||||
# vectors `name`, `state`, `type`, all of length n = length(name).
|
||||
# `state` and `type` of length 1 are recycled; lengths must be 1 or n
|
||||
# otherwise. NULL state/type become a vector of NA_character_.
|
||||
#' @noRd
|
||||
.validate_basket_args <- function(name, state, type) {
|
||||
if (!is.character(name)) {
|
||||
cli::cli_abort("`name` must be a character vector.")
|
||||
}
|
||||
n <- length(name)
|
||||
|
||||
state_norm <- if (is.null(state)) {
|
||||
rep(NA_character_, n)
|
||||
} else if (length(state) == 1L) {
|
||||
rep(as.character(state), n)
|
||||
} else if (length(state) == n) {
|
||||
as.character(state)
|
||||
} else {
|
||||
cli::cli_abort(
|
||||
"`state` must be length 1 or {n} (length of `name`); got {length(state)}."
|
||||
)
|
||||
}
|
||||
|
||||
type_norm <- if (is.null(type)) {
|
||||
rep(NA_character_, n)
|
||||
} else if (length(type) == 1L) {
|
||||
rep(as.character(type), n)
|
||||
} else if (length(type) == n) {
|
||||
as.character(type)
|
||||
} else {
|
||||
cli::cli_abort(
|
||||
"`type` must be length 1 or {n} (length of `name`); got {length(type)}."
|
||||
)
|
||||
}
|
||||
|
||||
list(name = name, state = state_norm, type = type_norm)
|
||||
}
|
||||
|
||||
@@ -72,3 +72,67 @@ test_that("cog_gov_search with no filters returns full registry", {
|
||||
r <- cog_gov_search()
|
||||
expect_gt(nrow(r), 1000L)
|
||||
})
|
||||
|
||||
# ---- basket mode internal helpers ----
|
||||
|
||||
test_that(".validate_basket_args recycles state from length 1", {
|
||||
out <- uscogdata:::.validate_basket_args(
|
||||
name = c("Broward", "San Diego", "Austin"),
|
||||
state = "FL",
|
||||
type = NULL
|
||||
)
|
||||
expect_equal(out$name, c("Broward", "San Diego", "Austin"))
|
||||
expect_equal(out$state, c("FL", "FL", "FL"))
|
||||
expect_equal(out$type, c(NA_character_, NA_character_, NA_character_))
|
||||
})
|
||||
|
||||
test_that(".validate_basket_args recycles type from length 1", {
|
||||
out <- uscogdata:::.validate_basket_args(
|
||||
name = c("San Diego", "Oakland"),
|
||||
state = "CA",
|
||||
type = "city"
|
||||
)
|
||||
expect_equal(out$type, c("city", "city"))
|
||||
})
|
||||
|
||||
test_that(".validate_basket_args accepts per-row state and type", {
|
||||
out <- uscogdata:::.validate_basket_args(
|
||||
name = c("Broward", "San Diego"),
|
||||
state = c("FL", "CA"),
|
||||
type = c(NA, "city")
|
||||
)
|
||||
expect_equal(out$state, c("FL", "CA"))
|
||||
expect_equal(out$type, c(NA_character_, "city"))
|
||||
})
|
||||
|
||||
test_that(".validate_basket_args rejects length-mismatched state", {
|
||||
expect_error(
|
||||
uscogdata:::.validate_basket_args(
|
||||
name = c("Broward", "San Diego", "Austin"),
|
||||
state = c("FL", "CA"),
|
||||
type = NULL
|
||||
),
|
||||
regexp = "must be length 1 or 3"
|
||||
)
|
||||
})
|
||||
|
||||
test_that(".validate_basket_args rejects length-mismatched type", {
|
||||
expect_error(
|
||||
uscogdata:::.validate_basket_args(
|
||||
name = c("Broward", "San Diego"),
|
||||
state = "FL",
|
||||
type = c("county", "city", "city")
|
||||
),
|
||||
regexp = "must be length 1 or 2"
|
||||
)
|
||||
})
|
||||
|
||||
test_that(".validate_basket_args allows NULL state and type", {
|
||||
out <- uscogdata:::.validate_basket_args(
|
||||
name = c("Broward", "San Diego"),
|
||||
state = NULL,
|
||||
type = NULL
|
||||
)
|
||||
expect_equal(out$state, c(NA_character_, NA_character_))
|
||||
expect_equal(out$type, c(NA_character_, NA_character_))
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user