- wursor-precheck: router skill, entry point for non-trivial tasks - wursor-principles: 21 engineering principles adapted for Wursor - wursor-tdd, wursor-bug-fix, wursor-feature, wursor-investigation, wursor-review, wursor-decision-log: playbook skills - AGENTS.md: repo guide wiring the skill routing table - Fix: double-quote YAML frontmatter descriptions (colon-space in plain scalars broke Zed's skill loader)
103 lines
3.3 KiB
Markdown
103 lines
3.3 KiB
Markdown
---
|
|
name: wursor-tdd
|
|
description: "Write a failing test first, then implement, then verify. For any code change in api/ (Node.js + TypeScript), web/ (React + TypeScript), plugin/ (PHP), or infrastructure/ (Docker) that has a measurable test path. Adapted from pstack's /tdd skill."
|
|
---
|
|
|
|
# Wursor TDD
|
|
|
|
Write the failing test first, then the implementation, then verify the test passes. This is the default workflow for any code change in this repository.
|
|
|
|
## When to use
|
|
|
|
Use this skill when:
|
|
- Fixing a bug with a measurable test path
|
|
- Building a new feature with unit-testable boundaries
|
|
- Adding a helper, utility, or pure function
|
|
- Refactoring where behavior should be preserved
|
|
- The task tells you the test path is cheap or fast
|
|
|
|
Do **not** use this for: configuration-only changes, non-code documentation, or infrastructure scripts whose test would be a full e2e run.
|
|
|
|
## Playbook
|
|
|
|
### Step 1 — Understand what's being tested
|
|
|
|
Read the relevant module. Understand the function signature, the inputs, the outputs, and the side effects. For `api/` modules, check the existing `__tests__/` or `tests/` directory for patterns.
|
|
|
|
### Step 2 — Write the failing test
|
|
|
|
One test per behavior. One assertion per test.
|
|
|
|
```typescript
|
|
// Example for api/ modules
|
|
import { describe, it, expect } from 'vitest';
|
|
|
|
describe('SandboxMirror', () => {
|
|
it('fetches site info from the plugin API', async () => {
|
|
const mirror = new SandboxMirror('https://example.com', 'token');
|
|
const info = await mirror.fetchSiteInfo();
|
|
expect(info.theme).toBeDefined();
|
|
expect(info.plugins).toBeInstanceOf(Array);
|
|
});
|
|
});
|
|
```
|
|
|
|
```php
|
|
// Example for plugin/ modules
|
|
class WursorAuthTest extends WP_UnitTestCase {
|
|
public function test_generates_six_character_code() {
|
|
$auth = new Wursor_Auth();
|
|
$code = $auth->generate_pairing_code();
|
|
$this->assertEquals(6, strlen($code));
|
|
$this->assertMatchesRegularExpression('/^[A-Z0-9]{6}$/', $code);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Step 3 — Run the test. It must fail.
|
|
|
|
Do not proceed until the test runner confirms the test fails. A test that passes before implementation is a test that tests nothing.
|
|
|
|
```bash
|
|
# api/ — vitest
|
|
pnpm test -- --grep "SandboxMirror"
|
|
# plugin/ — phpunit
|
|
phpunit --filter test_generates_six_character_code
|
|
```
|
|
|
|
### Step 4 — Implement the minimum code to pass
|
|
|
|
Write the implementation. No more than what's needed to make the test pass.
|
|
|
|
### Step 5 — Run the test. It must pass.
|
|
|
|
Same command as step 3. The test must pass.
|
|
|
|
### Step 6 — Refactor
|
|
|
|
Clean up the implementation and the test. Remove debug code, rename unclear variables, extract helpers if they exist. The test should still pass.
|
|
|
|
### Step 7 — Verify with the broader test suite
|
|
|
|
Run the relevant test suite to make sure nothing is broken:
|
|
|
|
```bash
|
|
# api/
|
|
pnpm test:api
|
|
# web/
|
|
pnpm test:web
|
|
# plugin/
|
|
phpunit
|
|
```
|
|
|
|
### Step 8 — Report
|
|
|
|
State what was tested, what the test proved, and what the broader suite showed.
|
|
|
|
## Hard rules
|
|
|
|
- No implementation code is written without a failing test.
|
|
- One test per behavior. One assertion per test.
|
|
- Tests are deterministic: no network calls in unit tests. Mock the Grok API, the plugin API, Docker, and the filesystem.
|
|
- The test must fail before the implementation. If it passes, the test is wrong.
|
|
- Coverage floor: api/ and web/ ≥ 90% line coverage. plugin/ ≥ 80%. |