Skip to content

Write unit tests for lib/state.cjs #133

@snipcodeit

Description

@snipcodeit

Context

Phase 32 is the first phase of v3.5 Foundation Hardening. lib/state.cjs is the most critical lib module — every command reads/writes project state through it. migrateProjectState() and resolveActiveMilestoneIndex() have complex schema-evolution logic that has never been tested. A regression in either silently corrupts pipeline state.

What Already Exists

  • lib/state.cjs (216 lines) — 9 exported functions: getMgwDir, getActiveDir, getCompletedDir, loadProjectState, writeProjectState, loadActiveIssue, mergeProjectState, migrateProjectState, resolveActiveMilestoneIndex
  • test/mgw.test.cjs (75 lines) — placeholder using node:test + node:assert/strict; documents the fs.mkdtempSync + process.cwd override strategy; npm test = node --test 'test/**/*.test.cjs'
  • package.json test script: node --test 'test/**/*.test.cjs' — no new deps needed
  • migrateProjectState() is idempotent and handles legacy current_milestone → active_gsd_milestone migration (lines 145-178)
  • resolveActiveMilestoneIndex() resolves active_gsd_milestone string OR legacy current_milestone integer (lines 187-204)

Description

Implement comprehensive unit tests for lib/state.cjs using the node:test built-in runner (zero new dependencies).

Technical Approach

  • New file: test/state.test.cjs
  • Framework: node:test + node:assert/strict — already wired in package.json test script
  • Isolation: fs.mkdtempSync() creates a real temp dir; override process.cwd() to point at it; afterEach removes .mgw/ for clean state between tests
  • Critical cases first: resolveActiveMilestoneIndex with new schema vs legacy, migrateProjectState idempotency
  • Functions to test (all 9): getMgwDir, getActiveDir, getCompletedDir, loadProjectState, writeProjectState, loadActiveIssue, mergeProjectState, migrateProjectState, resolveActiveMilestoneIndex

Done When

  • test/state.test.cjs exists with at least 15 test cases covering all 9 exported functions
  • resolveActiveMilestoneIndex tests include: new schema takes precedence, legacy fallback, dangling reference returns null
  • migrateProjectState tests include: idempotency (run twice yields same result), converts legacy current_milestone integer to active_gsd_milestone string
  • npm test exits 0 with all tests passing
  • npm test exits non-zero if a test is deleted and re-run with a forced failure

GSD Route

Quick task (mgw:run → quick path). Single plan, single executor, no GSD phase.

Phase Context

Phase 32 of 36 — Test Coverage. Runs independently (no deps on 33/34/35). Issues: #133 (this), #134.

Depends on

Nothing — first phase of v3.5.

Metadata

Metadata

Assignees

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions