testwhat
testwhat copied to clipboard
Add check_aes() for gplot2 aesthetics
I'm just starting to go through the ggplot2 courses updating SCTs to not use test_ggplot()
.
For a simple plot like this:
p <- ggplot(mtcars, aes(x = cyl, y = mpg)) +
geom_point()
I'm writing SCTs like this:
ex() %>% {
check_function(., 'ggplot') %>% {
check_arg(., 'data') %>% check_equal()
check_arg(., 'mapping') %>% check_function('aes') %>% {
check_arg(., 'x') %>% check_equal(eval = FALSE)
check_arg(., 'y') %>% check_equal(eval = FALSE)
}
}
check_function(., 'geom_point')
check_error(.)
}
So far, the most unsatisfying part is checking the aesthetics, since you always have to do eval = FALSE
.
ggplot2
v3 is built on top of rlang
, so I can now do
ex() %>%
check_expr("rlang::eval_tidy(p$mapping$x, p)$data)") %>%
check_result() %>%
check_equal()
This is great because I can check the object (and rlang
is always installed in the image because ggplot2
imports it).
There are 2 small problems:
- It's not intuitive, and
- It requires a custom message every time because "Running rlang::eval_tidy(p$mapping$x, p$data) didn't give the correct result." will scare all but the bravest students.
I think these problems can be nicely solved by having a check_aes()
that wraps this functionality.
Something like
check_aes <- function(state, plot, aesthetic) {
cmd <- sprintf("rlang::eval_tidy(%s$mapping[[%s]], %s$data)", plot, aesthetic, plot)
aes_error_msg <- sprintf("Evaluating the %s aesthetic for plot %s threw an error.", aesthetic, plot)
aes_incorrect_msg <- sprintf("The %s aesthetic for plot %s has the wrong value.", aesthetic, plot)
ex() %>%
check_expr(cmd) %>%
check_result(error_msg = aes_error_msg) %>%
check_equal(incorrect_msg = aes_incorrect_msg)
}
One bigger problem is that it requires that the student assign the plot to a variable. I thought I could use last_plot()
to retrieve the last plot that the students drew, but evaluation of that plot fails.
ex() %>%
check_expr("rlang::eval_tidy(last_plot()$mapping$x, last_plot()$data)") %>%
check_result() %>%
check_equal()
last_plot()
effectively does asNamespace("ggplot2")$.store$get()
, and I've no idea how testwhat
tries to evaluate that.
@richierocks I currently do not have time for this, but feel free to add this utility function in testwhat_ext
.. If you make a PR, I'll gladly review it.