-
Notifications
You must be signed in to change notification settings - Fork 10
refactor: use checkmate for arg validation #286
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
Conversation
@@ -44,7 +44,7 @@ test_that("scalar", { | |||
test_that("numeric", { | |||
expect_silent(arg_is_numeric(i, j, x, y)) | |||
expect_error(arg_is_numeric(a)) | |||
expect_error(arg_is_numeric(d)) | |||
expect_silent(arg_is_numeric(d)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dates now pass arg_is_numeric
, this didn't affect the rest of the tests.
@@ -56,7 +56,7 @@ test_that("numeric", { | |||
test_that("positive", { | |||
expect_silent(arg_is_pos(i, j, x, y)) | |||
expect_error(arg_is_pos(a)) | |||
expect_error(arg_is_pos(d)) | |||
expect_silent(arg_is_pos(d)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dates now pass arg_is_positive
, this didn't affect the rest of the tests.
@@ -68,7 +68,7 @@ test_that("positive", { | |||
test_that("nonneg", { | |||
expect_silent(arg_is_nonneg(i, j, x, y)) | |||
expect_error(arg_is_nonneg(a)) | |||
expect_error(arg_is_nonneg(d)) | |||
expect_silent(arg_is_nonneg(d)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dates now pass arg_is_nonneg
, this didn't affect the rest of the tests.
@@ -96,7 +96,8 @@ test_that("date", { | |||
expect_error(arg_is_date(d, dd, n)) | |||
expect_error(arg_is_date(d, dd, nn)) | |||
expect_silent(arg_is_date(d, dd, n, allow_null = TRUE)) | |||
expect_silent(arg_is_date(d, dd, nn, allow_na = TRUE)) | |||
# Upstream issue, see: https://github.com/mllg/checkmate/issues/256 | |||
# expect_silent(arg_is_date(d, dd, nn, allow_na = TRUE)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to remove allow_na
from arg_is_date
, due to a checkmate inconsistency, but this didn't affect the rest of the tests.
expect_silent(arg_is_sorted(b = NULL, allow_null = TRUE)) | ||
}) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These weren't used anywhere and checkmate supports a sorted check for some data types, so I figured we could rely on that when we need it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do these changes result in reasonable/interpretable error messages (still get the argument names correct in the error message, etc.) Can you maybe show an example in the PR comments?
Good question right, I brought back the r$> r1 <- epi_recipe(x) %>%
step_epi_ahead(death_rate, ahead = 3.6) %>%
step_epi_lag(death_rate, lag = 1.9)
Error in (function (name, value) :
Assertion on 'ahead' failed: Must be of type 'integerish', but element 1 is not close to an integer.
r$> r2 <- epi_recipe(x) %>%
step_epi_ahead(death_rate, ahead = 7) %>%
step_epi_lag(death_rate, lag = -7)
Error in (function (name, value) :
Assertion on 'lag' failed: Element 1 is not >= 0.
r$> step_growth_rate(r, value, role = 1)
Error in (function (name, value) :
Assertion on 'role' failed: Must be of type 'character', not 'double'.
r$> step_growth_rate(r, value, horizon = 0)
Error in (function (name, value) :
Assertion on 'horizon' failed: Element 1 is not >= 1. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps for a future Issue: it would be nice if those error messages more specifically described the calling function in which the error occurred.
FWIW, r$> r1 <- epi_recipe(x) %>%
step_epi_ahead(death_rate, ahead = 3.6) %>%
step_epi_lag(death_rate, lag = 1.9)
Error in (function (name, value) :
Assertion on 'ahead' failed: Must be of type 'integerish', but element 1 is not close to an integer.
r$> traceback()
15: stop(simpleError(sprintf(msg, ...), call.))
14: mstop("Assertion on '%s' failed: %s.", var.name, res, call. = sys.call(-2L))
13: makeAssertion(x, res, .var.name, add)
12: assert_integerish(value, null.ok = allow_null, lower = 0, any.missing = FALSE,
.var.name = name) at utils-arg.R#63
11: (function (name, value)
{
assert_integerish(value, null.ok = allow_null, lower = 0,
any.missing = FALSE, .var.name = name)
})(dots[[1L]][[1L]], dots[[2L]][[1L]])
10: mapply(.f, .x, .y, MoreArgs = list(...), SIMPLIFY = FALSE) at compat-purrr.R#72
9: map2(.x, .y, .f, ...) at compat-purrr.R#15
8: walk2(names, values, .tests) at utils-arg.R#10
7: handle_arg_list(..., .tests = function(name, value) {
assert_integerish(value, null.ok = allow_null, lower = 0,
any.missing = FALSE, .var.name = name)
}) at utils-arg.R#62
6: arg_is_nonneg_int(ahead) at step_epi_shift.R#126
5: step_epi_ahead(., death_rate, ahead = 3.6)
4: inherits(x, "epi_recipe") at epi_recipe.R#221
3: is_epi_recipe(recipe) at step_epi_shift.R#64
2: step_epi_lag(., death_rate, lag = 1.9)
1: epi_recipe(x) %>% step_epi_ahead(death_rate, ahead = 3.6) %>%
step_epi_lag(death_rate, lag = 1.9) |
True, though it would be nice if |
Related to cmu-delphi/epiprocess#403.
I took the safe approach of changing the internals of the arg functions to use
checkmate
, that way we can rely on the existing unit tests and don't need to change any other epipredict code. The functions look a lot simpler and more unified now. We could eventually get rid of these wrappers and just invoke check functions directly, but that would take more refactoring work.