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 check_aes() for gplot2 aesthetics #190

Open
richierocks opened this issue Jul 31, 2018 · 1 comment
Open

Add check_aes() for gplot2 aesthetics #190

richierocks opened this issue Jul 31, 2018 · 1 comment
Assignees

Comments

@richierocks
Copy link
Contributor

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:

  1. It's not intuitive, and
  2. 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.

@filipsch
Copy link
Contributor

filipsch commented Jul 31, 2018

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants