Skip to content

Commit 1711da3

Browse files
authored
Merge pull request #22 from lionel-/release-0.1.2
Release 0.1.2
2 parents 71ad780 + d22f614 commit 1711da3

File tree

30 files changed

+446
-91
lines changed

30 files changed

+446
-91
lines changed

.Rbuildignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
^\.travis\.yml$
55
^cran-comments\.md$
66
^appveyor\.yml$
7+
^revdep$

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ matrix:
1717
"sudo apt-get update -q",
1818
"sudo apt-get install libfreetype6"
1919
]
20+
- r: devel
2021
- os: osx
2122
osx_image: xcode7.2
2223
brew_packages: cairo

DESCRIPTION

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: vdiffr
22
Title: Visual Regression Testing and Graphical Diffing
3-
Version: 0.1.1.9000
3+
Version: 0.2.0
44
Authors@R: c(
55
person("Lionel", "Henry", , "[email protected]", c("cre", "aut")),
66
person("RStudio", role = "cph"),
@@ -14,6 +14,11 @@ Authors@R: c(
1414
Description: An extension to the 'testthat' package that makes it easy
1515
to add graphical unit tests. It provides a Shiny application to
1616
manage the test cases.
17+
License: GPL-3 | file LICENSE
18+
LazyData: true
19+
ByteCompile: true
20+
SystemRequirements:
21+
FreeType >= 2.6.0
1722
Depends:
1823
R (>= 3.1.0)
1924
Imports:
@@ -34,9 +39,8 @@ Imports:
3439
Suggests:
3540
ggplot2,
3641
roxygen2,
37-
rstudioapi
38-
License: GPL-3 | file LICENSE
39-
LazyData: true
42+
rstudioapi,
43+
yaml
44+
LinkingTo:
45+
Rcpp
4046
RoxygenNote: 6.0.1
41-
LinkingTo: Rcpp
42-
SystemRequirements: FreeType >= 2.6.0

NAMESPACE

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export(widget_toggle)
2525
export(widget_toggle_)
2626
import(rlang)
2727
importFrom(R6,R6Class)
28+
importFrom(Rcpp,sourceCpp)
2829
importFrom(glue,glue)
2930
importFrom(purrr,every)
3031
importFrom(purrr,keep)
@@ -33,4 +34,4 @@ importFrom(purrr,map2_chr)
3334
importFrom(purrr,map_chr)
3435
importFrom(purrr,partial)
3536
importFrom(purrr,walk)
36-
useDynLib(vdiffr)
37+
useDynLib(vdiffr, .registration = TRUE)

NEWS.md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11

2-
# vdiffr 0.1.1.9000
2+
# vdiffr 0.2.0
33

4-
* Set minimal R version required to 3.1.0.
4+
This release makes it easier to debug failures on remote systems. It
5+
also makes vdiffr more robust to failures caused by incompatible
6+
installations: instead of failing, the tests are skipped. This
7+
prevents spurious failures on CRAN.
8+
9+
10+
## Troubleshooting on remotes
511

612
* `expect_doppelganger()` gains a `verbose` argument to print the
713
SVG files for failed cases while testing. This is useful to debug
@@ -14,6 +20,33 @@
1420
remotes.
1521

1622

23+
## Handling of incompatible systems
24+
25+
The tests are now skipped if the FreeType version used to build the
26+
comparison SVGs does not match the version installed on the system
27+
where the tests are run. This is necessary because changes in new
28+
version of FreeType might affect the computation of text extents,
29+
which then causes svglite to produce slightly different SVGs. The
30+
minor version is not taken into account so FreeType 2.7.1 is deemed
31+
compatible with 2.7.2 but not with 2.8.0.
32+
33+
In practice, this means that package contributors should only
34+
validate visual cases if their FreeType version matches the one of
35+
the package maintainer. Also, the maintainer must update the version
36+
recorded in the package repository (in the file
37+
`./tests/figs/deps.txt`) when FreeType has been updated on their
38+
system. Running `vdiffr::validate_cases()` updates the dependency
39+
file even if there are no visual case to update.
40+
41+
In the future, we may provide a version of vdiffr statically
42+
compiled with a specific version of FreeType to prevent these issues.
43+
44+
45+
## Other changes
46+
47+
* The minimal R version required by vdiffr is now R 3.1.0.
48+
49+
1750
# vdiffr 0.1.1
1851

1952
* `expect_doppelganger()` no longer throws an error when FreeType is

R/RcppExports.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
33

44
compare_files <- function(expected, test) {
5-
.Call('_vdiffr_compare_files', PACKAGE = 'vdiffr', expected, test)
5+
.Call(`_vdiffr_compare_files`, expected, test)
66
}
77

R/cases.R

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,23 @@ validate_cases <- function(cases = collect_new_cases()) {
107107
}
108108

109109
write_deps_note <- function(cases, pkg_path) {
110+
versions_lines <- glue(
111+
"Fontconfig: { gdtools::version_fontconfig() }
112+
FreeType: { gdtools::version_freetype() }
113+
Cairo: { gdtools::version_cairo() }"
114+
)
115+
110116
deps <- attr(cases, "deps")
111117
versions <- map_chr(deps, package_version)
112-
deps <- map2_chr(deps, versions, paste, sep = ": ")
118+
deps_lines <- map2_chr(deps, versions, paste, sep = ": ")
119+
120+
deps_lines <- chr_lines(
121+
versions_lines,
122+
deps_lines
123+
)
113124

114125
deps_note_file <- file.path(pkg_path, "tests", "figs", "deps.txt")
115-
writeLines(deps, deps_note_file)
126+
writeLines(deps_lines, deps_note_file)
116127
}
117128

118129
update_case <- function(case, pkg_path) {

R/testthat-ui.R

Lines changed: 72 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ expect_doppelganger <- function(title, fig, path = NULL, ...,
8383
maybe_collect_case(case)
8484
maybe_print_svgs(case)
8585
msg <- paste0("Figure not generated yet: ", fig_name, ".svg")
86-
exp <- expectation_new(msg, case)
86+
exp <- new_exp(msg, case)
8787
}
8888

8989
signal_expectation(exp)
@@ -104,18 +104,68 @@ compare_figs <- function(case) {
104104
if (equal) {
105105
case <- success_case(case)
106106
maybe_collect_case(case)
107-
exp <- expectation_match("TRUE", case)
108-
} else {
109-
case <- mismatch_case(case)
110-
maybe_collect_case(case)
107+
return(match_exp("TRUE", case))
108+
}
109+
110+
case <- mismatch_case(case)
111+
maybe_collect_case(case)
112+
push_log(case)
113+
114+
cases_ver <- cases_freetype_version()
115+
system_ver <- system_freetype_version()
116+
117+
if (is_null(cases_ver)) {
118+
msg <- glue(
119+
"Failed doppelganger but vdiffr can't check its FreeType version.
120+
Please revalidate cases with a more recent vdiffr"
121+
)
122+
return(skipped_mismatch_exp(msg, case))
123+
}
124+
125+
if (cases_ver < system_ver) {
126+
msg <- glue(
127+
"Failed doppelganger was generated with an older FreeType version.
128+
Please revalidate cases with vdiffr::validate_cases() or vdiffr::manage_cases()"
129+
)
130+
return(skipped_mismatch_exp(msg, case))
131+
}
132+
133+
if (cases_ver > system_ver) {
134+
msg <- glue(
135+
"Failed doppelganger was generated with a newer FreeType version.
136+
Please install FreeType {cases_ver} on your system"
137+
)
138+
return(skipped_mismatch_exp(msg, case))
139+
}
140+
141+
msg <- paste0("Figures don't match: ", case$name, ".svg\n")
142+
mismatch_exp(msg, case)
143+
}
111144

112-
msg <- paste0("Figures don't match: ", case$name, ".svg\n")
113-
exp <- expectation_mismatch(msg, case)
145+
# Go back up one level by default as we should be in the `testthat`
146+
# folder
147+
cases_freetype_version <- function(path = "..") {
148+
deps <- readLines(file.path(path, "figs", "deps.txt"))
149+
ver <- purrr::detect(deps, function(dep) grepl("^FreeType:", dep))
114150

115-
push_log(case)
151+
if (is_null(ver)) {
152+
return(NULL)
116153
}
117154

118-
exp
155+
# Strip "FreeType: " prefix and minor version
156+
ver <- substr(ver, 11, nchar(ver))
157+
ver <- sub(".[0-9]+$", "", ver)
158+
159+
as_version(ver)
160+
}
161+
system_freetype_version <- function() {
162+
ver <- sub(".[0-9]+$", "", gdtools::version_freetype())
163+
as_version(ver)
164+
}
165+
as_version <- function(ver) {
166+
ver <- strsplit(ver, ".", fixed = TRUE)[[1]]
167+
ver <- as.integer(ver)
168+
structure(list(ver), class = c("package_version", "numeric_version"))
119169
}
120170

121171
# Print only if we're not collecting. The testthat reporter prints
@@ -126,20 +176,22 @@ maybe_print_svgs <- function(case, pkg_path = NULL) {
126176
}
127177
}
128178

129-
expectation_new <- function(msg, case) {
130-
exp <- testthat::expectation("skip", msg)
131-
classes <- c(class(exp), "vdiffr_new")
179+
new_expectation <- function(msg, case, type, vdiffr_type) {
180+
exp <- testthat::expectation(type, msg)
181+
classes <- c(class(exp), vdiffr_type)
132182
set_attrs(exp, class = classes, vdiffr_case = case)
133183
}
134-
expectation_mismatch <- function(msg, case) {
135-
exp <- testthat::expectation("failure", msg)
136-
classes <- c(class(exp), "vdiffr_mismatch")
137-
set_attrs(exp, class = classes, vdiffr_case = case)
184+
new_exp <- function(msg, case) {
185+
new_expectation(msg, case, "skip", "vdiffr_new")
138186
}
139-
expectation_match <- function(msg, case) {
140-
exp <- testthat::expectation("success", msg)
141-
classes <- c(class(exp), "vdiffr_match")
142-
set_attrs(exp, class = classes, vdiffr_case = case)
187+
match_exp <- function(msg, case) {
188+
new_expectation(msg, case, "success", "vdiffr_match")
189+
}
190+
mismatch_exp <- function(msg, case) {
191+
new_expectation(msg, case, "failure", "vdiffr_mismatch")
192+
}
193+
skipped_mismatch_exp <- function(msg, case) {
194+
new_expectation(msg, case, "skip", "vdiffr_mismatch")
143195
}
144196

145197
# From testthat

R/vdiffr.R

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
#' @importFrom glue glue
33
#' @importFrom purrr map map_chr keep walk every partial map2_chr
44
#' @importFrom R6 R6Class
5-
#' @useDynLib vdiffr
6-
NULL
5+
#' @importFrom Rcpp sourceCpp
6+
#' @useDynLib vdiffr, .registration = TRUE
7+
"_PACKAGE"
78

89
old_freetype <- function() {
910
gdtools::version_freetype() < "2.6.0"

README.md

Lines changed: 22 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -139,50 +139,28 @@ C-v`, include something like this in your init file:
139139

140140
## Technical Aspects
141141

142-
### Continuous integration on Travis
143-
144-
To work properly, vdiffr requires the C library `FreeType` version
145-
2.6.0 or later. The FreeType libraries available by default on Travis'
146-
Linux platforms are not this recent yet. Some adjustments to the
147-
`travis.yml` file are thus required.
148-
149-
**Ubuntu Precise (the default):**
150-
151-
```{yaml}
152-
addons:
153-
apt:
154-
sources:
155-
- debian-sid
156-
packages:
157-
- libfreetype6
158-
```
159-
160-
**Ubuntu Trusty:**
161-
162-
```{yaml}
163-
sudo: required
164-
before_install: [
165-
"sudo add-apt-repository \"deb http://archive.ubuntu.com/ubuntu/ xenial main\" -y",
166-
"sudo apt-get update -q",
167-
"sudo apt-get install libfreetype6"
168-
]
169-
```
170-
171-
**macOS with XCode 6.1:**
172-
173-
```{yaml}
174-
osx_image: beta-xcode6.1
175-
disable_homebrew: true
176-
latex: false
177-
```
178-
179-
**macOS with XCode 7.2:**
180-
181-
```{yaml}
182-
osx_image: xcode7.2
183-
brew_packages: cairo
184-
latex: false
185-
```
142+
### FreeType dependency
143+
144+
The software FreeType plays a key role in vdiffr. It is used to
145+
compute the extents of text boxes and thus determine the dimensions of
146+
graphical elements containing text. These dimensions are then recorded
147+
in the SVG files.
148+
149+
Small changes in the algorithm implemented in FreeType to compute text
150+
extents will produce different SVGs. For this reason, it is important
151+
that the FreeType version that was used to create validated cases be
152+
the same as the one on the system running the tests. To avoid false
153+
failures, the visual tests are skipped when that's not the case. The
154+
minor version is not taken into account so FreeType 2.7.1 is deemed
155+
compatible with 2.7.2 but not with 2.8.0.
156+
157+
In practice, this means that package contributors should only validate
158+
visual cases if their FreeType version matches the one of the package
159+
maintainer. Also, the maintainer must update the version recorded in
160+
the package repository (in the file `./tests/figs/deps.txt`) when
161+
FreeType has been updated on their system. Running
162+
`vdiffr::validate_cases()` updates the dependency file even if there
163+
are no visual case to update.
186164

187165

188166
### Windows platforms

0 commit comments

Comments
 (0)