Caliber Testing
caliber-ai-org/ai-setup
Writes Vitest tests following project patterns: tests/ directories, vi.mock() for module mocking with vi.hoisted() for test-time factories, global LLM mock from src/test/setup.ts, environment…
Generates Vitest tests for every runnable code example on a JavaScript concept documentation page, following a four-phase extraction and conversion process.
$ npx skills add leonardomso/33-js-concepts --skill test-writer -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install leonardomso/33-js-concepts test-writer --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/leonardomso/33-js-concepts.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/test-writer .claude/skills/test-writer && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "test-writer" agent skill from https://github.com/leonardomso/33-js-concepts/tree/master/.claude/skills/test-writer into .claude/skills/test-writer/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-writer", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/leonardomso/33-js-concepts/tree/master/.claude/skills/test-writerType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add leonardomso/33-js-concepts --skill test-writer -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install leonardomso/33-js-concepts test-writer --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/leonardomso/33-js-concepts.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/test-writer .agents/skills/test-writer && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "test-writer" agent skill from https://github.com/leonardomso/33-js-concepts/tree/master/.claude/skills/test-writer into .agents/skills/test-writer/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-writer", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add leonardomso/33-js-concepts --skill test-writer -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install leonardomso/33-js-concepts test-writer --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/leonardomso/33-js-concepts.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/test-writer .cursor/skills/test-writer && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "test-writer" agent skill from https://github.com/leonardomso/33-js-concepts/tree/master/.claude/skills/test-writer into .cursor/skills/test-writer/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-writer", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/leonardomso/33-js-concepts.git --path .claude/skills/test-writer--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add leonardomso/33-js-concepts --skill test-writer -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install leonardomso/33-js-concepts test-writer --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/leonardomso/33-js-concepts.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/test-writer .gemini/skills/test-writer && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "test-writer" agent skill from https://github.com/leonardomso/33-js-concepts/tree/master/.claude/skills/test-writer into .gemini/skills/test-writer/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-writer", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install leonardomso/33-js-concepts test-writerInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add leonardomso/33-js-concepts --skill test-writer -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/leonardomso/33-js-concepts.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/test-writer .github/skills/test-writer && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "test-writer" agent skill from https://github.com/leonardomso/33-js-concepts/tree/master/.claude/skills/test-writer into .github/skills/test-writer/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-writer", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add leonardomso/33-js-concepts --skill test-writer -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install leonardomso/33-js-concepts test-writer --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/leonardomso/33-js-concepts.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/test-writer .opencode/skills/test-writer && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "test-writer" agent skill from https://github.com/leonardomso/33-js-concepts/tree/master/.claude/skills/test-writer into .opencode/skills/test-writer/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-writer", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
test-writerGenerates Vitest tests for every runnable code example on a JavaScript concept documentation page, following a four-phase extraction and conversion process.
The agent scans a concept page and sorts each code example into categories: testable examples with a logged or returned expected value, DOM-specific examples needing a separate test file, intentional error examples that should use toThrow, purely conceptual snippets to skip, and browser-only APIs to skip or mock. It then decides the test file path and name under a tests directory organized by concept group, using a .dom.test.js suffix for DOM tests.
Each testable example is converted into expect assertions with its expected output taken from console.log comments or documented behavior, grouped into describe blocks that mirror the page's own sections, and commented with a reference back to the source line. Special cases get specific handling: fake timers for timing-dependent code, captured output for side effects, and async/await for asynchronous examples. Tests import from vitest following the project's existing import conventions.
4 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 16d0d95. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
npmFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use npm, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Concept Page Test Writer loads about 5.5k tokens when it runs. Until then it costs about 42 tokens; SKILL.md has 743 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from leonardomso/33-js-concepts at commit 16d0d95, republished under its MIT licence (© leonardomso). 743 words, ~5,450 tokens.
.claude/skills/test-writer/SKILL.md (or your agent's skills folder).Use this skill to generate comprehensive Vitest tests for all code examples in a concept documentation page. Tests verify that code examples in the documentation are accurate and work as described.
Follow these four phases to create comprehensive tests for a concept page.
Scan the concept page for all code examples and categorize them:
| Category | Characteristics | Action |
|---|---|---|
| Testable | Has console.log with output comments, returns values | Write tests |
| DOM-specific | Uses document, window, DOM APIs, event handlers | Write DOM tests (separate file) |
| Error examples | Intentionally throws errors, demonstrates failures | Write tests with toThrow |
| Conceptual | ASCII diagrams, pseudo-code, incomplete snippets | Skip (document why) |
| Browser-only | Uses browser APIs not available in jsdom | Skip or mock |
tests/
├── fundamentals/ # Concepts 1-6
├── functions-execution/ # Concepts 7-8
├── web-platform/ # Concepts 9-10
├── object-oriented/ # Concepts 11-15
├── functional-programming/ # Concepts 16-19
├── async-javascript/ # Concepts 20-22
├── advanced-topics/ # Concepts 23-31
└── beyond/ # Extended concepts
└── {subcategory}/File naming:
{concept-name}.test.js{concept-name}.dom.test.jsFor each testable code example:
console.log comments or documented behavior)expect assertionsdescribe blocks matching documentation sections| Case | Solution |
|---|---|
| Browser-only APIs | Use jsdom environment or skip with note |
| Timing-dependent code | Use vi.useFakeTimers() or test the logic, not timing |
| Side effects | Capture output or test mutations |
| Intentional errors | Use expect(() => {...}).toThrow() |
| Async code | Use async/await with proper assertions |
import { describe, it, expect } from 'vitest'For DOM tests or tests needing mocks:
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'/**
* @vitest-environment jsdom
*/
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'Match the structure of the documentation:
describe('Concept Name', () => {
describe('Section from Documentation', () => {
describe('Subsection if needed', () => {
it('should [specific behavior]', () => {
// Test
})
})
})
})// Good
it('should return "object" for typeof null', () => {})
it('should throw TypeError when accessing property of undefined', () => {})
it('should resolve promises in order they were created', () => {})
// Bad
it('test typeof', () => {})
it('works correctly', () => {})
it('null test', () => {})Always reference the documentation source:
// ============================================================
// SECTION NAME FROM DOCUMENTATION
// From {concept}.mdx lines XX-YY
// ============================================================
describe('Section Name', () => {
// From lines 45-52: Basic typeof examples
it('should return correct type strings', () => {
// Test
})
})Documentation:
console.log(typeof "hello") // "string"
console.log(typeof 42) // "number"Test:
// From lines XX-YY: typeof examples
it('should return correct type for primitives', () => {
expect(typeof "hello").toBe("string")
expect(typeof 42).toBe("number")
})Documentation:
let a = "hello"
let b = "hello"
console.log(a === b) // true
let obj1 = { x: 1 }
let obj2 = { x: 1 }
console.log(obj1 === obj2) // falseTest:
// From lines XX-YY: Primitive vs object comparison
it('should compare primitives by value', () => {
let a = "hello"
let b = "hello"
expect(a === b).toBe(true)
})
it('should compare objects by reference', () => {
let obj1 = { x: 1 }
let obj2 = { x: 1 }
expect(obj1 === obj2).toBe(false)
})Documentation:
function greet(name) {
return "Hello, " + name + "!"
}
console.log(greet("Alice")) // "Hello, Alice!"Test:
// From lines XX-YY: greet function example
it('should return greeting with name', () => {
function greet(name) {
return "Hello, " + name + "!"
}
expect(greet("Alice")).toBe("Hello, Alice!")
})Documentation:
// This throws an error!
const obj = null
console.log(obj.property) // TypeError: Cannot read property of nullTest:
// From lines XX-YY: Accessing property of null
it('should throw TypeError when accessing property of null', () => {
const obj = null
expect(() => {
obj.property
}).toThrow(TypeError)
})Documentation:
function divide(a, b) {
if (b === 0) throw new Error("Cannot divide by zero")
return a / b
}Test:
// From lines XX-YY: divide function with error
it('should throw error when dividing by zero', () => {
function divide(a, b) {
if (b === 0) throw new Error("Cannot divide by zero")
return a / b
}
expect(() => divide(10, 0)).toThrow("Cannot divide by zero")
expect(divide(10, 2)).toBe(5)
})Documentation:
async function fetchUser(id) {
const response = await fetch(`/api/users/${id}`)
return response.json()
}Test:
// From lines XX-YY: async fetchUser function
it('should fetch user data asynchronously', async () => {
// Mock fetch for testing
global.fetch = vi.fn(() =>
Promise.resolve({
json: () => Promise.resolve({ id: 1, name: 'Alice' })
})
)
async function fetchUser(id) {
const response = await fetch(`/api/users/${id}`)
return response.json()
}
const user = await fetchUser(1)
expect(user).toEqual({ id: 1, name: 'Alice' })
})Documentation:
const promise = new Promise((resolve) => {
resolve("done")
})
promise.then(result => console.log(result)) // "done"Test:
// From lines XX-YY: Basic Promise resolution
it('should resolve with correct value', async () => {
const promise = new Promise((resolve) => {
resolve("done")
})
await expect(promise).resolves.toBe("done")
})Documentation:
const promise = new Promise((resolve, reject) => {
reject(new Error("Something went wrong"))
})Test:
// From lines XX-YY: Promise rejection
it('should reject with error', async () => {
const promise = new Promise((resolve, reject) => {
reject(new Error("Something went wrong"))
})
await expect(promise).rejects.toThrow("Something went wrong")
})Documentation:
console.log(0.1 + 0.2) // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3) // falseTest:
// From lines XX-YY: Floating point precision
it('should demonstrate floating point imprecision', () => {
expect(0.1 + 0.2).not.toBe(0.3)
expect(0.1 + 0.2).toBeCloseTo(0.3)
expect(0.1 + 0.2 === 0.3).toBe(false)
})Documentation:
const numbers = [1, 2, 3, 4, 5]
const doubled = numbers.map(n => n * 2)
console.log(doubled) // [2, 4, 6, 8, 10]Test:
// From lines XX-YY: Array map example
it('should double all numbers in array', () => {
const numbers = [1, 2, 3, 4, 5]
const doubled = numbers.map(n => n * 2)
expect(doubled).toEqual([2, 4, 6, 8, 10])
expect(numbers).toEqual([1, 2, 3, 4, 5]) // Original unchanged
})Documentation:
const obj = { a: 1 }
obj.b = 2
console.log(obj) // { a: 1, b: 2 }Test:
// From lines XX-YY: Object mutation
it('should allow adding properties to objects', () => {
const obj = { a: 1 }
obj.b = 2
expect(obj).toEqual({ a: 1, b: 2 })
})Documentation:
function counter() {
let count = 0
return function() {
count++
return count
}
}
const increment = counter()
console.log(increment()) // 1
console.log(increment()) // 2
console.log(increment()) // 3Test:
// From lines XX-YY: Closure counter example
it('should maintain state across calls via closure', () => {
function counter() {
let count = 0
return function() {
count++
return count
}
}
const increment = counter()
expect(increment()).toBe(1)
expect(increment()).toBe(2)
expect(increment()).toBe(3)
})
it('should create independent counters', () => {
function counter() {
let count = 0
return function() {
count++
return count
}
}
const counter1 = counter()
const counter2 = counter()
expect(counter1()).toBe(1)
expect(counter1()).toBe(2)
expect(counter2()).toBe(1) // Independent
})Documentation:
const button = document.getElementById('myButton')
button.addEventListener('click', function(event) {
console.log('Button clicked!')
console.log(event.type) // "click"
})Test (in .dom.test.js file):
/**
* @vitest-environment jsdom
*/
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
describe('DOM Event Handlers', () => {
let button
beforeEach(() => {
button = document.createElement('button')
button.id = 'myButton'
document.body.appendChild(button)
})
afterEach(() => {
document.body.innerHTML = ''
})
// From lines XX-YY: Button click event
it('should fire click event handler', () => {
const output = []
button.addEventListener('click', function(event) {
output.push('Button clicked!')
output.push(event.type)
})
button.click()
expect(output).toEqual(['Button clicked!', 'click'])
})
})Documentation:
const div = document.createElement('div')
div.textContent = 'Hello'
div.classList.add('greeting')
document.body.appendChild(div)Test:
// From lines XX-YY: Creating and appending elements
it('should create element with text and class', () => {
const div = document.createElement('div')
div.textContent = 'Hello'
div.classList.add('greeting')
document.body.appendChild(div)
const element = document.querySelector('.greeting')
expect(element).not.toBeNull()
expect(element.textContent).toBe('Hello')
expect(element.classList.contains('greeting')).toBe(true)
})Documentation:
console.log('First')
setTimeout(() => console.log('Second'), 0)
console.log('Third')
// Output: First, Third, SecondTest:
// From lines XX-YY: setTimeout execution order
it('should execute setTimeout callback after synchronous code', async () => {
const output = []
output.push('First')
setTimeout(() => output.push('Second'), 0)
output.push('Third')
// Wait for setTimeout to execute
await new Promise(resolve => setTimeout(resolve, 10))
expect(output).toEqual(['First', 'Third', 'Second'])
})Documentation:
// In strict mode, this throws
"use strict"
x = 10 // ReferenceError: x is not definedTest:
// From lines XX-YY: Strict mode variable declaration
it('should throw ReferenceError in strict mode for undeclared variables', () => {
// Vitest runs in strict mode by default
expect(() => {
// Using eval to test strict mode behavior
"use strict"
eval('undeclaredVar = 10')
}).toThrow()
})import { describe, it, expect } from 'vitest'
describe('[Concept Name]', () => {
// ============================================================
// [FIRST SECTION NAME FROM DOCUMENTATION]
// From [concept].mdx lines XX-YY
// ============================================================
describe('[First Section]', () => {
// From lines XX-YY: [Brief description of example]
it('should [expected behavior]', () => {
// Code from documentation
expect(result).toBe(expected)
})
// From lines XX-YY: [Brief description of next example]
it('should [another expected behavior]', () => {
// Code from documentation
expect(result).toEqual(expected)
})
})
// ============================================================
// [SECOND SECTION NAME FROM DOCUMENTATION]
// From [concept].mdx lines XX-YY
// ============================================================
describe('[Second Section]', () => {
// From lines XX-YY: [Description]
it('should [behavior]', () => {
// Test
})
})
// ============================================================
// EDGE CASES AND COMMON MISTAKES
// From [concept].mdx lines XX-YY
// ============================================================
describe('Edge Cases', () => {
// From lines XX-YY: [Edge case description]
it('should handle [edge case]', () => {
// Test
})
})
describe('Common Mistakes', () => {
// From lines XX-YY: Wrong way example
it('should demonstrate the incorrect behavior', () => {
// Test showing why the "wrong" way fails
})
// From lines XX-YY: Correct way example
it('should demonstrate the correct behavior', () => {
// Test showing the right approach
})
})
})/**
* @vitest-environment jsdom
*/
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
// ============================================================
// DOM EXAMPLES FROM [CONCEPT NAME]
// From [concept].mdx lines XX-YY
// ============================================================
describe('[Concept Name] - DOM', () => {
// Shared setup
let container
beforeEach(() => {
// Create a fresh container for each test
container = document.createElement('div')
container.id = 'test-container'
document.body.appendChild(container)
})
afterEach(() => {
// Clean up after each test
document.body.innerHTML = ''
vi.restoreAllMocks()
})
// ============================================================
// [SECTION NAME]
// From lines XX-YY
// ============================================================
describe('[Section Name]', () => {
// From lines XX-YY: [Example description]
it('should [expected DOM behavior]', () => {
// Setup
const element = document.createElement('div')
container.appendChild(element)
// Action
element.textContent = 'Hello'
// Assert
expect(element.textContent).toBe('Hello')
})
})
// ============================================================
// EVENT HANDLING
// From lines XX-YY
// ============================================================
describe('Event Handling', () => {
// From lines XX-YY: Click event example
it('should handle click events', () => {
const button = document.createElement('button')
container.appendChild(button)
let clicked = false
button.addEventListener('click', () => {
clicked = true
})
button.click()
expect(clicked).toBe(true)
})
})
})# Run all tests
npm test
# Run tests for specific concept
npm test -- tests/fundamentals/primitive-types/
# Run tests for specific file
npm test -- tests/fundamentals/primitive-types/primitive-types.test.js
# Run DOM tests only
npm test -- tests/fundamentals/primitive-types/primitive-types.dom.test.js
# Run with watch mode
npm run test:watch
# Run with coverage
npm run test:coverage
# Run with verbose output
npm test -- --reporter=verbose.dom.test.js filetoThrow patterntoBeCloseTotoEqual (not toBe){concept}.test.js)npm test -- tests/{category}/{concept}/Use this template to document test coverage for a concept page.
# Test Coverage Report: [Concept Name]
**Concept Page:** `/docs/concepts/[slug].mdx`
**Test File:** `/tests/{category}/{concept}/{concept}.test.js`
**DOM Test File:** `/tests/{category}/{concept}/{concept}.dom.test.js` (if applicable)
**Date:** YYYY-MM-DD
**Author:** [Name/Claude]
## Summary
| Metric | Count |
|--------|-------|
| Total Code Examples in Doc | XX |
| Testable Examples | XX |
| Tests Written | XX |
| DOM Tests Written | XX |
| Skipped (with reason) | XX |
## Tests by Section
| Section | Line Range | Examples | Tests | Status |
|---------|------------|----------|-------|--------|
| [Section 1] | XX-YY | X | X | ✅ |
| [Section 2] | XX-YY | X | X | ✅ |
| [Section 3] | XX-YY | X | X | ⚠️ (1 skipped) |
## Skipped Examples
| Line | Example Description | Reason |
|------|---------------------|--------|
| XX | ASCII diagram of call stack | Conceptual, not executable |
| YY | Browser fetch example | Requires network, mocked instead |
## Test Execution
```bash
npm test -- tests/{category}/{concept}/Result: ✅ XX passing | ❌ X failing | ⏭️ X skipped
[Any special considerations, mock requirements, or issues encountered]
---
## Common Issues and Solutions
### Issue: Test passes but shouldn't
**Problem:** Test expectations don't match documentation output
**Solution:** Double-check the expected value matches the `console.log` comment exactly
```javascript
// Documentation says: console.log(result) // [1, 2, 3]
// Make sure test uses:
expect(result).toEqual([1, 2, 3]) // NOT toBe for arraysProblem: Async test never resolves
Solution: Ensure all promises are awaited and async function is marked
// Bad
it('should fetch data', () => {
const data = fetchData() // Missing await!
expect(data).toBeDefined()
})
// Good
it('should fetch data', async () => {
const data = await fetchData()
expect(data).toBeDefined()
})Problem: Missing jsdom environment
Solution: Add environment directive at top of file
/**
* @vitest-environment jsdom
*/Problem: Tests affect each other
Solution: Use beforeEach/afterEach for cleanup
afterEach(() => {
document.body.innerHTML = ''
vi.restoreAllMocks()
})When writing tests for a concept page:
Remember: Tests serve two purposes:
Every testable code example in the documentation should have a corresponding test. If an example can't be tested, document why.
© leonardomso, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .claude/skills/test-writer of leonardomso/33-js-concepts.
Open the folder on GitHubat commit 16d0d95
Concept Page Test Writer next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Concept Page Test Writer this skillleonardomso/33-js-concepts | 67k | — | ~5.5k | Automated safety check: Pass | MIT | |
| Caliber Testingcaliber-ai-org/ai-setup | 1.3k | — | ~3.2k | Automated safety check: Pass | MIT | |
| MoAI TDD Workflowmodu-ai/moai-adk | 1.2k | — | ~3.1k | Automated safety check: Pass | Apache-2.0 | |
| Test Coveragescott-fryxell/brayness | 124 | — | ~1.6k | Automated safety check: Pass | MIT | |
| Verify Changesh0x91b/dev-3.0 | 307 | — | ~1.7k | Automated safety check: Pass | Apache-2.0 | |
| Gen TestArtexis10/endstate-gui | 116 | — | ~661 | Automated safety check: Pass | Apache-2.0 |
caliber-ai-org/ai-setup
Writes Vitest tests following project patterns: tests/ directories, vi.mock() for module mocking with vi.hoisted() for test-time factories, global LLM mock from src/test/setup.ts, environment…
modu-ai/moai-adk
Drives test-first development through the RED, GREEN, REFACTOR cycle, with a config switch that selects between TDD and a DDD workflow for existing code.
scott-fryxell/brayness
Write Vitest specs for Vue 3 JavaScript (Vite Plus, happy-dom, @vue/test-utils) and analyze V8 coverage + Fallow health to prioritize test-first refactors.
h0x91b/dev-3.0
How to test and verify work in the dev-3.0 repo — which vitest config covers what, how to write a test that fits the house style, mocking Electrobun RPC and i18n providers, what coverage is actually…
Artexis10/endstate-gui
Generate unit tests following project conventions. An agent skill from Artexis10/endstate-gui.
cin12211/orca-q
OrcaQ-specific testing guide. An agent skill from cin12211/orca-q.
leonardomso/33-js-concepts
Verifies the technical accuracy of JavaScript concept pages by checking code examples, MDN and ECMAScript claims and external links through a five-phase method.
leonardomso/33-js-concepts
Orchestrates five skills to produce a complete JavaScript concept documentation page, from resource curation through writing, tests, fact-checking and SEO.
leonardomso/33-js-concepts
Finds, vets, writes up and maintains external articles, videos and courses for JavaScript concept pages, including audits for broken and outdated links.
leonardomso/33-js-concepts
Runs a five-step SEO audit on JavaScript concept pages: keyword clusters, on-page checks, featured snippets, internal links and a written report.
leonardomso/33-js-concepts
Writes or reviews documentation pages for the 33 JavaScript Concepts project, following its structure, a beginner-friendly voice and rules against AI-sounding language.
Works with
Categories
Generates Vitest tests for every runnable code example on a JavaScript concept documentation page, following a four-phase extraction and conversion process. The agent scans a concept page and sorts each code example into categories: testable examples with a logged or returned expected value, DOM-specific examples needing a separate test file, intentional error examples that should use toThrow, purely conceptual snippets to skip, and browser-only APIs to skip or mock.js suffix for DOM tests.
Concept Page Test Writer fits situations like: writing tests for a newly added concept documentation page; adding tests after new code examples are added to an existing page; verifying that updated code examples still behave as documented.
Run `npx skills add leonardomso/33-js-concepts --skill test-writer -a claude-code`. Or copy the skill folder (.claude/skills/test-writer in leonardomso/33-js-concepts) into .claude/skills/test-writer in your project. Claude Code loads it when a task matches its description.
Run `npx skills add leonardomso/33-js-concepts --skill test-writer -a codex`. Or copy the skill folder (.claude/skills/test-writer in leonardomso/33-js-concepts) into .agents/skills/test-writer in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add leonardomso/33-js-concepts --skill test-writer -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/test-writer, .gemini/skills/test-writer, .github/skills/test-writer and .opencode/skills/test-writer in your project.
Going by SKILL.md and its folder, Concept Page Test Writer needs the command-line tools its instructions call (npm). Our summary lists: Vitest configured in the project, with jsdom for DOM-specific tests.
SKILL.md contains no URLs. Its commands use npm, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Concept Page Test Writer is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 5.5k tokens (SKILL.md is roughly 22k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Concept Page Test Writer: Caliber Testing (caliber-ai-org/ai-setup, 1.3k stars), MoAI TDD Workflow (modu-ai/moai-adk, 1.2k stars), Test Coverage (scott-fryxell/brayness, 124 stars) and Verify Changes (h0x91b/dev-3.0, 307 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
leonardomso (a GitHub user) maintains it in leonardomso/33-js-concepts, which has 66,532 GitHub stars. The repository holds 6 skills in this directory. The repository was last updated on September 10, 2026.
Source: leonardomso/33-js-concepts on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.