{"manifest":{"name":"Test Generator","version":"1.0.0","description":"Analyzes source code and generates comprehensive unit tests. Auto-detects framework (Vitest/Jest/pytest/Go), handles mocking, covers edge cases.","tags":["testing","tdd","generator","devtools"],"standard":"agentskills.io","standard_version":"1.0","content_checksum":"f14ee6d8bb004bde21fa8a859aa9a743d3b0828da7f79db55bb55655bd99cf56","bundle_checksum":null,"metadata":{},"files":[]},"files":{"SKILL.md":"# Test Generator\n\n> **Purpose:** Analyze source code and generate comprehensive unit tests following the project's testing conventions.\n\n---\n\n## Invocation\n\n```\n/test-gen <file_path> [--framework vitest|jest|pytest|go]\n```\n\n---\n\n## Process\n\n### Step 1: Analyze the Target\n\nRead the source file and identify:\n- All exported functions/classes/methods\n- Input types and return types\n- Edge cases from conditional branches\n- Dependencies that need mocking\n- Existing test file (if any) to avoid duplicates\n\n### Step 2: Determine Testing Framework\n\nAuto-detect from project config:\n- `vitest.config.*` → Vitest\n- `jest.config.*` or `package.json[jest]` → Jest\n- `pytest.ini` or `pyproject.toml[tool.pytest]` → pytest\n- `*_test.go` files → Go testing\n\n### Step 3: Generate Test Cases\n\nFor each function, generate:\n\n1. **Happy path** — typical valid input → expected output\n2. **Edge cases** — empty input, zero, null/undefined, boundary values\n3. **Error paths** — invalid input → expected error/exception\n4. **Type variations** — different valid types if function accepts union types\n\n### Step 4: Structure the Test File\n\n```typescript\nimport { describe, it, expect, vi } from 'vitest'\nimport { targetFunction } from '../path/to/source'\n\ndescribe('targetFunction', () => {\n  it('returns expected result for valid input', () => {\n    expect(targetFunction('valid')).toBe('expected')\n  })\n\n  it('throws on null input', () => {\n    expect(() => targetFunction(null)).toThrow()\n  })\n\n  it('handles empty string', () => {\n    expect(targetFunction('')).toBe('')\n  })\n})\n```\n\n---\n\n## Mocking Strategy\n\n- **External APIs**: Always mock with `vi.mock()` or `jest.mock()`\n- **Database calls**: Mock the client/ORM, not the database\n- **File system**: Mock `fs` operations, never touch real files\n- **Time**: Use `vi.useFakeTimers()` for time-dependent logic\n- **Environment variables**: Set via `vi.stubEnv()` or test setup\n\n---\n\n## Rules\n\n- Match the project's existing test style (describe/it vs test, assertion style)\n- Place test files adjacent to source (`*.test.ts`) or in `tests/` mirror\n- Never generate snapshot tests unless explicitly asked\n- Aim for branch coverage, not just line coverage\n- Each test should be independent — no shared mutable state\n- Test names should describe behavior, not implementation\n\n## Playground\n\n<!DOCTYPE html><html><head><meta charset='utf-8'><style>*{box-sizing:border-box;margin:0;padding:0}body{background:#0d1117;color:#e6edf3;font-family:monospace;font-size:12px;height:100vh;display:flex;flex-direction:column;overflow:hidden}.header{background:#161b22;border-bottom:1px solid #30363d;padding:8px 14px;font-size:11px;color:#8b949e;display:flex;justify-content:space-between;align-items:center;flex-shrink:0}.title{color:#58a6ff;font-weight:bold;font-size:13px}.panels{display:flex;flex:1;overflow:hidden}.panel{flex:1;overflow:auto;padding:12px;border-right:1px solid #30363d}.panel:last-child{border-right:none}.label{font-size:10px;color:#8b949e;text-transform:uppercase;letter-spacing:.08em;margin-bottom:6px}pre{white-space:pre-wrap;word-break:break-word;line-height:1.5}</style></head><body><div class='header'><span class='title'>Test Generator</span><span>Example · SkillSlap</span></div><div class='panels'><div class='panel'><div class='label'>Input: Function spec</div><pre><span style='color:#8b949e'>Function: parseAmount(str)</span>\n<span style='color:#8b949e'>Language: TypeScript / Vitest</span>\n\n<span style='color:#8b949e'>Parses a currency string like</span>\n<span style='color:#8b949e'>\"$1,234.56\" → 1234.56 (number).</span>\n<span style='color:#8b949e'>Throws if input is not a valid</span>\n<span style='color:#8b949e'>currency string.</span></pre></div><div class='panel'><div class='label'>Output: Test suite</div><pre><span style='color:#58a6ff'>describe('parseAmount', () =&gt; {</span>\n<span style='color:#3fb950'>  it('parses USD with commas', () =&gt;</span>\n<span style='color:#8b949e'>    expect(parseAmount('$1,234.56'))</span>\n<span style='color:#8b949e'>      .toBe(1234.56))</span>\n\n<span style='color:#3fb950'>  it('parses zero', () =&gt;</span>\n<span style='color:#8b949e'>    expect(parseAmount('$0.00')).toBe(0))</span>\n\n<span style='color:#3fb950'>  it('throws on empty string', () =&gt;</span>\n<span style='color:#8b949e'>    expect(() =&gt; parseAmount(''))</span>\n<span style='color:#8b949e'>      .toThrow())</span>\n\n<span style='color:#3fb950'>  it('throws on plain text', () =&gt;</span>\n<span style='color:#8b949e'>    expect(() =&gt; parseAmount('hello'))</span>\n<span style='color:#8b949e'>      .toThrow())</span>\n<span style='color:#58a6ff'>})</span></pre></div></div></body></html>"}}