mirror of
https://github.com/affaan-m/ECC.git
synced 2026-08-20 22:42:22 +02:00
The `.opencode/commands/*.md` frontmatter referenced agents with the Claude Code plugin namespace (`agent: everything-claude-code:<name>`), but ECC's opencode integration registers its agents unscoped in `opencode.json`'s `agent` map (`code-reviewer`, `planner`, ...), and that file's own `command` section already references them unscoped. The `everything-claude-code:` scope resolves under no opencode config (the opencode plugin package is `ecc-universal`, and inline-config agents are bare), so subtask commands like `/code-review` hard-fail with `Agent not found: everything-claude-code:code-reviewer`. Non-subtask commands fall back to the default agent and appear to work — which is why only some commands failed. Strip the `everything-claude-code:` prefix from all 30 command frontmatter agent ids so they match the registered agents, fix the MIGRATION.md example, and replace the test that enforced the broken scoped invariant with one that asserts each command agent id is a registered opencode agent (fails on the old scoped ids, passes on the fix). Fixes #2477
105 lines
2.2 KiB
Markdown
105 lines
2.2 KiB
Markdown
---
|
|
description: Rust TDD workflow with unit and property tests
|
|
agent: tdd-guide
|
|
subtask: true
|
|
---
|
|
|
|
# Rust Test Command
|
|
|
|
Implement using Rust TDD methodology: $ARGUMENTS
|
|
|
|
## Your Task
|
|
|
|
Apply test-driven development with Rust idioms:
|
|
|
|
1. **Define types** - Structs, enums, traits
|
|
2. **Write tests** - Unit tests in `#[cfg(test)]` modules
|
|
3. **Implement minimal code** - Pass the tests
|
|
4. **Check coverage** - Target 80%+
|
|
|
|
## TDD Cycle for Rust
|
|
|
|
### Step 1: Define Interface
|
|
```rust
|
|
pub struct Input {
|
|
// fields
|
|
}
|
|
|
|
pub fn process(input: &Input) -> Result<Output, Error> {
|
|
todo!()
|
|
}
|
|
```
|
|
|
|
### Step 2: Write Tests
|
|
```rust
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn valid_input_succeeds() {
|
|
let input = Input { /* ... */ };
|
|
let result = process(&input);
|
|
assert!(result.is_ok());
|
|
}
|
|
|
|
#[test]
|
|
fn invalid_input_returns_error() {
|
|
let input = Input { /* ... */ };
|
|
let result = process(&input);
|
|
assert!(result.is_err());
|
|
}
|
|
}
|
|
```
|
|
|
|
### Step 3: Run Tests (RED)
|
|
```bash
|
|
cargo test
|
|
```
|
|
|
|
### Step 4: Implement (GREEN)
|
|
```rust
|
|
pub fn process(input: &Input) -> Result<Output, Error> {
|
|
// Minimal implementation that handles both paths
|
|
validate(input)?;
|
|
Ok(Output { /* ... */ })
|
|
}
|
|
```
|
|
|
|
### Step 5: Check Coverage
|
|
```bash
|
|
cargo llvm-cov
|
|
cargo llvm-cov --fail-under-lines 80
|
|
```
|
|
|
|
## Rust Testing Commands
|
|
|
|
```bash
|
|
cargo test # Run all tests
|
|
cargo test -- --nocapture # Show println output
|
|
cargo test test_name # Run specific test
|
|
cargo test --no-fail-fast # Don't stop on first failure
|
|
cargo test --lib # Unit tests only
|
|
cargo test --test integration # Integration tests only
|
|
cargo test --doc # Doc tests only
|
|
cargo bench # Run benchmarks
|
|
```
|
|
|
|
## Test File Organization
|
|
|
|
```
|
|
src/
|
|
├── lib.rs # Library root
|
|
├── service.rs # Implementation
|
|
└── service/
|
|
└── tests.rs # Or inline #[cfg(test)] mod tests {}
|
|
tests/
|
|
└── integration.rs # Integration tests
|
|
benches/
|
|
└── benchmark.rs # Criterion benchmarks
|
|
```
|
|
|
|
---
|
|
|
|
**TIP**: Use `rstest` for parameterized tests and `proptest` for property-based testing.
|