Back to skills
SkillHub ClubWrite Technical DocsFull StackTech WriterTesting

jest-testing

Use when writing Jest tests - covers testing patterns for interpreters, parsers, and async code

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3
Hot score
80
Updated
March 19, 2026
Overall rating
C2.1
Composite score
2.1
Best-practice grade
N/A

Install command

npx @skill-hub/cli install mcclowes-lea-jest-testing

Repository

mcclowes/lea

Skill path: .claude/skills/jest-testing

Use when writing Jest tests - covers testing patterns for interpreters, parsers, and async code

Open repository

Best for

Primary workflow: Write Technical Docs.

Technical facets: Full Stack, Tech Writer, Testing.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: mcclowes.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install jest-testing into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/mcclowes/lea before adding jest-testing to shared team environments
  • Use jest-testing for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: jest-testing
# prettier-ignore
description: Use when writing Jest tests - covers testing patterns for interpreters, parsers, and async code
---

# Jest Testing Best Practices

## Quick Start

```typescript
import { run } from "../src/api";

describe("interpreter", () => {
  it("evaluates arithmetic expressions", () => {
    expect(run("2 + 3")).toBe(5);
  });

  it("handles errors gracefully", () => {
    expect(() => run("undefined_var")).toThrow(/undefined/i);
  });
});
```

## Core Principles

- **Arrange-Act-Assert**: Structure tests clearly
- **One assertion focus**: Test one behavior per test
- **Descriptive names**: Use "should" or behavior-based naming
- **Isolation**: Tests should not depend on each other

## Testing Patterns

### Interpreter Tests

```typescript
describe("builtins", () => {
  describe("map", () => {
    it("transforms each element", () => {
      const code = `[1, 2, 3] /> map((x) -> x * 2)`;
      expect(run(code)).toEqual([2, 4, 6]);
    });

    it("passes index as second argument", () => {
      const code = `["a", "b"] /> map((x, i) -> i)`;
      expect(run(code)).toEqual([0, 1]);
    });
  });
});
```

### Parser Tests

```typescript
describe("parser", () => {
  it("parses pipe expressions", () => {
    const ast = parse("x /> fn");
    expect(ast.body[0]).toMatchObject({
      type: "ExprStmt",
      expression: {
        type: "PipeExpr",
        left: { type: "Identifier", name: "x" },
        right: { type: "Identifier", name: "fn" }
      }
    });
  });
});
```

### Async Tests

```typescript
it("resolves async operations", async () => {
  const result = await run(`
    let fetch = () -> delay(10) /> then(() -> "done") #async
    await fetch()
  `);
  expect(result).toBe("done");
});
```

### Snapshot Tests

```typescript
it("formats code consistently", () => {
  const formatted = format("let x=1+2");
  expect(formatted).toMatchSnapshot();
});
```

## Configuration

```javascript
// jest.config.js
module.exports = {
  preset: "ts-jest",
  testEnvironment: "node",
  testMatch: ["**/__tests__/**/*.test.ts"],
  collectCoverageFrom: ["src/**/*.ts", "!src/**/*.d.ts"],
};
```

## Reference Files

- [references/mocking.md](references/mocking.md) - Mocking strategies
- [references/async-testing.md](references/async-testing.md) - Async test patterns


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### references/mocking.md

```markdown
# Mocking Strategies

## Basic Mocking

```typescript
// Mock a module
jest.mock("../src/utils");

// Mock with implementation
jest.mock("../src/api", () => ({
  fetchData: jest.fn().mockResolvedValue({ data: "test" }),
}));
```

## Mocking Functions

```typescript
// Create a mock function
const mockFn = jest.fn();

// With return value
const mockAdd = jest.fn().mockReturnValue(5);

// With implementation
const mockCalculate = jest.fn((a, b) => a + b);

// Different returns per call
const mockSequence = jest.fn()
  .mockReturnValueOnce(1)
  .mockReturnValueOnce(2)
  .mockReturnValue(3);
```

## Mocking Builtins for Interpreter

```typescript
describe("print builtin", () => {
  let consoleSpy: jest.SpyInstance;

  beforeEach(() => {
    consoleSpy = jest.spyOn(console, "log").mockImplementation();
  });

  afterEach(() => {
    consoleSpy.mockRestore();
  });

  it("prints to console", () => {
    run('"hello" /> print');
    expect(consoleSpy).toHaveBeenCalledWith("hello");
  });
});
```

## Mocking Timers

```typescript
describe("delay builtin", () => {
  beforeEach(() => {
    jest.useFakeTimers();
  });

  afterEach(() => {
    jest.useRealTimers();
  });

  it("delays execution", async () => {
    const promise = run("delay(1000)");
    jest.advanceTimersByTime(1000);
    await expect(promise).resolves.toBeUndefined();
  });
});
```

## Mocking Modules

```typescript
// __mocks__/fs.ts
export const readFileSync = jest.fn();
export const writeFileSync = jest.fn();

// In test
jest.mock("fs");
import { readFileSync } from "fs";

it("reads file", () => {
  (readFileSync as jest.Mock).mockReturnValue("content");
  // ...
});
```

## Spying on Methods

```typescript
const interpreter = new Interpreter();
const evaluateSpy = jest.spyOn(interpreter, "evaluate");

interpreter.run("2 + 3");

expect(evaluateSpy).toHaveBeenCalled();
expect(evaluateSpy).toHaveBeenCalledWith(expect.objectContaining({
  type: "BinaryExpr",
}));
```

## Clearing and Resetting

```typescript
beforeEach(() => {
  jest.clearAllMocks();  // Clear call history
  // or
  jest.resetAllMocks();  // Clear history + reset implementations
  // or
  jest.restoreAllMocks(); // Restore original implementations
});
```

```

### references/async-testing.md

```markdown
# Async Test Patterns

## Basic Async Tests

```typescript
// Using async/await
it("resolves async value", async () => {
  const result = await run("await delay(10)");
  expect(result).toBeDefined();
});

// Using promises
it("resolves async value", () => {
  return run("await delay(10)").then((result) => {
    expect(result).toBeDefined();
  });
});
```

## Testing Rejections

```typescript
// Expect rejection
it("rejects on error", async () => {
  await expect(run("await reject()")).rejects.toThrow("error");
});

// Using try/catch
it("catches error", async () => {
  try {
    await run("await reject()");
    fail("Expected error");
  } catch (error) {
    expect(error.message).toContain("error");
  }
});
```

## Testing Parallel Operations

```typescript
it("runs operations in parallel", async () => {
  const start = Date.now();

  await run(`
    let a = delay(100) #async
    let b = delay(100) #async
    [await a, await b]
  `);

  const elapsed = Date.now() - start;
  expect(elapsed).toBeLessThan(150); // Should be ~100ms, not 200ms
});
```

## Fake Timers with Async

```typescript
it("handles delayed operations", async () => {
  jest.useFakeTimers();

  const promise = run("await delay(5000)");

  // Fast-forward time
  jest.advanceTimersByTime(5000);

  // Wait for promise to resolve
  await promise;

  jest.useRealTimers();
});
```

## Testing Event Streams

```typescript
it("collects events", async () => {
  const events: string[] = [];

  const result = await run(`
    [1, 2, 3]
      /> map((x) -> { emit("item"); x })
  `, {
    onEmit: (event) => events.push(event),
  });

  expect(events).toEqual(["item", "item", "item"]);
});
```

## Timeout Handling

```typescript
// Set custom timeout for slow tests
it("handles long operation", async () => {
  const result = await run("heavyComputation()");
  expect(result).toBeDefined();
}, 10000); // 10 second timeout

// Global timeout
jest.setTimeout(10000);
```

## Concurrent Tests

```typescript
describe("concurrent tests", () => {
  it.concurrent("test 1", async () => {
    await run("delay(100)");
  });

  it.concurrent("test 2", async () => {
    await run("delay(100)");
  });

  // These run in parallel
});
```

```

jest-testing | SkillHub