Skip to content

Commit 87d61c5

Browse files
schloerkehadley
andauthored
Enforce uniqueness of snapshot files (#1592)
And slightly improve error messages/trace frame. Co-authored-by: Hadley Wickham <[email protected]>
1 parent 608decc commit 87d61c5

File tree

7 files changed

+47
-39
lines changed

7 files changed

+47
-39
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# testthat (development version)
22

3+
* `expect_snapshot_file(name=)` must have a unique file path. If a snapshot file attempts to be saved with a duplicate `name`, an error will be thrown. (#1592)
34
* `test_dir()`, `test_file()`, `test_package()`, `test_check()`, `test_local()`, `source_file()` gain a `shuffle` argument uses `sample()` to randomly reorder the top-level expressions in each test file (#1942). This random reordering surfaces dependencies between tests and code outside of any test, as well as dependencies between tests. This helps you find and eliminate unintentional dependencies.
45
* `snapshot_accept(test)` now works when the test file name contains `.` (#1669).
56
* `local_mock()` and `with_mock()` have been deprecated because they are no longer permitted in R 4.5.

R/snapshot-file.R

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ expect_snapshot_file <- function(
137137
path,
138138
file_equal = compare,
139139
variant = variant,
140-
trace_env = caller_env()
141140
)
142141
if (inherits(equal, "expectation_failure")) {
143142
return(equal)
@@ -204,7 +203,7 @@ snapshot_file_equal <- function(
204203
trace_env = caller_env()
205204
) {
206205
if (!file.exists(path)) {
207-
cli::cli_abort("{.path {path}} not found.")
206+
cli::cli_abort("{.path {path}} not found.", call = trace_env)
208207
}
209208

210209
if (is.null(snap_variant)) {

R/snapshot-reporter.R

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ SnapshotReporter <- R6::R6Class(
77
test = NULL,
88
test_file_seen = character(),
99
snap_file_seen = character(),
10+
snap_file_saved = character(),
1011
variants_changed = FALSE,
1112
fail_on_new = NULL,
1213

@@ -22,6 +23,7 @@ SnapshotReporter <- R6::R6Class(
2223
start_file = function(path, test = NULL) {
2324
self$file <- context_name(path)
2425
self$test_file_seen <- c(self$test_file_seen, self$file)
26+
self$snap_file_saved <- character()
2527

2628
self$variants_changed <- character()
2729

@@ -107,6 +109,15 @@ SnapshotReporter <- R6::R6Class(
107109
) {
108110
self$announce_file_snapshot(name)
109111

112+
save_path <- paste0(c(self$file, variant, name), collapse = "/")
113+
if (save_path %in% self$snap_file_saved) {
114+
cli::cli_abort(
115+
"Snapshot file names must be unique. {.arg name} has already been used.",
116+
call = trace_env
117+
)
118+
}
119+
self$snap_file_saved <- c(self$snap_file_saved, save_path)
120+
110121
snapshot_file_equal(
111122
snap_dir = self$snap_dir,
112123
snap_test = self$file,

tests/testthat/_snaps/snapshot-file.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
# expect_snapshot_file finds duplicate snapshot files
2+
3+
Code
4+
expect_snapshot_file(write_tmp_lines(r_version()), "version.txt", variant = r_version())
5+
Condition
6+
Error in `expect_snapshot_file()`:
7+
! Snapshot file names must be unique. `name` has already been used.
8+
19
# warns on first creation
210

311
Code
@@ -11,7 +19,7 @@
1119
Code
1220
snapshot_file_equal_("doesnt-exist.txt")
1321
Condition
14-
Error in `snapshot_file_equal()`:
22+
Error in `snapshot_file_equal_()`:
1523
! 'doesnt-exist.txt' not found.
1624

1725
# snapshot_hint output differs in R CMD check
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
"","mpg","cyl","disp","hp"
2+
"Mazda RX4",21,6,160,110
3+
"Mazda RX4 Wag",21,6,160,110
4+
"Datsun 710",22.8,4,108,93
5+
"Hornet 4 Drive",21.4,6,258,110
6+
"Hornet Sportabout",18.7,8,360,175
Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,6 @@
1-
"","mpg","cyl","disp","hp","drat","wt","qsec","vs","am","gear","carb"
2-
"Mazda RX4",21,6,160,110,3.9,2.62,16.46,0,1,4,4
3-
"Mazda RX4 Wag",21,6,160,110,3.9,2.875,17.02,0,1,4,4
4-
"Datsun 710",22.8,4,108,93,3.85,2.32,18.61,1,1,4,1
5-
"Hornet 4 Drive",21.4,6,258,110,3.08,3.215,19.44,1,0,3,1
6-
"Hornet Sportabout",18.7,8,360,175,3.15,3.44,17.02,0,0,3,2
7-
"Valiant",18.1,6,225,105,2.76,3.46,20.22,1,0,3,1
8-
"Duster 360",14.3,8,360,245,3.21,3.57,15.84,0,0,3,4
9-
"Merc 240D",24.4,4,146.7,62,3.69,3.19,20,1,0,4,2
10-
"Merc 230",22.8,4,140.8,95,3.92,3.15,22.9,1,0,4,2
11-
"Merc 280",19.2,6,167.6,123,3.92,3.44,18.3,1,0,4,4
12-
"Merc 280C",17.8,6,167.6,123,3.92,3.44,18.9,1,0,4,4
13-
"Merc 450SE",16.4,8,275.8,180,3.07,4.07,17.4,0,0,3,3
14-
"Merc 450SL",17.3,8,275.8,180,3.07,3.73,17.6,0,0,3,3
15-
"Merc 450SLC",15.2,8,275.8,180,3.07,3.78,18,0,0,3,3
16-
"Cadillac Fleetwood",10.4,8,472,205,2.93,5.25,17.98,0,0,3,4
17-
"Lincoln Continental",10.4,8,460,215,3,5.424,17.82,0,0,3,4
18-
"Chrysler Imperial",14.7,8,440,230,3.23,5.345,17.42,0,0,3,4
19-
"Fiat 128",32.4,4,78.7,66,4.08,2.2,19.47,1,1,4,1
20-
"Honda Civic",30.4,4,75.7,52,4.93,1.615,18.52,1,1,4,2
21-
"Toyota Corolla",33.9,4,71.1,65,4.22,1.835,19.9,1,1,4,1
22-
"Toyota Corona",21.5,4,120.1,97,3.7,2.465,20.01,1,0,3,1
23-
"Dodge Challenger",15.5,8,318,150,2.76,3.52,16.87,0,0,3,2
24-
"AMC Javelin",15.2,8,304,150,3.15,3.435,17.3,0,0,3,2
25-
"Camaro Z28",13.3,8,350,245,3.73,3.84,15.41,0,0,3,4
26-
"Pontiac Firebird",19.2,8,400,175,3.08,3.845,17.05,0,0,3,2
27-
"Fiat X1-9",27.3,4,79,66,4.08,1.935,18.9,1,1,4,1
28-
"Porsche 914-2",26,4,120.3,91,4.43,2.14,16.7,0,1,5,2
29-
"Lotus Europa",30.4,4,95.1,113,3.77,1.513,16.9,1,1,5,2
30-
"Ford Pantera L",15.8,8,351,264,4.22,3.17,14.5,0,1,5,4
31-
"Ferrari Dino",19.7,6,145,175,3.62,2.77,15.5,0,1,5,6
32-
"Maserati Bora",15,8,301,335,3.54,3.57,14.6,0,1,5,8
33-
"Volvo 142E",21.4,4,121,109,4.11,2.78,18.6,1,1,4,2
1+
"","mpg","cyl","disp","hp"
2+
"Mazda RX4",21,6,160,110
3+
"Mazda RX4 Wag",21,6,160,110
4+
"Datsun 710",22.8,4,108,93
5+
"Hornet 4 Drive",21.4,6,258,110
6+
"Hornet Sportabout",18.7,8,360,175

tests/testthat/test-snapshot-file.R

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@ test_that("expect_snapshot_file works", {
99
expect_snapshot_file(path, "foo.png")
1010

1111
path <- withr::local_tempfile()
12-
mtcars2 <- mtcars
13-
# mtcars2$wt[10] <- NA
12+
mtcars2 <- mtcars[1:5, 1:4]
1413
write.csv(mtcars2, path)
1514
expect_snapshot_file(path, "foo.csv", compare = compare_file_text)
1615

1716
# Deprecated `binary` argument still works
1817
withr::local_options(lifecycle_verbosity = "quiet")
19-
expect_snapshot_file(path, "foo.csv", binary = FALSE)
18+
expect_snapshot_file(path, "foo-not-binary.csv", binary = FALSE)
2019
})
2120

2221

@@ -39,6 +38,17 @@ test_that("expect_snapshot_file works with variant", {
3938
)
4039
})
4140

41+
test_that("expect_snapshot_file finds duplicate snapshot files", {
42+
expect_snapshot(
43+
expect_snapshot_file(
44+
write_tmp_lines(r_version()),
45+
"version.txt",
46+
variant = r_version()
47+
),
48+
error = TRUE
49+
)
50+
})
51+
4252
test_that("basic workflow", {
4353
snapper <- local_snapshotter(fail_on_new = FALSE)
4454

0 commit comments

Comments
 (0)