Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Read and follow the CONTRIBUTING.md file in this repository for all code style c
- For error types, only derive `Display` and `Error` from `derive_more` when each is actually needed. Not all displayable types are errors.
- Minimize `unwrap()` in non-test code. Use proper error handling instead.
- Prefer `#[cfg_attr(..., ignore = "reason")]` over `#[cfg(...)]` when skipping tests. Use `#[cfg]` on tests only when the code cannot compile under the condition, such as when it references types or functions that do not exist on other platforms.
- A unit-test module may sit inline as `mod tests { ... }` when it is short. Once it grows long enough to noticeably extend the parent, move it to an external file and declare the module with `#[cfg(test)] mod tests;` at the end of the parent. The external file lives at `src/foo/tests.rs` for a parent `src/foo.rs`, and at `src/foo/bar/tests.rs` for a parent `src/foo/bar.rs`. Use this layout even when the parent has no other submodules.
- Install the toolchain before running tests: `rustup toolchain install "$(< rust-toolchain)" && rustup component add --toolchain "$(< rust-toolchain)" rustfmt clippy`.
- When you change CLI arguments, help text, or anything that affects command-line output, run `./generate-completions.sh` to regenerate the shell completion files, the help text files, `USAGE.md`, and the man page. **Do not attempt to regenerate these files manually.** Always use the script.
- Validate changes with `FMT=true LINT=true BUILD=true TEST=true DOC=true ./test.sh`. When a test fails with a hint about `TEST_SKIP`, follow the hint and rerun with the suggested variable. When a sync test fails, read its error message and run the exact command it reports.
Expand Down
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Read and follow the CONTRIBUTING.md file in this repository for all code style c
- For error types, only derive `Display` and `Error` from `derive_more` when each is actually needed. Not all displayable types are errors.
- Minimize `unwrap()` in non-test code. Use proper error handling instead.
- Prefer `#[cfg_attr(..., ignore = "reason")]` over `#[cfg(...)]` when skipping tests. Use `#[cfg]` on tests only when the code cannot compile under the condition, such as when it references types or functions that do not exist on other platforms.
- A unit-test module may sit inline as `mod tests { ... }` when it is short. Once it grows long enough to noticeably extend the parent, move it to an external file and declare the module with `#[cfg(test)] mod tests;` at the end of the parent. The external file lives at `src/foo/tests.rs` for a parent `src/foo.rs`, and at `src/foo/bar/tests.rs` for a parent `src/foo/bar.rs`. Use this layout even when the parent has no other submodules.
- Install the toolchain before running tests: `rustup toolchain install "$(< rust-toolchain)" && rustup component add --toolchain "$(< rust-toolchain)" rustfmt clippy`.
- When you change CLI arguments, help text, or anything that affects command-line output, run `./generate-completions.sh` to regenerate the shell completion files, the help text files, `USAGE.md`, and the man page. **Do not attempt to regenerate these files manually.** Always use the script.
- Validate changes with `FMT=true LINT=true BUILD=true TEST=true DOC=true ./test.sh`. When a test fails with a hint about `TEST_SKIP`, follow the hint and rerun with the suggested variable. When a sync test fails, read its error message and run the exact command it reports.
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Read and follow the CONTRIBUTING.md file in this repository for all code style c
- For error types, only derive `Display` and `Error` from `derive_more` when each is actually needed. Not all displayable types are errors.
- Minimize `unwrap()` in non-test code. Use proper error handling instead.
- Prefer `#[cfg_attr(..., ignore = "reason")]` over `#[cfg(...)]` when skipping tests. Use `#[cfg]` on tests only when the code cannot compile under the condition, such as when it references types or functions that do not exist on other platforms.
- A unit-test module may sit inline as `mod tests { ... }` when it is short. Once it grows long enough to noticeably extend the parent, move it to an external file and declare the module with `#[cfg(test)] mod tests;` at the end of the parent. The external file lives at `src/foo/tests.rs` for a parent `src/foo.rs`, and at `src/foo/bar/tests.rs` for a parent `src/foo/bar.rs`. Use this layout even when the parent has no other submodules.
- Install the toolchain before running tests: `rustup toolchain install "$(< rust-toolchain)" && rustup component add --toolchain "$(< rust-toolchain)" rustfmt clippy`.
- When you change CLI arguments, help text, or anything that affects command-line output, run `./generate-completions.sh` to regenerate the shell completion files, the help text files, `USAGE.md`, and the man page. **Do not attempt to regenerate these files manually.** Always use the script.
- Validate changes with `FMT=true LINT=true BUILD=true TEST=true DOC=true ./test.sh`. When a test fails with a hint about `TEST_SKIP`, follow the hint and rerun with the suggested variable. When a sync test fails, read its error message and run the exact command it reports.
Expand Down
24 changes: 24 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,30 @@ ExitCode::from(match self {
})
```

## Unit Tests

A unit-test module may either sit inline as `mod tests { ... }` in its parent or live in a dedicated external `tests` submodule. Use the inline form for short test modules. Once the block becomes long enough to obscure the surrounding module, move the tests into an external file.

### When the inline form is acceptable

The inline form `mod tests { ... }` is acceptable on its own. Reserve it for modules whose entire test suite fits in a small number of lines, so the block does not noticeably extend the parent. Use the number of lines as the deciding factor.

### Where the external file sits

When the tests live externally, the parent declares them at the end of the file with the standard declaration:

```rust
#[cfg(test)]
mod tests;
```

The external file itself sits in a directory named after the parent, using the same path regardless of whether the parent has any other submodules. Concretely:

- For `src/foo.rs`, the tests file is `src/foo/tests.rs`.
- For `src/foo/bar.rs`, the tests file is `src/foo/bar/tests.rs`.

Do not flatten the tests into a sibling file such as `src/foo_tests.rs`, and do not skip the intermediate directory when the parent currently has no other submodules. This mirrors the flat file pattern (`module.rs` rather than `module/mod.rs`) described under [Module Organization](#module-organization).

## Setup

Install the required Rust toolchain and components before running any checks:
Expand Down
1 change: 1 addition & 0 deletions template/ai-instructions/shared.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Read and follow the CONTRIBUTING.md file in this repository for all code style c
- For error types, only derive `Display` and `Error` from `derive_more` when each is actually needed. Not all displayable types are errors.
- Minimize `unwrap()` in non-test code. Use proper error handling instead.
- Prefer `#[cfg_attr(..., ignore = "reason")]` over `#[cfg(...)]` when skipping tests. Use `#[cfg]` on tests only when the code cannot compile under the condition, such as when it references types or functions that do not exist on other platforms.
- A unit-test module may sit inline as `mod tests { ... }` when it is short. Once it grows long enough to noticeably extend the parent, move it to an external file and declare the module with `#[cfg(test)] mod tests;` at the end of the parent. The external file lives at `src/foo/tests.rs` for a parent `src/foo.rs`, and at `src/foo/bar/tests.rs` for a parent `src/foo/bar.rs`. Use this layout even when the parent has no other submodules.
- Install the toolchain before running tests: `rustup toolchain install "$(< rust-toolchain)" && rustup component add --toolchain "$(< rust-toolchain)" rustfmt clippy`.
- When you change CLI arguments, help text, or anything that affects command-line output, run `./generate-completions.sh` to regenerate the shell completion files, the help text files, `USAGE.md`, and the man page. **Do not attempt to regenerate these files manually.** Always use the script.
- Validate changes with `FMT=true LINT=true BUILD=true TEST=true DOC=true ./test.sh`. When a test fails with a hint about `TEST_SKIP`, follow the hint and rerun with the suggested variable. When a sync test fails, read its error message and run the exact command it reports.
Expand Down