Skip to content

Commit 938d8b0

Browse files
authored
egui_kittest: write .old.png files when updating images (#5578)
After running `UPDATE_SNAPSHOTS=1 cargo test --all-features` I want to compare before/after images before committing them. Now I can!
1 parent 5cbf337 commit 938d8b0

File tree

2 files changed

+55
-42
lines changed

2 files changed

+55
-42
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
**/target_wasm
55
**/tests/snapshots/**/*.diff.png
66
**/tests/snapshots/**/*.new.png
7+
**/tests/snapshots/**/*.old.png
78
/.*.json
89
/.vscode
910
/media/*

crates/egui_kittest/src/snapshot.rs

+54-42
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::Harness;
22
use image::ImageError;
33
use std::fmt::Display;
44
use std::io::ErrorKind;
5-
use std::path::{Path, PathBuf};
5+
use std::path::PathBuf;
66

77
#[non_exhaustive]
88
pub struct SnapshotOptions {
@@ -159,22 +159,6 @@ fn should_update_snapshots() -> bool {
159159
std::env::var("UPDATE_SNAPSHOTS").is_ok()
160160
}
161161

162-
fn maybe_update_snapshot(
163-
snapshot_path: &Path,
164-
current: &image::RgbaImage,
165-
) -> Result<(), SnapshotError> {
166-
if should_update_snapshots() {
167-
current
168-
.save(snapshot_path)
169-
.map_err(|err| SnapshotError::WriteSnapshot {
170-
err,
171-
path: snapshot_path.into(),
172-
})?;
173-
println!("Updated snapshot: {snapshot_path:?}");
174-
}
175-
Ok(())
176-
}
177-
178162
/// Image snapshot test with custom options.
179163
///
180164
/// If you want to change the default options for your whole project, it's recommended to create a
@@ -188,11 +172,14 @@ fn maybe_update_snapshot(
188172
/// The new image from the most recent test run will be saved under `{output_path}/{name}.new.png`.
189173
/// If new image didn't match the snapshot, a diff image will be saved under `{output_path}/{name}.diff.png`.
190174
///
175+
/// If the env-var `UPDATE_SNAPSHOTS` is set, then the old image will backed up under `{output_path}/{name}.old.png`.
176+
/// and then new image will be written to `{output_path}/{name}.png`
177+
///
191178
/// # Errors
192179
/// Returns a [`SnapshotError`] if the image does not match the snapshot or if there was an error
193180
/// reading or writing the snapshot.
194181
pub fn try_image_snapshot_options(
195-
current: &image::RgbaImage,
182+
new: &image::RgbaImage,
196183
name: &str,
197184
options: &SnapshotOptions,
198185
) -> Result<(), SnapshotError> {
@@ -201,45 +188,72 @@ pub fn try_image_snapshot_options(
201188
output_path,
202189
} = options;
203190

204-
let path = output_path.join(format!("{name}.png"));
205-
std::fs::create_dir_all(path.parent().expect("Could not get snapshot folder")).ok();
191+
std::fs::create_dir_all(output_path).ok();
192+
193+
// The one that is checked in to git
194+
let snapshot_path = output_path.join(format!("{name}.png"));
206195

196+
// These should be in .gitignore:
207197
let diff_path = output_path.join(format!("{name}.diff.png"));
208-
let current_path = output_path.join(format!("{name}.new.png"));
198+
let old_backup_path = output_path.join(format!("{name}.old.png"));
199+
let new_path = output_path.join(format!("{name}.new.png"));
200+
201+
// Delete old temporary files if they exist:
202+
std::fs::remove_file(&diff_path).ok();
203+
std::fs::remove_file(&old_backup_path).ok();
204+
std::fs::remove_file(&new_path).ok();
205+
206+
let maybe_update_snapshot = || {
207+
if should_update_snapshots() {
208+
// Keep the old version so the user can compare it:
209+
std::fs::rename(&snapshot_path, &old_backup_path).ok();
210+
211+
// Write the new file to the checked in path:
212+
new.save(&snapshot_path)
213+
.map_err(|err| SnapshotError::WriteSnapshot {
214+
err,
215+
path: snapshot_path.clone(),
216+
})?;
217+
218+
// No need for an explicit `.new` file:
219+
std::fs::remove_file(&new_path).ok();
220+
221+
println!("Updated snapshot: {snapshot_path:?}");
222+
}
223+
Ok(())
224+
};
209225

210-
current
211-
.save(&current_path)
226+
// Always write a `.new` file so the user can compare:
227+
new.save(&new_path)
212228
.map_err(|err| SnapshotError::WriteSnapshot {
213229
err,
214-
path: current_path,
230+
path: new_path.clone(),
215231
})?;
216232

217-
let previous = match image::open(&path) {
233+
let previous = match image::open(&snapshot_path) {
218234
Ok(image) => image.to_rgba8(),
219235
Err(err) => {
220-
maybe_update_snapshot(&path, current)?;
221-
return Err(SnapshotError::OpenSnapshot { path, err });
236+
// No previous snapshot - probablye a new test.
237+
maybe_update_snapshot()?;
238+
return Err(SnapshotError::OpenSnapshot {
239+
path: snapshot_path.clone(),
240+
err,
241+
});
222242
}
223243
};
224244

225-
if previous.dimensions() != current.dimensions() {
226-
maybe_update_snapshot(&path, current)?;
245+
if previous.dimensions() != new.dimensions() {
246+
maybe_update_snapshot()?;
227247
return Err(SnapshotError::SizeMismatch {
228248
name: name.to_owned(),
229249
expected: previous.dimensions(),
230-
actual: current.dimensions(),
250+
actual: new.dimensions(),
231251
});
232252
}
233253

234-
let result = dify::diff::get_results(
235-
previous,
236-
current.clone(),
237-
*threshold,
238-
true,
239-
None,
240-
&None,
241-
&None,
242-
);
254+
// Compare existing image to the new one:
255+
let result =
256+
dify::diff::get_results(previous, new.clone(), *threshold, true, None, &None, &None);
243257

244258
if let Some((diff, result_image)) = result {
245259
result_image
@@ -248,15 +262,13 @@ pub fn try_image_snapshot_options(
248262
path: diff_path.clone(),
249263
err,
250264
})?;
251-
maybe_update_snapshot(&path, current)?;
265+
maybe_update_snapshot()?;
252266
Err(SnapshotError::Diff {
253267
name: name.to_owned(),
254268
diff,
255269
diff_path,
256270
})
257271
} else {
258-
// Delete old diff if it exists
259-
std::fs::remove_file(diff_path).ok();
260272
Ok(())
261273
}
262274
}

0 commit comments

Comments
 (0)