# TDD Guide Agent

> **Purpose:** Enforce Test-Driven Development by ensuring tests are written FIRST, verified to fail, then implementation follows.

---

## When to Use

This agent is automatically invoked when:
- New feature implementation begins
- Bug fixes are being made
- The `/tdd` command is used

You can also invoke it manually with `/tdd [feature-description]`.

---

## Core Philosophy: Red-Green-Refactor

### 1. RED: Write a Failing Test
Write the test before any implementation code exists.

```python
# tests/test_calculator.py
def test_add_returns_sum_of_two_numbers():
    calc = Calculator()
    result = calc.add(2, 3)
    assert result == 5
```

**Verify it fails:**
```bash
$ pytest tests/test_calculator.py
FAILED - NameError: name 'Calculator' is not defined
```

### 2. GREEN: Write Minimal Code to Pass
Only write enough code to make the test pass.

```python
# src/calculator.py
class Calculator:
    def add(self, a: int, b: int) -> int:
        return a + b
```

**Verify it passes:**
```bash
$ pytest tests/test_calculator.py
PASSED
```

### 3. REFACTOR: Improve Without Breaking
Clean up the code while keeping tests green.

---

## TDD Workflow

```
┌─────────────────────────────────────────────────┐
│                 TDD CYCLE                       │
│                                                 │
│    ┌───────┐                                   │
│    │  RED  │ ← Write failing test              │
│    └───┬───┘                                   │
│        │                                       │
│        ▼                                       │
│    ┌───────┐                                   │
│    │ GREEN │ ← Write minimal code to pass      │
│    └───┬───┘                                   │
│        │                                       │
│        ▼                                       │
│    ┌──────────┐                                │
│    │ REFACTOR │ ← Improve code, keep tests     │
│    └────┬─────┘    passing                     │
│         │                                      │
│         └──────────────────────────────────┐   │
│                                            │   │
│    Repeat for each requirement ────────────┘   │
└─────────────────────────────────────────────────┘
```

---

## Coverage Requirements

### Target: Aim for >80% Coverage

```bash
# Python
pytest --cov=src --cov-report=term-missing tests/

# TypeScript
jest --coverage
```

### Coverage Report Interpretation
```
Name                    Stmts   Miss  Cover   Missing
-----------------------------------------------------
src/calculator.py          10      2    80%   15-16
src/validator.py           25      3    88%   42, 55, 67
-----------------------------------------------------
TOTAL                      35      5    86%
```

---

## Test Types

### Unit Tests
```python
# Test isolated units with mocked dependencies
def test_user_service_creates_user(mock_repository):
    service = UserService(repository=mock_repository)
    user = service.create("test@example.com")
    assert user.email == "test@example.com"
    mock_repository.save.assert_called_once()
```

### Integration Tests
```python
# Test multiple components together
@pytest.fixture
def test_db():
    db = create_test_database()
    yield db
    db.cleanup()

def test_user_registration_flow(test_db):
    service = UserService(repository=SqlRepository(test_db))
    user = service.create("test@example.com")
    assert service.get(user.id) == user
```

### E2E Tests
See: `e2e-runner.md` agent documentation

---

## Python TDD Patterns

### Pytest Fixtures
```python
@pytest.fixture
def mock_api():
    with patch("src.external.api.call") as mock:
        mock.return_value = {"status": "ok"}
        yield mock

def test_service_calls_api(mock_api):
    service = Service()
    result = service.process()
    mock_api.assert_called_once()
```

### Parametrized Tests
```python
@pytest.mark.parametrize("input,expected", [
    (2, 4),
    (3, 9),
    (0, 0),
    (-2, 4),
])
def test_square(input, expected):
    assert square(input) == expected
```

---

## TypeScript/JavaScript TDD Patterns

### Jest/Vitest
```typescript
describe('Calculator', () => {
  describe('add', () => {
    it('returns sum of two positive numbers', () => {
      const calc = new Calculator();
      expect(calc.add(2, 3)).toBe(5);
    });

    it('handles negative numbers', () => {
      const calc = new Calculator();
      expect(calc.add(-2, 3)).toBe(1);
    });
  });
});
```

### React Testing Library
```typescript
describe('LoginForm', () => {
  it('submits with valid credentials', async () => {
    const onSubmit = vi.fn();
    render(<LoginForm onSubmit={onSubmit} />);

    await userEvent.type(screen.getByLabelText('Email'), 'test@example.com');
    await userEvent.type(screen.getByLabelText('Password'), 'password');
    await userEvent.click(screen.getByRole('button', { name: 'Login' }));

    expect(onSubmit).toHaveBeenCalledWith({
      email: 'test@example.com',
      password: 'password',
    });
  });
});
```

---

## Bug Fix TDD

For bug fixes, write a test that reproduces the bug first:

```python
def test_bug_123_login_fails_with_special_chars():
    """Regression test for issue #123.

    Users with special characters in password couldn't login.
    """
    # This test should FAIL before the fix
    service = AuthService()
    result = service.login("user@example.com", "pass!@#$%")
    assert result.success  # Failed before fix
```

---

## Integration with Other Agents

- **Planner:** All plans include TDD steps
- **Build Error Resolver:** Fixes test failures
- **Code Reviewer:** Verifies test coverage
- **E2E Runner:** Extended test coverage

---

## Commands

| Command | Description |
|---------|-------------|
| `/tdd [feature]` | Start TDD workflow for feature |
| `/tdd verify` | Verify current test is failing |
| `/tdd coverage` | Check coverage report |

---

## Best Practices

1. **Test First, Always** - No exceptions. Write the test first.
2. **One Assertion Focus** - Each test verifies one behavior
3. **Descriptive Names** - `test_<what>_<when>_<expected>`
4. **Fast Tests** - Unit tests should run in milliseconds
5. **Isolated Tests** - Tests shouldn't depend on each other
6. **Meaningful Coverage** - Coverage of meaningful paths, not just lines

---

## Anti-Patterns to Avoid

| Anti-Pattern | Why It's Bad | Better Approach |
|--------------|--------------|-----------------|
| Test after code | Tests shaped by implementation | Write test first |
| Testing implementation | Brittle tests | Test behavior |
| Too many mocks | Tests don't reflect reality | Integration tests |
| Ignoring failures | Technical debt | Fix immediately |
| Skipping refactor | Messy code | Always refactor |
