tmuxido/CLAUDE.md
cinco euzebio 30d6c3d1c5 chore: install Claude scaffold
Add CLAUDE.md with project-specific rules (test structure, naming
conventions, MCP tools reference). Add .mcp.json for rust-mcp and
crates-io MCP servers. Add rust-toolchain.toml pinning stable with
rustfmt and clippy. Add .claude/settings.json with PostToolUse hook
that runs cargo test automatically after every file edit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 20:15:08 -03:00

122 lines
2.9 KiB
Markdown

# Rust Project — Claude Instructions
## Mandatory Rules
1. **Always write tests** alongside production code — no feature ships without tests
2. **Always verify tests pass** after every change — the PostToolUse hook runs automatically;
if it shows failures, fix them before moving on
3. Run `cargo clippy -- -D warnings` and resolve all warnings
4. Run `cargo fmt` before considering any task complete
## Available MCP Tools
Install with `curl -sSf https://raw.githubusercontent.com/USUARIO/claude-rust-scaffold/main/install.sh | sh`
| Server | Tools | Purpose |
|--------|-------|---------|
| `rust-mcp` | `cargo_check`, `cargo_build`, `cargo_test`, `cargo_clippy`, `cargo_fmt`, `cargo_add` | Run cargo commands directly |
| `crates` | search, versions, dependencies, docs | Explore crates.io and docs.rs |
## Test Structure
### Unit Tests — inside `src/`
Place at the bottom of each source file:
```rust
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn should_return_error_when_input_is_empty() {
// arrange
let input = "";
// act
let result = parse(input);
// assert
assert!(result.is_err());
}
}
```
- Name tests descriptively: `should_<outcome>_when_<condition>`
- Cover: happy path, edge cases (empty, max values), error cases
### Integration Tests — `tests/` directory
- One file per feature or behavior
- Use only public interfaces (`pub`)
- Simulate real usage end-to-end
```rust
// tests/parsing.rs
use tmuxido::parse;
#[test]
fn parses_valid_input_successfully() {
let result = parse("valid input");
assert!(result.is_ok());
}
```
### Snapshot Testing with `insta`
For complex outputs or large structs:
```rust
#[test]
fn renders_report_correctly() {
let report = generate_report(&data);
insta::assert_snapshot!(report);
}
```
Review snapshots: `cargo insta review`
### Property Testing with `proptest`
For pure functions over wide input domains:
```rust
use proptest::prelude::*;
proptest! {
#[test]
fn round_trip_encode_decode(s in ".*") {
let encoded = encode(&s);
prop_assert_eq!(decode(&encoded), s);
}
}
```
## Recommended `Cargo.toml` dev-dependencies
```toml
[dev-dependencies]
proptest = "1"
insta = { version = "1", features = ["json", "yaml"] }
mockall = "0.13"
# if async:
tokio = { version = "1", features = ["full", "test-util"] }
```
## Recommended Project Structure
```
tmuxido/
├── Cargo.toml
├── src/
│ ├── lib.rs # core logic (unit tests at bottom)
│ ├── main.rs # entrypoint (thin, delegates to lib)
│ └── module/
│ └── mod.rs # #[cfg(test)] mod tests {} at bottom
├── tests/
│ └── integration.rs # integration tests
└── benches/
└── bench.rs # benchmarks (optional)
```
Prefer `lib.rs` + `main.rs` split so logic stays testable independently of the binary entrypoint.