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)
30 .unwrap_or_else(|err| panic!("Writing `{snapshot_path:?}`: {err}"));
31 } else {
32 let expected = std::fs::read_to_string(snapshot_path)
34 .unwrap_or_else(|err| panic!("Reading `{snapshot_path:?}`: {err}"));
35 similar_asserts::assert_eq!(actual, expected);
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42
43 struct DirGuard(std::path::PathBuf);
44 impl DirGuard {
45 fn new(path: std::path::PathBuf) -> Self {
46 std::fs::create_dir_all(&path).unwrap();
47 Self(path)
48 }
49 }
50 impl Drop for DirGuard {
51 fn drop(&mut self) {
52 let _ = std::fs::remove_dir_all(&self.0);
53 }
54 }
55
56 fn test_assert_eq(first: &str, second: &str) {
57 let dir = DirGuard::new(
58 std::env::temp_dir().join(format!("assert-or-bless-{}", fastrand::u32(0..1_000_000))),
59 );
60 let snapshot_path = dir.0.join("test-snapshot.txt");
61 assert_eq_or_bless_if(first, &snapshot_path, true);
62 assert_eq_or_bless(second, &snapshot_path);
63 }
64
65 #[test]
66 fn assert_eq_succeeds() {
67 test_assert_eq(
68 "this is the\ncorrect snapshot contents",
69 "this is the\ncorrect snapshot contents",
70 );
71 }
72
73 #[test]
74 #[should_panic]
75 fn assert_eq_panics() {
76 test_assert_eq(
77 "this is the\ncorrect snapshot contents",
78 "this is the\nWRONG snapshot contents",
79 );
80 }
81}