@@ -319,3 +319,54 @@ test_that("limits with NA are replaced with the min/max of the data for continuo
319
319
expect_equal(make_scale(limits = c(1 , NA ), data = 1 : 5 )$ get_limits(), c(1 , 5 ))
320
320
expect_equal(make_scale(limits = c(NA , 5 ), data = 1 : 5 )$ get_limits(), c(1 , 5 ))
321
321
})
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