Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Use vdiffr for visual unit tests #1874

Merged
merged 11 commits into from Feb 1, 2017
View
@@ -2,6 +2,13 @@ language: R
cache: packages
sudo: false
+addons:
+ apt:
+ sources:
+ - debian-sid
+ packages:
+ - libfreetype6
+
r_github_packages:
- hadley/staticdocs@old
View
@@ -36,6 +36,7 @@ Suggests:
multcomp,
nlme,
testthat (>= 0.11.0),
+ vdiffr,
quantreg,
knitr,
rpart,
@@ -217,3 +218,4 @@ Collate:
'zzz.r'
VignetteBuilder: knitr
RoxygenNote: 6.0.0
+Remotes: hadley/svglite
View
@@ -476,6 +476,7 @@ export(theme_linedraw)
export(theme_minimal)
export(theme_replace)
export(theme_set)
+export(theme_test)
export(theme_update)
export(theme_void)
export(transform_position)
View
@@ -1,5 +1,7 @@
# ggplot2 2.2.1.9000
+* Automatic visual unit tests with vdiffr.
+
* Layers no longer warn about unknown aesthetics who's value is set to
`NULL` (overriding a set aesthetic in the plot) (#1909).
View
@@ -40,6 +40,10 @@
#' \item{\code{theme_void}}{
#' A completely empty theme.}
#'
+#' \item{\code{theme_test}}{
+#' A theme for visual unit tests. It should ideally never change except
+#' for new features.}
+#'
#' }
#'
#' @examples
@@ -341,3 +345,110 @@ theme_void <- function(base_size = 11, base_family = "") {
)
}
+#' @export
+#' @rdname ggtheme
+theme_test <- function(base_size = 11, base_family = "") {
+ half_line <- base_size / 2
+
+ theme(
+ line = element_line(colour = "black", size = 0.5, linetype = 1,
+ lineend = "butt"),
+ rect = element_rect(fill = "white", colour = "black",
+ size = 0.5, linetype = 1),
+ text = element_text(
+ family = base_family, face = "plain",
+ colour = "black", size = base_size,
+ lineheight = 0.9, hjust = 0.5, vjust = 0.5, angle = 0,
+ margin = margin(), debug = FALSE
+ ),
+
+ axis.line = element_blank(),
+ axis.line.x = NULL,
+ axis.line.y = NULL,
+ axis.text = element_text(size = rel(0.8), colour = "grey30"),
+ axis.text.x = element_text(margin = margin(t = 0.8 * half_line / 2), vjust = 1),
+ axis.text.x.top = element_text(margin = margin(b = 0.8 * half_line / 2), vjust = 0),
+ axis.text.y = element_text(margin = margin(r = 0.8 * half_line / 2), hjust = 1),
+ axis.text.y.right = element_text(margin = margin(l = 0.8 * half_line / 2), hjust = 0),
+ axis.ticks = element_line(colour = "grey20"),
+ axis.ticks.length = unit(half_line / 2, "pt"),
+ axis.title.x = element_text(
+ margin = margin(t = half_line),
+ vjust = 1
+ ),
+ axis.title.x.top = element_text(
+ margin = margin(b = half_line),
+ vjust = 0
+ ),
+ axis.title.y = element_text(
+ angle = 90,
+ margin = margin(r = half_line),
+ vjust = 1
+ ),
+ axis.title.y.right = element_text(
+ angle = -90,
+ margin = margin(l = half_line),
+ vjust = 0
+ ),
+
+ legend.background = element_rect(colour = NA),
+ legend.spacing = unit(0.4, "cm"),
+ legend.spacing.x = NULL,
+ legend.spacing.y = NULL,
+ legend.margin = margin(0, 0, 0, 0, "cm"),
+ legend.key = element_rect(fill = "white", colour=NA),
+ legend.key.size = unit(1.2, "lines"),
+ legend.key.height = NULL,
+ legend.key.width = NULL,
+ legend.text = element_text(size = rel(0.8)),
+ legend.text.align = NULL,
+ legend.title = element_text(hjust = 0),
+ legend.title.align = NULL,
+ legend.position = "right",
+ legend.direction = NULL,
+ legend.justification = "center",
+ legend.box = NULL,
+ legend.box.margin = margin(0, 0, 0, 0, "cm"),
+ legend.box.background = element_blank(),
+ legend.box.spacing = unit(0.4, "cm"),
+
+ panel.background = element_rect(fill = "white", colour = NA),
+ panel.border = element_rect(fill = NA, colour = "grey20"),
+ panel.grid.major = element_blank(),
+ panel.grid.minor = element_blank(),
+ panel.spacing = unit(half_line, "pt"),
+ panel.spacing.x = NULL,
+ panel.spacing.y = NULL,
+ panel.ontop = FALSE,
+
+ strip.background = element_rect(fill = "grey85", colour = "grey20"),
+ strip.text = element_text(colour = "grey10", size = rel(0.8)),
+ strip.text.x = element_text(margin = margin(t = half_line, b = half_line)),
+ strip.text.y = element_text(angle = -90, margin = margin(l = half_line, r = half_line)),
+ strip.placement = "inside",
+ strip.placement.x = NULL,
+ strip.placement.y = NULL,
+ strip.switch.pad.grid = unit(0.1, "cm"),
+ strip.switch.pad.wrap = unit(0.1, "cm"),
+
+ plot.background = element_rect(colour = "white"),
+ plot.title = element_text(
+ size = rel(1.2),
+ hjust = 0, vjust = 1,
+ margin = margin(b = half_line * 1.2)
+ ),
+ plot.subtitle = element_text(
+ size = rel(0.9),
+ hjust = 0, vjust = 1,
+ margin = margin(b = half_line * 0.9)
+ ),
+ plot.caption = element_text(
+ size = rel(0.9),
+ hjust = 1, vjust = 1,
+ margin = margin(t = half_line * 0.9)
+ ),
+ plot.margin = margin(half_line, half_line, half_line, half_line),
+
+ complete = TRUE
+ )
+}
View
@@ -12,6 +12,10 @@ install:
# Adapt as necessary starting from here
+environment:
+ global:
+ USE_RTOOLS: true
+
build_script:
- travis-tool.sh install_deps
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
@@ -0,0 +1,69 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 720.00 576.00'>
+<defs>
+ <style type='text/css'><![CDATA[
+ line, polyline, polygon, path, rect, circle {
+ fill: none;
+ stroke: #000000;
+ stroke-linecap: round;
+ stroke-linejoin: round;
+ stroke-miterlimit: 10.00;
+ }
+ ]]></style>
+</defs>
+<rect width='100%' height='100%' style='stroke: none; fill: #FFFFFF;'/>
+<rect x='0.00' y='0.00' width='720.00' height='576.00' style='stroke-width: 1.07; stroke: #FFFFFF; fill: #FFFFFF;' />
+<defs>
+ <clipPath id='cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA=='>
+ <rect x='35.95' y='23.48' width='678.57' height='522.79' />
+ </clipPath>
+</defs>
+<rect x='35.95' y='23.48' width='678.57' height='522.79' style='stroke-width: 1.07; stroke: none; fill: #FFFFFF;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='258.03' cy='498.74' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='336.68' cy='498.74' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='165.49' cy='455.97' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='441.55' cy='489.23' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='510.95' cy='553.39' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='517.12' cy='567.65' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='433.84' cy='417.94' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='421.50' cy='455.97' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='510.95' cy='541.51' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='510.95' cy='574.78' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='128.48' cy='227.84' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='15.90' cy='192.19' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='210.22' cy='486.86' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='635.87' cy='541.51' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='46.74' cy='349.03' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='109.97' cy='379.92' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='304.29' cy='529.63' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<circle cx='307.38' cy='489.23' r='1.95pt' style='stroke-width: 0.71; fill: #000000;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<rect x='35.95' y='23.48' width='678.57' height='522.79' style='stroke-width: 1.07; stroke: #333333;' clip-path='url(#cpMzUuOTV8NzE0LjUyfDU0Ni4yN3wyMy40OA==)' />
+<defs>
+ <clipPath id='cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA='>
+ <rect x='0.00' y='0.00' width='720.00' height='576.00' />
+ </clipPath>
+</defs>
+<g clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)'><text x='21.01' y='525.60' style='font-size: 8.80px; fill: #4D4D4D; font-family: Liberation Sans;' textLength='10.01px' lengthAdjust='spacingAndGlyphs'>20</text></g>
+<g clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)'><text x='21.01' y='406.78' style='font-size: 8.80px; fill: #4D4D4D; font-family: Liberation Sans;' textLength='10.01px' lengthAdjust='spacingAndGlyphs'>25</text></g>
+<g clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)'><text x='21.01' y='287.97' style='font-size: 8.80px; fill: #4D4D4D; font-family: Liberation Sans;' textLength='10.01px' lengthAdjust='spacingAndGlyphs'>30</text></g>
+<g clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)'><text x='21.01' y='169.15' style='font-size: 8.80px; fill: #4D4D4D; font-family: Liberation Sans;' textLength='10.01px' lengthAdjust='spacingAndGlyphs'>35</text></g>
+<g clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)'><text x='21.01' y='50.33' style='font-size: 8.80px; fill: #4D4D4D; font-family: Liberation Sans;' textLength='10.01px' lengthAdjust='spacingAndGlyphs'>40</text></g>
+<polyline points='33.21,522.50 35.95,522.50 ' style='stroke-width: 1.07; stroke: #333333; stroke-linecap: butt;' clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)' />
+<polyline points='33.21,403.69 35.95,403.69 ' style='stroke-width: 1.07; stroke: #333333; stroke-linecap: butt;' clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)' />
+<polyline points='33.21,284.87 35.95,284.87 ' style='stroke-width: 1.07; stroke: #333333; stroke-linecap: butt;' clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)' />
+<polyline points='33.21,166.06 35.95,166.06 ' style='stroke-width: 1.07; stroke: #333333; stroke-linecap: butt;' clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)' />
+<polyline points='33.21,47.24 35.95,47.24 ' style='stroke-width: 1.07; stroke: #333333; stroke-linecap: butt;' clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)' />
+<polyline points='66.79,549.01 66.79,546.27 ' style='stroke-width: 1.07; stroke: #333333; stroke-linecap: butt;' clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)' />
+<polyline points='221.01,549.01 221.01,546.27 ' style='stroke-width: 1.07; stroke: #333333; stroke-linecap: butt;' clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)' />
+<polyline points='375.23,549.01 375.23,546.27 ' style='stroke-width: 1.07; stroke: #333333; stroke-linecap: butt;' clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)' />
+<polyline points='529.46,549.01 529.46,546.27 ' style='stroke-width: 1.07; stroke: #333333; stroke-linecap: butt;' clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)' />
+<polyline points='683.68,549.01 683.68,546.27 ' style='stroke-width: 1.07; stroke: #333333; stroke-linecap: butt;' clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)' />
+<g clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)'><text x='60.54' y='557.38' style='font-size: 8.80px; fill: #4D4D4D; font-family: Liberation Sans;' textLength='12.51px' lengthAdjust='spacingAndGlyphs'>2.0</text></g>
+<g clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)'><text x='214.76' y='557.38' style='font-size: 8.80px; fill: #4D4D4D; font-family: Liberation Sans;' textLength='12.51px' lengthAdjust='spacingAndGlyphs'>2.5</text></g>
+<g clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)'><text x='368.98' y='557.38' style='font-size: 8.80px; fill: #4D4D4D; font-family: Liberation Sans;' textLength='12.51px' lengthAdjust='spacingAndGlyphs'>3.0</text></g>
+<g clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)'><text x='523.20' y='557.38' style='font-size: 8.80px; fill: #4D4D4D; font-family: Liberation Sans;' textLength='12.51px' lengthAdjust='spacingAndGlyphs'>3.5</text></g>
+<g clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)'><text x='677.42' y='557.38' style='font-size: 8.80px; fill: #4D4D4D; font-family: Liberation Sans;' textLength='12.51px' lengthAdjust='spacingAndGlyphs'>4.0</text></g>
+<g clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)'><text x='369.73' y='570.43' style='font-size: 11.00px; font-family: Liberation Sans;' textLength='11.00px' lengthAdjust='spacingAndGlyphs'>wt</text></g>
+<g clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)'><text transform='translate(13.04,295.57) rotate(-90)' style='font-size: 11.00px; font-family: Liberation Sans;' textLength='21.40px' lengthAdjust='spacingAndGlyphs'>mpg</text></g>
+<g clip-path='url(#cpMC4wMHw3MjAuMDB8NTc2LjAwfDAuMDA=)'><text x='35.95' y='14.42' style='font-size: 13.20px; font-family: Liberation Sans;' textLength='83.10px' lengthAdjust='spacingAndGlyphs'>contract range</text></g>
+</svg>
Oops, something went wrong.