| name | write-unit-test |
| description | The required unit-test format for `crates/**/src/**` — use when writing or reviewing a Rust `#[test]`, a test helper, or an `assert_*`. Not for `tasks/compiler_tests/` (use add-test) or `tasks/diagnostic_tests/` (use add-diagnostic-test). |
| paths | ["crates/**/src/**/*.rs"] |
Write unit test
Body is at most three lines — setup, optional execute, assert:
#[test]
fn dynamic_expr_inside_svelte_element() {
let (c, data) = analyze_source(r#"...<svelte:element this={"div"}>{name}</svelte:element>"#);
assert_dynamic_tag(&data, &c, "name");
}
- setup — a Creation Method (
analyze_source, build_instance, parse) hiding parse/mocks/fixtures behind an intent-revealing name.
- execute — optional; omit when the factory already runs the action (
analyze_source parses and analyzes), keep it on its own line when the action is the point of the test (transform, codegen).
- assert — exactly one Custom Assertion (
assert_*); this is the Single-Condition Test (Meszaros' xUnit).
Blank line between tests.
Rules
- Single-Condition Test. Never stack
assert_a(); assert_b(); — bundle the checks into one Custom Assertion, which holds as many raw assert_eq!/assert! inside as needed.
- Assert per entity, expectations as args. Prefer one reusable assert keyed to the thing under test (
assert_start_tag(tok, src, name, self_closing)) over a one-off helper per test. Converges to a shared vocabulary, not a long tail.
#[track_caller] on every assert_*. Required — else the panic points inside the helper instead of the failing test.
- Explicit messages. Every inner check names the expectation and prints the actual:
assert_eq!(got, expected, "name: expected {expected:?}, got {got:?}"). No bare assert!(cond).
- No raw asserts in the body — only behind a named
assert_*.
- Name the test after the behaviour, not the function:
reports_diagnostic_when_prop_unknown.
Helpers
Live in the same #[cfg(test)] mod tests / tests.rs. Reuse before adding — the repo has dozens of assert_* and analyze_*/build_* factories; grep fn assert_ / fn build_ in the target crate first.
Examples
EXAMPLES.md — eight cases in one shape, plus a well-formed #[track_caller] assert.