Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add {cli} error messaging for assert_one_to_one() #427

Merged
merged 16 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 65 additions & 15 deletions R/assertions.R
Original file line number Diff line number Diff line change
Expand Up @@ -1605,6 +1605,12 @@ assert_list_element <- function(list,
#'
#' @param vars2 Second list of variables
#'
#' @param message string passed to `cli::cli_abort(message)`. When `NULL`, default messaging
#' is used (see examples for default messages). `"dataset_name"` can be used in messaging.
#'
#' @param dataset_name string indicating the label/symbol of the object being checked.
#' Default is `rlang::caller_arg(dataset)`.
#' @inheritParams assert_logical_scalar
#'
#' @return
#' An error if the condition is not meet. The input otherwise.
Expand All @@ -1613,7 +1619,40 @@ assert_list_element <- function(list,
#' @family assertion
#' @export
#'
ddsjoberg marked this conversation as resolved.
Show resolved Hide resolved
assert_one_to_one <- function(dataset, vars1, vars2) {
#' @examples
#' library(dplyr)
#' library(rlang)
#'
#' df <- tribble(
#' ~SPECIES, ~SPECIESN,
#' "DOG", 1L,
#' "CAT", 2L,
#' "DOG", 1L
#' )
#'
#' assert_one_to_one(df, vars1 = exprs(SPECIES), vars2 = exprs(SPECIESN))
#'
#' df_many <- tribble(
#' ~SPECIES, ~SPECIESN,
#' "DOG", 1L,
#' "CAT", 2L,
#' "DOG", 3L
#' )
#'
#' try(
#' assert_one_to_one(df_many, vars1 = exprs(SPECIES), vars2 = exprs(SPECIESN))
#' )
#'
#' try(
#' assert_one_to_one(df_many, vars1 = exprs(SPECIESN), vars2 = exprs(SPECIES))
#' )
assert_one_to_one <- function(dataset,
vars1,
vars2,
dataset_name = rlang::caller_arg(dataset),
message = NULL,
class = "assert_one_to_one",
call = parent.frame()) {
assert_vars(vars1)
assert_vars(vars2)
assert_data_frame(dataset, required_vars = expr_c(vars1, vars2))
Expand All @@ -1623,34 +1662,45 @@ assert_one_to_one <- function(dataset, vars1, vars2) {
group_by(!!!vars1) %>%
filter(n() > 1) %>%
arrange(!!!vars1)

if (nrow(one_to_many) > 0) {
admiraldev_environment$one_to_many <- one_to_many
abort(
paste0(
"For some values of ",
vars2chr(vars1),
" there is more than one value of ",
vars2chr(vars2),
".\nCall `get_one_to_many_dataset()` to get all one to many values."

message <- message %||%
c("For some values of {.val {vars2chr(vars1)}} there is more than one
value of {.val {vars2chr(vars2)}}",
"i" = "Call {.fun get_one_to_many_dataset} to get all one-to-many values."
)

cli::cli_abort(
message = message,
call = call,
class = c(class, "assert-admiraldev")
)
}

many_to_one <- uniques %>%
group_by(!!!vars2) %>%
filter(n() > 1) %>%
arrange(!!!vars2)

if (nrow(many_to_one) > 0) {
admiraldev_environment$many_to_one <- many_to_one
abort(
paste0(
"There is more than one value of ",
vars2chr(vars1),
" for some values of ",
vars2chr(vars2),
".\nCall `get_many_to_one_dataset()` to get all many to one values."

message <- message %||%
c("There is more than one value of {.val {vars2chr(vars1)}} for some
values of {.val {vars2chr(vars2)}}",
"i" = "Call {.fun get_many_to_one_dataset} to get all many-to-one values."
)

cli::cli_abort(
message = message,
call = call,
class = c(class, "assert-admiraldev")
)
}

invisible(dataset)
}

#' Is a Variable in a Dataset a Date or Datetime Variable?
Expand Down
60 changes: 59 additions & 1 deletion man/assert_one_to_one.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 13 additions & 4 deletions tests/testthat/_snaps/assertions.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,31 +261,40 @@
! List element "val" must be `>=0` in argument `input`:
i But, `input[[2]]$val = -1`, and `input[[3]]$val = -2`

# assert_date_var Test 86: error if variable is not a date or datetime variable
# assert_one_to_one Test 84: error if there is a one to many mapping

Code
assert_one_to_one(pharmaversesdtm::dm, exprs(DOMAIN), exprs(USUBJID))
Condition
Error:
! For some values of "DOMAIN" there is more than one value of "USUBJID"
i Call `get_one_to_many_dataset()` to get all one-to-many values.

# assert_date_var Test 87: error if variable is not a date or datetime variable

Code
example_fun(dataset = my_data, var = USUBJID)
Condition
Error in `example_fun()`:
! Column "USUBJID" in dataset `dataset` must be a date or datetime, but is a character vector.

# assert_date_vector Test 90: error if `arg` is NULL and optional is FALSE
# assert_date_vector Test 91: error if `arg` is NULL and optional is FALSE

Code
example_fun(NULL)
Condition
Error in `example_fun()`:
! Argument `arg` must be a date or datetime, but is NULL.

# assert_atomic_vector Test 91: error if input is not atomic vector
# assert_atomic_vector Test 92: error if input is not atomic vector

Code
assert_atomic_vector(x)
Condition
Error:
! Argument `x` must be an atomic vector, but is a list.

# assert_same_type Test 93: error if different type
# assert_same_type Test 94: error if different type

Code
assert_same_type(true_value, false_value, missing_value)
Expand Down
62 changes: 43 additions & 19 deletions tests/testthat/test-assertions.R
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,13 @@ test_that("assert_list_element Test 83: error if the elements do not fulfill the
## Test 84: error if there is a one to many mapping ----
test_that("assert_one_to_one Test 84: error if there is a one to many mapping", {
expect_error(
assert_one_to_one(pharmaversesdtm::dm, exprs(DOMAIN), exprs(USUBJID)),
class = "assert_one_to_one"
)
admiraldev_environment$one_to_many <- NULL

expect_snapshot(
error = TRUE,
assert_one_to_one(pharmaversesdtm::dm, exprs(DOMAIN), exprs(USUBJID))
)
admiraldev_environment$one_to_many <- NULL
Expand All @@ -1276,14 +1283,31 @@ test_that("assert_one_to_one Test 84: error if there is a one to many mapping",
## Test 85: error if there is a many to one mapping ----
test_that("assert_one_to_one Test 85: error if there is a many to one mapping", {
expect_error(
assert_one_to_one(pharmaversesdtm::dm, exprs(USUBJID), exprs(DOMAIN))
assert_one_to_one(pharmaversesdtm::dm, exprs(USUBJID), exprs(DOMAIN)),
class = "assert_one_to_one"
)
admiraldev_environment$many_to_one <- NULL
})

## Test 86: dataset is returned invisible if one-to-one ----
test_that("assert_one_to_one Test 86: dataset is returned invisible if one-to-one", {
df <- tibble::tribble(
~SPECIES, ~SPECIESN,
"DOG", 1L,
"CAT", 2L,
"DOG", 1L
)

df_out <- expect_invisible(
assert_one_to_one(df, vars1 = exprs(SPECIES), vars2 = exprs(SPECIESN))
)

expect_equal(df_out, expected = df)
})

# assert_date_var ----
## Test 86: error if variable is not a date or datetime variable ----
test_that("assert_date_var Test 86: error if variable is not a date or datetime variable", {
## Test 87: error if variable is not a date or datetime variable ----
test_that("assert_date_var Test 87: error if variable is not a date or datetime variable", {
example_fun <- function(dataset, var) {
var <- assert_symbol(enexpr(var))
assert_date_var(dataset = dataset, var = !!var)
Expand Down Expand Up @@ -1311,18 +1335,18 @@ test_that("assert_date_var Test 86: error if variable is not a date or datetime
})

# assert_date_vector ----
## Test 87: returns error if input vector is not a date formatted ----
test_that("assert_date_vector Test 87: returns error if input vector is not a date formatted", {
## Test 88: returns error if input vector is not a date formatted ----
test_that("assert_date_vector Test 88: returns error if input vector is not a date formatted", {
expect_error(assert_date_vector("2018-08-23"))
})

## Test 88: returns invisible if input is date formatted ----
test_that("assert_date_vector Test 88: returns invisible if input is date formatted", {
## Test 89: returns invisible if input is date formatted ----
test_that("assert_date_vector Test 89: returns invisible if input is date formatted", {
expect_invisible(assert_date_vector(as.Date("2022-10-25")))
})

## Test 89: no error if `arg` is NULL and optional is TRUE ----
test_that("assert_date_vector Test 89: no error if `arg` is NULL and optional is TRUE", {
## Test 90: no error if `arg` is NULL and optional is TRUE ----
test_that("assert_date_vector Test 90: no error if `arg` is NULL and optional is TRUE", {
example_fun <- function(arg) {
assert_date_vector(arg, optional = TRUE)
}
Expand All @@ -1332,8 +1356,8 @@ test_that("assert_date_vector Test 89: no error if `arg` is NULL and optional is
)
})

## Test 90: error if `arg` is NULL and optional is FALSE ----
test_that("assert_date_vector Test 90: error if `arg` is NULL and optional is FALSE", {
## Test 91: error if `arg` is NULL and optional is FALSE ----
test_that("assert_date_vector Test 91: error if `arg` is NULL and optional is FALSE", {
example_fun <- function(arg) {
assert_date_vector(arg, optional = FALSE)
}
Expand All @@ -1350,8 +1374,8 @@ test_that("assert_date_vector Test 90: error if `arg` is NULL and optional is FA


# assert_atomic_vector ----
## Test 91: error if input is not atomic vector ----
test_that("assert_atomic_vector Test 91: error if input is not atomic vector", {
## Test 92: error if input is not atomic vector ----
test_that("assert_atomic_vector Test 92: error if input is not atomic vector", {
x <- list("a", "a", "b", "c", "d", "d", 1, 1, 4)
expect_error(assert_atomic_vector(x), class = "assert_atomic_vector")
expect_snapshot(
Expand All @@ -1361,15 +1385,15 @@ test_that("assert_atomic_vector Test 91: error if input is not atomic vector", {
})

# assert_same_type ----
## Test 92: no error if same type ----
test_that("assert_same_type Test 92: no error if same type", {
## Test 93: no error if same type ----
test_that("assert_same_type Test 93: no error if same type", {
true_value <- "Y"
false_value <- "N"
expect_invisible(assert_same_type(true_value, false_value))
})

## Test 93: error if different type ----
test_that("assert_same_type Test 93: error if different type", {
## Test 94: error if different type ----
test_that("assert_same_type Test 94: error if different type", {
true_value <- "Y"
false_value <- "N"
missing_value <- 0
Expand All @@ -1385,8 +1409,8 @@ test_that("assert_same_type Test 93: error if different type", {
)
})

## Test 94: works as intended ----
test_that("assert_same_type Test 94: works as intended", {
## Test 95: works as intended ----
test_that("assert_same_type Test 95: works as intended", {
expect_equal(
valid_time_units(),
c("years", "months", "days", "hours", "minutes", "seconds")
Expand Down
3 changes: 3 additions & 0 deletions tests/testthat/test-get.R
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ test_that("get_source_vars Test 6: no source vars returns NULL", {
# get_dataset ----
## Test 7: get_dataset works ----
test_that("get_dataset Test 7: get_dataset works", {
admiraldev_environment$many_to_one <- NULL
admiraldev_environment$one_to_many <- NULL

expect_equal(NULL, get_dataset("one_to_many"))
})

Expand Down
Loading