feat(search): basket mode for cog_gov_search() #1

Merged
jared merged 12 commits from feat/cog-gov-search-basket-mode into main 2026-04-28 15:09:44 -04:00
2 changed files with 102 additions and 0 deletions
Showing only changes of commit 7fd29c919d - Show all commits
+38
View File
@@ -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)
}
+64
View File
@@ -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_))
})