John
John

Reputation: 1947

How to test if ggplot was printed?

Let's consider very basic function :

plot_ggplot <- function() { 
    print(ggplot() + aes(x = 1:100, y = 1:100) + geom_point())
}

Is there any possibility to create sensible unit for such defined function ? I know that we can easily create unit testing when print is not included. Maybe is there possibility to check if something appears in plot window in R ?

I don't want to redefine the function because it's part of much bigger function.

Upvotes: 1

Views: 242

Answers (1)

teunbrand
teunbrand

Reputation: 38023

One possibility is to capture the device as a raster and check if all values are white, but I don't know how devices act in a testthat environment. You'd also have to dev.off() after every print and restart cap <- ragg::agg_capture() for every test, I think.

library(ggplot2)

cap <- ragg::agg_capture()

has_printed <- function(x = cap()) {
  !all(x == "white")
}

plot_ggplot <- function() { 
  print(ggplot() + aes(x = 1:100, y = 1:100) + geom_point())
}

has_printed()
#> [1] FALSE

plot_ggplot()

has_printed()
#> [1] TRUE

dev.off()
#> png 
#>   2
cap <- ragg::agg_capture()

has_printed()
#> [1] FALSE

Created on 2021-01-29 by the reprex package (v0.3.0)

EDIT: You can probably automate the resetting as part of the has_printed() function, but you'd have to be careful with superassignment (here be dragons).

library(ggplot2)

cap <- ragg::agg_capture()

has_printed <- function(x = cap()) {
  out <- !all(x == "white")
  dev.off()
  cap <<- ragg::agg_capture()
  return(out)
}

plot_ggplot <- function() { 
  print(ggplot() + aes(x = 1:100, y = 1:100) + geom_point())
}

has_printed()
#> [1] FALSE

plot_ggplot()

has_printed()
#> [1] TRUE

has_printed()
#> [1] FALSE

Created on 2021-01-29 by the reprex package (v0.3.0)

Upvotes: 3

Related Questions