1pub fn assert_eq_or_bless(actual: impl AsRef<str>, snapshot_path: impl AsRef<std::path::Path>) {
9 assert_eq_or_bless_if(
10 actual,
11 snapshot_path,
12 std::env::var("ASSERT_OR_BLESS") == Ok("bless".to_string()),
13 );
14}
15
16pub fn assert_eq_or_bless_if(
20 actual: impl AsRef<str>,
21 snapshot_path: impl AsRef<std::path::Path>,
22 bless: bool,
23) {
24 let snapshot_path = snapshot_path.as_ref();
25 let actual = actual.as_ref();
26
27 if bless {
28 std::fs::write(snapshot_path, actual)
29 .unwrap_or_else(|err| panic!("Writing `{snapshot_path:?}`: {err}"));
30 } else {
31 let expected = std::fs::read_to_string(snapshot_path)
32 .unwrap_or_else(|err| panic!("Reading `{snapshot_path:?}`: {err}"));
33 similar_asserts::assert_eq!(actual, expected);
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 struct DirGuard(std::path::PathBuf);
42 impl DirGuard {
43 fn new(path: std::path::PathBuf) -> Self {
44 std::fs::create_dir_all(&path).unwrap();
45 Self(path)
46 }
47 }
48 impl Drop for DirGuard {
49 fn drop(&mut self) {
50 let _ = std::fs::remove_dir_all(&self.0);
51 }
52 }
53
54 fn test_assert_eq(first: &str, second: &str) {
55 let dir = DirGuard::new(
56 std::env::temp_dir().join(format!("assert-or-bless-{}", fastrand::u32(0..1_000_000))),
57 );
58 let snapshot_path = dir.0.join("test-snapshot.txt");
59 assert_eq_or_bless_if(first, &snapshot_path, true);
60 assert_eq_or_bless(second, &snapshot_path);
61 }
62
63 #[test]
64 fn assert_eq_succeeds() {
65 test_assert_eq(
66 "this is the\ncorrect snapshot contents",
67 "this is the\ncorrect snapshot contents",
68 );
69 }
70
71 #[test]
72 #[should_panic]
73 fn assert_eq_panics() {
74 test_assert_eq(
75 "this is the\ncorrect snapshot contents",
76 "this is the\nWRONG snapshot contents",
77 );
78 }
79}