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!
This commit is contained in:
parent
5cbf337f18
commit
938d8b0d2e
|
|
@ -4,6 +4,7 @@
|
||||||
**/target_wasm
|
**/target_wasm
|
||||||
**/tests/snapshots/**/*.diff.png
|
**/tests/snapshots/**/*.diff.png
|
||||||
**/tests/snapshots/**/*.new.png
|
**/tests/snapshots/**/*.new.png
|
||||||
|
**/tests/snapshots/**/*.old.png
|
||||||
/.*.json
|
/.*.json
|
||||||
/.vscode
|
/.vscode
|
||||||
/media/*
|
/media/*
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use crate::Harness;
|
||||||
use image::ImageError;
|
use image::ImageError;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub struct SnapshotOptions {
|
pub struct SnapshotOptions {
|
||||||
|
|
@ -159,22 +159,6 @@ fn should_update_snapshots() -> bool {
|
||||||
std::env::var("UPDATE_SNAPSHOTS").is_ok()
|
std::env::var("UPDATE_SNAPSHOTS").is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maybe_update_snapshot(
|
|
||||||
snapshot_path: &Path,
|
|
||||||
current: &image::RgbaImage,
|
|
||||||
) -> Result<(), SnapshotError> {
|
|
||||||
if should_update_snapshots() {
|
|
||||||
current
|
|
||||||
.save(snapshot_path)
|
|
||||||
.map_err(|err| SnapshotError::WriteSnapshot {
|
|
||||||
err,
|
|
||||||
path: snapshot_path.into(),
|
|
||||||
})?;
|
|
||||||
println!("Updated snapshot: {snapshot_path:?}");
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Image snapshot test with custom options.
|
/// Image snapshot test with custom options.
|
||||||
///
|
///
|
||||||
/// If you want to change the default options for your whole project, it's recommended to create a
|
/// 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(
|
||||||
/// The new image from the most recent test run will be saved under `{output_path}/{name}.new.png`.
|
/// The new image from the most recent test run will be saved under `{output_path}/{name}.new.png`.
|
||||||
/// If new image didn't match the snapshot, a diff image will be saved under `{output_path}/{name}.diff.png`.
|
/// If new image didn't match the snapshot, a diff image will be saved under `{output_path}/{name}.diff.png`.
|
||||||
///
|
///
|
||||||
|
/// If the env-var `UPDATE_SNAPSHOTS` is set, then the old image will backed up under `{output_path}/{name}.old.png`.
|
||||||
|
/// and then new image will be written to `{output_path}/{name}.png`
|
||||||
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// Returns a [`SnapshotError`] if the image does not match the snapshot or if there was an error
|
/// Returns a [`SnapshotError`] if the image does not match the snapshot or if there was an error
|
||||||
/// reading or writing the snapshot.
|
/// reading or writing the snapshot.
|
||||||
pub fn try_image_snapshot_options(
|
pub fn try_image_snapshot_options(
|
||||||
current: &image::RgbaImage,
|
new: &image::RgbaImage,
|
||||||
name: &str,
|
name: &str,
|
||||||
options: &SnapshotOptions,
|
options: &SnapshotOptions,
|
||||||
) -> Result<(), SnapshotError> {
|
) -> Result<(), SnapshotError> {
|
||||||
|
|
@ -201,45 +188,72 @@ pub fn try_image_snapshot_options(
|
||||||
output_path,
|
output_path,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
let path = output_path.join(format!("{name}.png"));
|
std::fs::create_dir_all(output_path).ok();
|
||||||
std::fs::create_dir_all(path.parent().expect("Could not get snapshot folder")).ok();
|
|
||||||
|
|
||||||
|
// The one that is checked in to git
|
||||||
|
let snapshot_path = output_path.join(format!("{name}.png"));
|
||||||
|
|
||||||
|
// These should be in .gitignore:
|
||||||
let diff_path = output_path.join(format!("{name}.diff.png"));
|
let diff_path = output_path.join(format!("{name}.diff.png"));
|
||||||
let current_path = output_path.join(format!("{name}.new.png"));
|
let old_backup_path = output_path.join(format!("{name}.old.png"));
|
||||||
|
let new_path = output_path.join(format!("{name}.new.png"));
|
||||||
|
|
||||||
current
|
// Delete old temporary files if they exist:
|
||||||
.save(¤t_path)
|
std::fs::remove_file(&diff_path).ok();
|
||||||
|
std::fs::remove_file(&old_backup_path).ok();
|
||||||
|
std::fs::remove_file(&new_path).ok();
|
||||||
|
|
||||||
|
let maybe_update_snapshot = || {
|
||||||
|
if should_update_snapshots() {
|
||||||
|
// Keep the old version so the user can compare it:
|
||||||
|
std::fs::rename(&snapshot_path, &old_backup_path).ok();
|
||||||
|
|
||||||
|
// Write the new file to the checked in path:
|
||||||
|
new.save(&snapshot_path)
|
||||||
|
.map_err(|err| SnapshotError::WriteSnapshot {
|
||||||
|
err,
|
||||||
|
path: snapshot_path.clone(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// No need for an explicit `.new` file:
|
||||||
|
std::fs::remove_file(&new_path).ok();
|
||||||
|
|
||||||
|
println!("Updated snapshot: {snapshot_path:?}");
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
};
|
||||||
|
|
||||||
|
// Always write a `.new` file so the user can compare:
|
||||||
|
new.save(&new_path)
|
||||||
.map_err(|err| SnapshotError::WriteSnapshot {
|
.map_err(|err| SnapshotError::WriteSnapshot {
|
||||||
err,
|
err,
|
||||||
path: current_path,
|
path: new_path.clone(),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let previous = match image::open(&path) {
|
let previous = match image::open(&snapshot_path) {
|
||||||
Ok(image) => image.to_rgba8(),
|
Ok(image) => image.to_rgba8(),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
maybe_update_snapshot(&path, current)?;
|
// No previous snapshot - probablye a new test.
|
||||||
return Err(SnapshotError::OpenSnapshot { path, err });
|
maybe_update_snapshot()?;
|
||||||
|
return Err(SnapshotError::OpenSnapshot {
|
||||||
|
path: snapshot_path.clone(),
|
||||||
|
err,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if previous.dimensions() != current.dimensions() {
|
if previous.dimensions() != new.dimensions() {
|
||||||
maybe_update_snapshot(&path, current)?;
|
maybe_update_snapshot()?;
|
||||||
return Err(SnapshotError::SizeMismatch {
|
return Err(SnapshotError::SizeMismatch {
|
||||||
name: name.to_owned(),
|
name: name.to_owned(),
|
||||||
expected: previous.dimensions(),
|
expected: previous.dimensions(),
|
||||||
actual: current.dimensions(),
|
actual: new.dimensions(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = dify::diff::get_results(
|
// Compare existing image to the new one:
|
||||||
previous,
|
let result =
|
||||||
current.clone(),
|
dify::diff::get_results(previous, new.clone(), *threshold, true, None, &None, &None);
|
||||||
*threshold,
|
|
||||||
true,
|
|
||||||
None,
|
|
||||||
&None,
|
|
||||||
&None,
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some((diff, result_image)) = result {
|
if let Some((diff, result_image)) = result {
|
||||||
result_image
|
result_image
|
||||||
|
|
@ -248,15 +262,13 @@ pub fn try_image_snapshot_options(
|
||||||
path: diff_path.clone(),
|
path: diff_path.clone(),
|
||||||
err,
|
err,
|
||||||
})?;
|
})?;
|
||||||
maybe_update_snapshot(&path, current)?;
|
maybe_update_snapshot()?;
|
||||||
Err(SnapshotError::Diff {
|
Err(SnapshotError::Diff {
|
||||||
name: name.to_owned(),
|
name: name.to_owned(),
|
||||||
diff,
|
diff,
|
||||||
diff_path,
|
diff_path,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// Delete old diff if it exists
|
|
||||||
std::fs::remove_file(diff_path).ok();
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue