@@ -319,3 +319,54 @@ test_that("limits with NA are replaced with the min/max of the data for continuo
319319 expect_equal(make_scale(limits = c(1 , NA ), data = 1 : 5 )$ get_limits(), c(1 , 5 ))
320320 expect_equal(make_scale(limits = c(NA , 5 ), data = 1 : 5 )$ get_limits(), c(1 , 5 ))
321321})
322+
323+ test_that(" scale_apply preserves class and attributes" , {
324+ df <- data_frame(
325+ x = structure(c(1 , 2 ), foo = " bar" , class = c(" baz" , " numeric" )),
326+ y = c(1 , 1 ),
327+ z = c(" A" , " B" )
328+ )
329+
330+ # Functions to make the 'baz'-class more type stable
331+ `c.baz` <- function (... ) {
332+ dots <- list (... )
333+ attris <- attributes(dots [[1 ]])
334+ x <- do.call(" c" , lapply(dots , unclass ))
335+ attributes(x ) <- attris
336+ x
337+ }
338+ `[.baz` <- function (x , i ) {
339+ attris <- attributes(x )
340+ x <- unclass(x )[i ]
341+ attributes(x ) <- attris
342+ x
343+ }
344+
345+ plot <- ggplot(df , aes(x , y )) +
346+ scale_x_continuous() +
347+ # Facetting such that 2 x-scales will exist, i.e. `x` will be subsetted
348+ facet_grid(~ z , scales = " free_x" )
349+ plot <- ggplot_build(plot )
350+
351+ # Perform identity transformation via `scale_apply`
352+ out <- with_bindings(scale_apply(
353+ df , " x" , " transform" , 1 : 2 , plot $ layout $ panel_scales_x
354+ )[[1 ]], `c.baz` = `c.baz` , `[.baz` = `[.baz` , .env = global_env())
355+
356+ # Check class preservation
357+ expect_is(out , " baz" )
358+ expect_is(out , " numeric" )
359+
360+ # Check attribute preservation
361+ expect_identical(attr(out , " foo" ), " bar" )
362+
363+ # Negative control: non-type stable classes don't preserve attributes
364+ class(df $ x ) <- " foobar"
365+
366+ out <- with_bindings(scale_apply(
367+ df , " x" , " transform" , 1 : 2 , plot $ layout $ panel_scales_x
368+ )[[1 ]], `c.baz` = `c.baz` , `[.baz` = `[.baz` , .env = global_env())
369+
370+ expect_false(inherits(out , " foobar" ))
371+ expect_null(attributes(out ))
372+ })
0 commit comments