mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-03-31 06:03:29 +08:00
* feat(rules): add Rust coding style, hooks, and patterns rules Add language-specific rules for Rust extending the common rule set: - coding-style.md: rustfmt, clippy, ownership idioms, error handling, iterator patterns, module organization, visibility - hooks.md: PostToolUse hooks for rustfmt, clippy, cargo check - patterns.md: trait-based repository, newtype, enum state machines, builder, sealed traits, API response envelope Rules reference existing rust-patterns skill for deep content. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering> * feat(rules): add Rust testing and security rules Add remaining Rust language-specific rules: - testing.md: cargo test, rstest parameterized tests, mockall mocking with mock! macro, tokio async tests, cargo-llvm-cov coverage - security.md: secrets via env vars, parameterized SQL with sqlx, parse-don't-validate input validation, unsafe code audit requirements, cargo-audit dependency scanning, proper HTTP error status codes Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering> * fix(rules): address review feedback on Rust rules Fixes from Copilot, Greptile, Cubic, and CodeRabbit reviews: - Add missing imports: use std::borrow::Cow, use anyhow::Context - Use anyhow::Result<T> consistently (patterns.md, security.md) - Change sqlx placeholder from ? to $1 (Postgres is most common) - Remove Cargo.lock from hooks.md paths (auto-generated file) - Fix tokio::test to show attribute form #[tokio::test] - Fix mockall mock! name collision, wrap in #[cfg(test)] mod tests - Fix --test target to match file layout (api_test, not integration) Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering> * fix: update catalog counts in README.md and AGENTS.md Update documented counts to match actual repository state after rebase: - Skills: 109 → 113 (new skills merged to main) - Commands: 57 → 58 (new command merged to main) Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering> --------- Co-authored-by: Chris Yau <chris@diveanddev.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Happy <yesreply@happy.engineering>
3.8 KiB
3.8 KiB
paths
| paths | |
|---|---|
|
Rust Testing
This file extends common/testing.md with Rust-specific content.
Test Framework
#[test]with#[cfg(test)]modules for unit tests- rstest for parameterized tests and fixtures
- proptest for property-based testing
- mockall for trait-based mocking
#[tokio::test]for async tests
Test Organization
my_crate/
├── src/
│ ├── lib.rs # Unit tests in #[cfg(test)] modules
│ ├── auth/
│ │ └── mod.rs # #[cfg(test)] mod tests { ... }
│ └── orders/
│ └── service.rs # #[cfg(test)] mod tests { ... }
├── tests/ # Integration tests (each file = separate binary)
│ ├── api_test.rs
│ ├── db_test.rs
│ └── common/ # Shared test utilities
│ └── mod.rs
└── benches/ # Criterion benchmarks
└── benchmark.rs
Unit tests go inside #[cfg(test)] modules in the same file. Integration tests go in tests/.
Unit Test Pattern
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn creates_user_with_valid_email() {
let user = User::new("Alice", "alice@example.com").unwrap();
assert_eq!(user.name, "Alice");
}
#[test]
fn rejects_invalid_email() {
let result = User::new("Bob", "not-an-email");
assert!(result.is_err());
assert!(result.unwrap_err().to_string().contains("invalid email"));
}
}
Parameterized Tests
use rstest::rstest;
#[rstest]
#[case("hello", 5)]
#[case("", 0)]
#[case("rust", 4)]
fn test_string_length(#[case] input: &str, #[case] expected: usize) {
assert_eq!(input.len(), expected);
}
Async Tests
#[tokio::test]
async fn fetches_data_successfully() {
let client = TestClient::new().await;
let result = client.get("/data").await;
assert!(result.is_ok());
}
Mocking with mockall
Define traits in production code; generate mocks in test modules:
// Production trait — pub so integration tests can import it
pub trait UserRepository {
fn find_by_id(&self, id: u64) -> Option<User>;
}
#[cfg(test)]
mod tests {
use super::*;
use mockall::predicate::eq;
mockall::mock! {
pub Repo {}
impl UserRepository for Repo {
fn find_by_id(&self, id: u64) -> Option<User>;
}
}
#[test]
fn service_returns_user_when_found() {
let mut mock = MockRepo::new();
mock.expect_find_by_id()
.with(eq(42))
.times(1)
.returning(|_| Some(User { id: 42, name: "Alice".into() }));
let service = UserService::new(Box::new(mock));
let user = service.get_user(42).unwrap();
assert_eq!(user.name, "Alice");
}
}
Test Naming
Use descriptive names that explain the scenario:
creates_user_with_valid_email()rejects_order_when_insufficient_stock()returns_none_when_not_found()
Coverage
- Target 80%+ line coverage
- Use cargo-llvm-cov for coverage reporting
- Focus on business logic — exclude generated code and FFI bindings
cargo llvm-cov # Summary
cargo llvm-cov --html # HTML report
cargo llvm-cov --fail-under-lines 80 # Fail if below threshold
Testing Commands
cargo test # Run all tests
cargo test -- --nocapture # Show println output
cargo test test_name # Run tests matching pattern
cargo test --lib # Unit tests only
cargo test --test api_test # Specific integration test (tests/api_test.rs)
cargo test --doc # Doc tests only
References
See skill: rust-testing for comprehensive testing patterns including property-based testing, fixtures, and benchmarking with Criterion.