Skip to main content

assert_snap/
assert_impl.rs

1use std::borrow::Cow;
2
3use crate::redaction::{RedactionRule, apply_redactions};
4
5/// Asserts that an actual value matches an expected snapshot value after applying redaction rules.
6///
7/// This function compares `actual` against `expected` after applying the provided
8/// `redaction_rules` to the actual value. If they don't match, it prints diagnostic information
9/// and panics.
10///
11/// # Arguments
12///
13/// * `actual` - The actual value produced by the code under test.
14/// * `expected` - The expected snapshot value to compare against.
15/// * `redaction_rules` - A slice of redaction rules to apply to `actual` before comparison.
16///   These are typically used to mask dynamic content like timestamps, IDs, or memory addresses.
17///
18/// # Panics
19///
20/// Panics if the redacted `actual` does not equal `expected`. When the `diff` feature
21/// is enabled, a unified diff is printed showing the differences.
22///
23#[track_caller]
24pub fn assert_snap(actual: &str, expected: &str, redaction_rules: &[RedactionRule]) {
25    println!("===== ACTUAL VALUE =====");
26    println!("{actual}\n");
27    let actual = apply_redactions(actual, redaction_rules);
28    if matches!(actual, Cow::Owned(_)) {
29        println!("===== REDACTED VALUE =====");
30        println!("{actual}\n");
31    }
32
33    if expected != actual {
34        println!("===== EXPECTED VALUE =====");
35        println!("{expected}\n");
36        #[cfg(feature = "diff")]
37        show_diff(&actual, expected);
38        panic!("===== ASSERTION Failed =====");
39    }
40    println!("===== ASSERTION PASSED =====");
41}
42
43#[cfg(feature = "diff")]
44#[track_caller]
45fn show_diff(actual: &str, expected: &str) {
46    use similar::TextDiff;
47
48    println!("===== DIFF =====");
49    let diff = TextDiff::from_lines(expected, actual);
50    println!(
51        "{}",
52        diff.unified_diff()
53            .header("EXPECTED VALUE", "ACTUAL/REDACTED VALUE")
54            .missing_newline_hint(false)
55    );
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61    #[test]
62    fn test_assert_impl() {
63        let real = "User(id=123, name=Alice)";
64        let expected = "User(id=REDACTED, name=Alice)";
65        let rules = [RedactionRule::new(r"id=\d+", "id=REDACTED", 0)];
66        assert_snap(real, expected, &rules);
67    }
68}