context("Themes") test_that("Modifying theme element properties with + operator", { # Changing a "leaf node" works t <- theme_grey() + theme(axis.title.x = element_text(colour='red')) expect_identical(t$axis.title.x, element_text(colour='red')) # Make sure the theme class didn't change or get dropped expect_true(is.theme(t)) # Make sure the element class didn't change or get dropped expect_true(inherits(t$axis.title.x, "element")) expect_true(inherits(t$axis.title.x, "element_text")) # Modifying an intermediate node works t <- theme_grey() + theme(axis.title = element_text(colour='red')) expect_identical(t$axis.title, element_text(colour='red')) # Modifying a root node changes only the specified properties t <- theme_grey() + theme(text = element_text(colour='red')) expect_identical(t$text$colour, 'red') expect_identical(t$text$family, theme_grey()$text$family) expect_identical(t$text$face, theme_grey()$text$face) expect_identical(t$text$size, theme_grey()$text$size) # Descendent is unchanged expect_identical(t$axis.title.x, theme_grey()$axis.title.x) # Adding element_blank replaces element t <- theme_grey() + theme(axis.text.y = element_blank()) expect_identical(t$axis.text.y, element_blank()) # Adding a non-blank element to an element_blank() replaces it t <- t + theme(axis.text.y = element_text(colour='red')) expect_identical(t$axis.text.y, element_text(colour='red')) # Adding empty theme() has no effect t <- theme_grey() + theme() expect_identical(t, theme_grey()) expect_error(theme_grey() + "asdf") }) test_that("Adding theme object to ggplot object with + operator", { p <- qplot(1:3, 1:3) p <- p + theme(axis.title = element_text(size = 20)) expect_true(p$theme$axis.title$size == 20) # Should update specified properties, but not reset other properties p <- p + theme(text = element_text(colour='red')) expect_true(p$theme$text$colour == 'red') tt <- theme_grey()$text tt$colour <- 'red' expect_identical(p$theme$text, tt) }) test_that("Replacing theme elements with %+replace% operator", { # Changing a "leaf node" works t <- theme_grey() %+replace% theme(axis.title.x = element_text(colour='red')) expect_identical(t$axis.title.x, element_text(colour='red')) # Make sure the class didn't change or get dropped expect_true(is.theme(t)) # Changing an intermediate node works t <- theme_grey() %+replace% theme(axis.title = element_text(colour='red')) expect_identical(t$axis.title, element_text(colour='red')) # Descendent is unchanged expect_identical(t$axis.title.x, theme_grey()$axis.title.x) # Adding empty theme() has no effect t <- theme_grey() %+replace% theme() expect_identical(t, theme_grey()) expect_error(theme_grey() + "asdf") }) test_that("Calculating theme element inheritance", { t <- theme_grey() + theme(axis.title = element_text(colour='red')) # Check that properties are passed along from axis.title to axis.title.x e <- calc_element('axis.title.x', t) expect_identical(e$colour, 'red') expect_false(is.null(e$family)) expect_false(is.null(e$face)) expect_false(is.null(e$size)) # Check that rel() works for relative sizing, and is applied at each level t <- theme_grey(base_size=12) + theme(axis.title = element_text(size=rel(0.5))) + theme(axis.title.x = element_text(size=rel(0.5))) e <- calc_element('axis.title', t) expect_identical(e$size, 6) ex <- calc_element('axis.title.x', t) expect_identical(ex$size, 3) # Check that a theme_blank in a parent node gets passed along to children t <- theme_grey() + theme(text = element_blank()) expect_identical(calc_element('axis.title.x', t), element_blank()) }) test_that("Complete and non-complete themes interact correctly with each other", { # The 'complete' attribute of t1 + t2 is the OR of their 'complete' attributes. # But for _element properties_, the one on the right modifies the one on the left. t <- theme_bw() + theme(text = element_text(colour='red')) expect_true(attr(t, "complete")) expect_equal(t$text$colour, 'red') # A complete theme object (like theme_bw) always trumps a non-complete theme object t <- theme(text = element_text(colour='red')) + theme_bw() expect_true(attr(t, "complete")) expect_equal(t$text$colour, theme_bw()$text$colour) # Adding two non-complete themes: the one on the right modifies the one on the left. t <- theme(text = element_text(colour='blue')) + theme(text = element_text(colour='red')) expect_false(attr(t, "complete")) expect_equal(t$text$colour, 'red') }) test_that("Complete and non-complete themes interact correctly with ggplot objects", { # Check that adding two theme successive theme objects to a ggplot object # works like adding the two theme object to each other p <- ggplot_build(qplot(1:3, 1:3) + theme_bw() + theme(text=element_text(colour='red'))) expect_true(attr(p$plot$theme, "complete")) # Compare the theme objects, after sorting the items, because item order can differ pt <- p$plot$theme tt <- theme_bw() + theme(text=element_text(colour='red')) pt <- pt[order(names(pt))] tt <- tt[order(names(tt))] expect_identical(pt, tt) p <- ggplot_build(qplot(1:3, 1:3) + theme(text=element_text(colour='red')) + theme_bw()) expect_true(attr(p$plot$theme, "complete")) # Compare the theme objects, after sorting the items, because item order can differ pt <- p$plot$theme tt <- theme(text=element_text(colour='red')) + theme_bw() pt <- pt[order(names(pt))] tt <- tt[order(names(tt))] expect_identical(pt, tt) p <- ggplot_build(qplot(1:3, 1:3) + theme(text=element_text(colour='red', face='italic'))) expect_false(attr(p$plot$theme, "complete")) expect_equal(p$plot$theme$text$colour, "red") expect_equal(p$plot$theme$text$face, "italic") p <- ggplot_build(qplot(1:3, 1:3) + theme(text=element_text(colour='red')) + theme(text=element_text(face='italic'))) expect_false(attr(p$plot$theme, "complete")) expect_equal(p$plot$theme$text$colour, "red") expect_equal(p$plot$theme$text$face, "italic") # Only gets red property; because of the way lists are processed in R, the # the second item doesn't get used properly. But I think that's OK. p <- ggplot_build(qplot(1:3, 1:3) + theme(text=element_text(colour='red'), text=element_text(face='italic'))) expect_false(attr(p$plot$theme, "complete")) expect_equal(p$plot$theme$text$colour, "red") expect_equal(p$plot$theme$text$face, "plain") })