Skip to content

v1.0.0 — Stable API

Latest

Choose a tag to compare

@jamesgober jamesgober released this 01 Jul 12:41

test-lang v1.0.0 — API Freeze

The public surface is now stable. Everything that shipped in 0.2.0 — the four types, their methods, their trait implementations — is frozen under SemVer: no breaking change lands before a 2.0, and 1.x releases add capability without removing or altering what exists. There are no functional changes from 0.2.0; this release records the promise.

What is test-lang?

A snapshot test harness for language front-ends. Give it source, run that source through a lexer, parser, or diagnostics renderer, and assert the rendered result against a known-good block of text. When the output changes, you get a line-level unified diff pointing at exactly what moved, and accepting the new behavior is a copy-paste. It owns no grammar and depends on no other front-end crate — it works over core::fmt::Display and Debug, so the same harness serves a hand-written lexer or a generated parser without coupling to either. no_std + alloc supported.

The frozen surface

Two types you construct, one you receive on failure, and the pair that describes what differed:

  • Snapshot — a normalized, comparable rendering of some stage's output.
    • new, display, debug, per_line — capture from a string, a Display value, a pretty-printed Debug tree, or a sequence of items (one per line).
    • as_str, check — read the normalized text; compare against expected text, returning Result<(), Mismatch>.
    • Implements Display + the standard Debug/Clone/PartialEq/Eq/Hash.
  • Diff + Change — the line-level edit script (LCS with a common prefix/suffix fast path), rendered as a unified -expected/+actual diff.
    • Diff::lines, is_empty, changes; Change::marker.
  • Mismatch — the error from Snapshot::check, carrying the Diff, implementing Display and core::error::Error.
use test_lang::Snapshot;

let snapshot = Snapshot::per_line(["let", "x", "=", "1"]);
snapshot.check("let\nx\n=\n1").expect("token stream matches");

The full reference, with parameters and multiple runnable examples per item, is in docs/API.md — now marked stable.

What the freeze means

  • No breaking changes before 2.0. Method signatures, type names, variant names, and trait impls listed in docs/API.md are fixed.
  • 1.x is additive. New constructors, helpers, or trait impls may arrive in minor releases; nothing already present will be removed or changed.
  • Normalization is part of the contract. CRLF/CR collapse to LF, trailing whitespace is stripped, and trailing blank lines are trimmed — so a snapshot written on one platform matches output captured on another. This behavior is stable.

Breaking changes

None. The API is identical to 0.2.0. The only documentation correction: the std feature description now states accurately that the Error impl is core::error::Error in both std and no_std builds — the feature only controls whether the standard library is linked.

Verification

Re-ran the full gate on Windows x86_64 (Rust stable 1.95) and Linux (WSL2 Ubuntu); MSRV 1.85 verified locally; the CI matrix covers Linux / macOS / Windows × stable / 1.85:

cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
cargo clippy --all-targets --all-features -- -D warnings
cargo test
cargo test --all-features
cargo test --no-default-features
cargo build --examples
cargo +1.85 build --all-features
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features
cargo deny check

All green. Test counts at this tag: 30 unit + 8 integration + 6 property + 18 doctests.

What's next

The public API is frozen; future 1.x work is additive and driven by real usage — candidates include a by-value Display capture helper, a compact ({:?}) debug variant, and a convenience assertion macro. None are required, and none will break existing code.

Installation

[dependencies]
test-lang = "1"

# no_std + alloc
test-lang = { version = "1", default-features = false }

MSRV: Rust 1.85.

Documentation


Full diff: v0.2.0...v1.0.0.
Changelog: CHANGELOG.md.