🎯

tdd-workflow

🎯Skill

from sakataka/tetris-game2

VibeIndex|
What it does

Guides test-driven development for Tetris game logic, emphasizing property-based testing, Result<T,E> pattern, and comprehensive test coverage.

πŸ“¦

Part of

sakataka/tetris-game2(6 items)

tdd-workflow

Installation

BunRun with Bun
bun install
BunRun with Bun
bun run dev
BunRun with Bun
bun run dev # Development server
BunRun with Bun
bun run format # Format code (write)
BunRun with Bun
bun run format:check # Check formatting

+ 5 more commands

πŸ“– Extracted from docs: sakataka/tetris-game2
4Installs
-
AddedFeb 4, 2026

Skill Details

SKILL.md

Test-driven development guidance for Tetris game logic. Use when writing tests, fixing test failures, improving test coverage, or implementing game mechanics. Auto-triggers on phrases like "write a test", "test this function", "improve coverage", "fix failing tests", or "add game logic". Emphasizes Result<T,E> pattern and property-based testing with fast-check.

Overview

# TDD Workflow for Tetris Game

Test-driven development guidance following the project's strict TDD requirements.

TDD Principles

  1. Test First: Write tests before implementation
  2. Red-Green-Refactor: Fail β†’ Pass β†’ Improve
  3. Co-located Tests: Test files must be next to implementation (*.test.ts)
  4. 160+ Tests: Comprehensive coverage for all game logic
  5. Property-based Testing: Use fast-check for critical game mechanics

Test Execution

```bash

# Run all tests (160+ tests)

bun test

# Run specific test file

bun test src/game/board.test.ts

# Run tests with coverage

bun test --coverage

```

Testing Requirements

βœ… Required Practices

  • Co-located Tests: Place test files next to implementation

```

src/game/

β”œβ”€β”€ board.ts

β”œβ”€β”€ board.test.ts # βœ… Co-located

β”œβ”€β”€ pieces.ts

└── pieces.test.ts # βœ… Co-located

```

  • Result Pattern: Game logic must return Result type

```typescript

type Result = { ok: true; value: T } | { ok: false; error: E }

// Good example

export const rotatepiece = (piece: Piece): Result => {

// ...

}

```

  • Block Bodies in forEach: Avoid implicit returns in test loops

```typescript

// βœ… Good

testCases.forEach((testCase) => {

expect(fn(testCase.input)).toBe(testCase.expected)

})

// ❌ Bad (implicit return)

testCases.forEach(testCase => expect(fn(testCase.input)).toBe(testCase.expected))

```

  • Property-based Testing: Use fast-check for game mechanics

```typescript

import fc from 'fast-check'

test('piece rotation is reversible', () => {

fc.assert(

fc.property(fc.integer(), (rotation) => {

const piece = rotatePiece(basePiece, rotation)

const reversed = rotatePiece(piece, -rotation)

return deepEqual(reversed, basePiece)

})

)

})

```

❌ Prohibited Practices

  • ❌ Relaxing conditions to resolve test errors
  • ❌ Skipping tests or using inappropriate mocking
  • ❌ Hardcoding outputs or responses
  • ❌ Ignoring or hiding error messages
  • ❌ Temporary fixes that postpone problems

TDD Workflow Steps

1. Write Failing Test (Red)

```typescript

// src/game/scoring.test.ts

test('T-Spin triple awards 1600 points', () => {

const result = calculateScore({

linesCleared: 3,

isTSpin: true,

level: 1

})

expect(result.ok).toBe(true)

if (result.ok) {

expect(result.value).toBe(1600)

}

})

```

2. Implement Minimum Code (Green)

```typescript

// src/game/scoring.ts

export const calculateScore = (params: ScoreParams): Result => {

if (params.isTSpin && params.linesCleared === 3) {

return { ok: true, value: 1600 }

}

// ... rest of implementation

}

```

3. Refactor (Clean)

  • Improve code quality while keeping tests green
  • Add edge case tests
  • Use property-based testing for comprehensive coverage

When This Skill Activates

  • "Write a test for this function"
  • "Test this game logic"
  • "Improve test coverage"
  • "Fix failing tests"
  • "Add tests for edge cases"
  • "Use TDD to implement this"
  • "Property-based test for rotation"

Test Structure Best Practices

```typescript

// src/game/board.test.ts

import { describe, test, expect } from 'bun:test'

import { createBoard, placePiece } from './board'

import fc from 'fast-check'

describe('Board Operations', () => {

test('creates empty 20x10 board', () => {

const board = createBoard()

expect(board.length).toBe(20)

expect(board[0].length).toBe(10)

})

test('placing piece updates board state', () => {

const board = createBoard()

const result = placePiece(board, piece, { x: 4, y: 0 })

expect(result.ok).toBe(true)

if (result.ok) {

expect(result.value.board).not.toBe(board) // Immutability

}

})

// Property-based test

test('board operations preserve dimensions', () => {

fc.assert(

fc.property(fc.array(fc.array(fc.boolean())), (cells) => {

const board = createBoardFromCells(cells)

return board.length === 20 && board[0].length === 10

})

)

})

})

```

Advanced Testing Patterns

See [testing-patterns.md](testing-patterns.md) for:

  • Complex Result pattern usage
  • Property-based testing strategies
  • Test organization best practices
  • Mocking guidelines