pub struct Snapshot { /* private fields */ }Expand description
A normalized, comparable rendering of some compiler output.
Snapshots normalize three things so that byte-for-byte equality is not required for a test to pass:
- Line endings.
\r\nand lone\rboth become\n. - Trailing whitespace. Spaces and tabs at the end of each line are stripped, so an editor that trims (or fails to trim) lines does not break a test.
- Trailing blank lines. A trailing newline — or several — is removed, so the expected text can be written with or without one.
Interior blank lines and leading whitespace are preserved: they are usually significant (indentation in a pretty-printed tree, for example).
§Examples
Capture a value that implements Display:
use test_lang::Snapshot;
let snap = Snapshot::display(&42);
assert_eq!(snap.as_str(), "42");Capture a token stream, one item per line:
use test_lang::Snapshot;
let tokens = ["let", "x", "=", "1"];
let snap = Snapshot::per_line(tokens);
assert_eq!(snap.as_str(), "let\nx\n=\n1");Implementations§
Source§impl Snapshot
impl Snapshot
Sourcepub fn new(text: impl AsRef<str>) -> Self
pub fn new(text: impl AsRef<str>) -> Self
Build a snapshot from an already-rendered block of text.
The input is normalized (see the type-level docs). Use this when the
stage under test already hands you a String.
§Examples
use test_lang::Snapshot;
// Trailing whitespace and CRLF endings are normalized away.
let snap = Snapshot::new("a \r\nb\n");
assert_eq!(snap.as_str(), "a\nb");Sourcepub fn display(value: &impl Display) -> Self
pub fn display(value: &impl Display) -> Self
Build a snapshot by rendering a value through its
Display implementation.
This is the natural entry point for a value that already knows how to print itself the way a test should read it — a formatted diagnostic, a single token, a pretty-printed tree.
§Examples
use core::fmt;
use test_lang::Snapshot;
struct Diagnostic;
impl fmt::Display for Diagnostic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "error: unexpected token")
}
}
let snap = Snapshot::display(&Diagnostic);
assert_eq!(snap.as_str(), "error: unexpected token");Sourcepub fn debug(value: &impl Debug) -> Self
pub fn debug(value: &impl Debug) -> Self
Build a snapshot by rendering a value through its
Debug implementation, using the alternate ({:#?})
pretty form.
Most syntax-tree node types derive Debug but not Display; this
captures the multi-line pretty-printed tree without requiring the node to
implement a display format of its own.
§Examples
use test_lang::Snapshot;
#[derive(Debug)]
struct Binary { op: char }
let snap = Snapshot::debug(&Binary { op: '+' });
assert!(snap.as_str().contains("op: '+'"));Sourcepub fn per_line<I>(items: I) -> Self
pub fn per_line<I>(items: I) -> Self
Build a snapshot from a sequence of values, rendering each on its own
line through Display.
This is the idiomatic way to snapshot a token stream: one token per line makes the diff on failure point at the exact token that changed.
§Examples
use test_lang::Snapshot;
let kinds = ["Ident(x)", "Eq", "Int(1)"];
let snap = Snapshot::per_line(kinds);
assert_eq!(snap.as_str(), "Ident(x)\nEq\nInt(1)");An empty sequence yields an empty snapshot:
use test_lang::Snapshot;
let empty: [&str; 0] = [];
assert_eq!(Snapshot::per_line(empty).as_str(), "");Sourcepub fn as_str(&self) -> &str
pub fn as_str(&self) -> &str
The normalized snapshot text.
This is what check compares, and what you paste back
into a test as the expected value when accepting a new snapshot.
Sourcepub fn check(&self, expected: impl AsRef<str>) -> Result<(), Mismatch>
pub fn check(&self, expected: impl AsRef<str>) -> Result<(), Mismatch>
Compare the snapshot against the expected text.
The expected text is normalized the same way the snapshot was, so it can
be written inline in a test as a plain string literal without worrying
about trailing newlines or platform line endings. Returns Ok(()) on a
match, or a Mismatch carrying the diff otherwise.
§Errors
Returns Mismatch when the normalized snapshot differs from the
normalized expected text. The error’s Display renders
a unified diff; Mismatch::diff exposes it programmatically.
§Examples
A matching snapshot:
use test_lang::Snapshot;
let snap = Snapshot::per_line(["a", "b"]);
assert!(snap.check("a\nb").is_ok());A mismatch carries a diff you can print or inspect:
use test_lang::Snapshot;
let snap = Snapshot::per_line(["a", "b"]);
let err = snap.check("a\nc").unwrap_err();
assert!(err.to_string().contains("-c")); // expected `c`, was missing
assert!(err.to_string().contains("+b")); // `b` was produced instead