test: deepen fixture module v2 for reliability (#329)

* test: deepen fixture seam for init/state/workstream suites

* test: deepen fixture module v2 with declarative builders
This commit is contained in:
Tom Boucher
2026-05-26 11:23:42 -04:00
committed by GitHub
parent 656bff8b73
commit 06cf7826e3
6 changed files with 304 additions and 132 deletions

View File

@@ -8,7 +8,8 @@ const crypto = require('crypto');
const fs = require('fs');
const os = require('os');
const path = require('path');
const { runGsdTools, createTempProject, cleanup } = require('./helpers.cjs');
const { runGsdTools, cleanup } = require('./helpers.cjs');
const { createFixture, seedWorkstream, writeState } = require('./fixtures/index.cjs');
const { migrateToWorkstreams, getOtherActiveWorkstreams } = require('../get-shit-done/bin/lib/workstream.cjs');
// ─── Helper ──────────────────────────────────────────────────────────────────
@@ -18,7 +19,7 @@ function createProjectWithState(tmpDir, roadmap, state) {
fs.writeFileSync(path.join(tmpDir, '.planning', 'ROADMAP.md'), roadmap, 'utf-8');
}
if (state) {
fs.writeFileSync(path.join(tmpDir, '.planning', 'STATE.md'), state, 'utf-8');
writeState(tmpDir, state);
}
}
@@ -75,13 +76,13 @@ describe('planningDir workstream awareness via env var', () => {
let tmpDir;
before(() => {
tmpDir = createTempProject();
// Create workstream structure
const wsDir = path.join(tmpDir, '.planning', 'workstreams', 'alpha');
fs.mkdirSync(path.join(wsDir, 'phases'), { recursive: true });
fs.writeFileSync(path.join(wsDir, 'STATE.md'), '# State\n**Status:** In progress\n**Current Phase:** 1\n');
fs.writeFileSync(path.join(wsDir, 'ROADMAP.md'), '## Roadmap v1.0: Alpha\n### Phase 1: Setup\n');
fs.writeFileSync(path.join(tmpDir, '.planning', 'active-workstream'), 'alpha\n');
tmpDir = createFixture();
seedWorkstream(tmpDir, {
name: 'alpha',
state: '# State\n**Status:** In progress\n**Current Phase:** 1\n',
roadmap: '## Roadmap v1.0: Alpha\n### Phase 1: Setup\n',
active: true,
});
});
after(() => cleanup(tmpDir));
@@ -119,7 +120,7 @@ describe('session-scoped active workstream routing', () => {
let tmpDir;
before(() => {
tmpDir = createTempProject();
tmpDir = createFixture();
for (const [ws, status] of [['alpha', 'Alpha active'], ['beta', 'Beta active']]) {
const wsDir = path.join(tmpDir, '.planning', 'workstreams', ws);
@@ -193,7 +194,7 @@ describe('session resolution hardening', () => {
let tmpDir;
beforeEach(() => {
tmpDir = createTempProject();
tmpDir = createFixture();
for (const [ws, status] of [['alpha', 'Alpha active'], ['beta', 'Beta active']]) {
const wsDir = path.join(tmpDir, '.planning', 'workstreams', ws);
@@ -254,7 +255,7 @@ describe('pointer lifecycle hardening', () => {
let tmpDir;
beforeEach(() => {
tmpDir = createTempProject();
tmpDir = createFixture();
for (const [ws, status] of [['alpha', 'Alpha active'], ['beta', 'Beta active']]) {
const wsDir = path.join(tmpDir, '.planning', 'workstreams', ws);
@@ -323,7 +324,7 @@ describe('workstream create', () => {
let tmpDir;
before(() => {
tmpDir = createTempProject();
tmpDir = createFixture();
fs.writeFileSync(path.join(tmpDir, '.planning', 'PROJECT.md'), '# Project\n');
});
@@ -365,7 +366,7 @@ describe('workstream create with migration', () => {
let tmpDir;
before(() => {
tmpDir = createTempProject();
tmpDir = createFixture();
fs.writeFileSync(path.join(tmpDir, '.planning', 'PROJECT.md'), '# Project\n');
// Existing flat-mode work
fs.writeFileSync(path.join(tmpDir, '.planning', 'ROADMAP.md'), '## Roadmap v1.0: Existing\n### Phase 1: A\n');
@@ -389,7 +390,7 @@ describe('workstream create with migration', () => {
});
test('normalizes --migrate-name to a valid workstream slug', () => {
const isolatedDir = createTempProject();
const isolatedDir = createFixture();
try {
fs.writeFileSync(path.join(isolatedDir, '.planning', 'PROJECT.md'), '# Project\n');
fs.writeFileSync(path.join(isolatedDir, '.planning', 'ROADMAP.md'), '## Roadmap v1.0: Existing\n### Phase 1: A\n');
@@ -414,7 +415,7 @@ describe('workstream create with migration', () => {
describe('migrateToWorkstreams', () => {
test('rejects invalid workstream names for migration', () => {
const tmpDir = createTempProject();
const tmpDir = createFixture();
try {
assert.throws(
() => migrateToWorkstreams(tmpDir, 'bad/name'),
@@ -426,7 +427,7 @@ describe('migrateToWorkstreams', () => {
});
test('fails when already in workstream mode', () => {
const tmpDir = createTempProject();
const tmpDir = createFixture();
try {
fs.mkdirSync(path.join(tmpDir, '.planning', 'workstreams', 'existing'), { recursive: true });
assert.throws(
@@ -443,7 +444,7 @@ describe('workstream list', () => {
let tmpDir;
before(() => {
tmpDir = createTempProject();
tmpDir = createFixture();
// Create two workstreams
for (const ws of ['alpha', 'beta']) {
const wsDir = path.join(tmpDir, '.planning', 'workstreams', ws);
@@ -468,7 +469,7 @@ describe('workstream list', () => {
let flatDir;
beforeEach(() => {
flatDir = createTempProject();
flatDir = createFixture();
});
afterEach(() => {
@@ -488,7 +489,7 @@ describe('workstream status', () => {
let tmpDir;
before(() => {
tmpDir = createTempProject();
tmpDir = createFixture();
const wsDir = path.join(tmpDir, '.planning', 'workstreams', 'alpha');
fs.mkdirSync(path.join(wsDir, 'phases', '01-setup'), { recursive: true });
fs.writeFileSync(path.join(wsDir, 'phases', '01-setup', 'PLAN.md'), '# Plan\n');
@@ -521,7 +522,7 @@ describe('workstream complete', () => {
let tmpDir;
before(() => {
tmpDir = createTempProject();
tmpDir = createFixture();
const wsDir = path.join(tmpDir, '.planning', 'workstreams', 'done-ws');
fs.mkdirSync(path.join(wsDir, 'phases'), { recursive: true });
fs.writeFileSync(path.join(wsDir, 'STATE.md'), '# State\n**Status:** Complete\n');
@@ -549,7 +550,7 @@ describe('workstream set/get', () => {
let tmpDir;
before(() => {
tmpDir = createTempProject();
tmpDir = createFixture();
for (const ws of ['ws-a', 'ws-b']) {
const wsDir = path.join(tmpDir, '.planning', 'workstreams', ws);
fs.mkdirSync(path.join(wsDir, 'phases'), { recursive: true });
@@ -596,7 +597,7 @@ describe('getOtherActiveWorkstreams', () => {
let tmpDir;
before(() => {
tmpDir = createTempProject();
tmpDir = createFixture();
// Create 3 workstreams: alpha (active), beta (active), gamma (completed)
for (const ws of ['alpha', 'beta', 'gamma']) {
const wsDir = path.join(tmpDir, '.planning', 'workstreams', ws);
@@ -643,7 +644,7 @@ describe('workstream progress', () => {
let tmpDir;
before(() => {
tmpDir = createTempProject();
tmpDir = createFixture();
const wsDir = path.join(tmpDir, '.planning', 'workstreams', 'feature');
fs.mkdirSync(path.join(wsDir, 'phases', '01-init'), { recursive: true });
fs.writeFileSync(path.join(wsDir, 'phases', '01-init', 'PLAN.md'), '# Plan\n');
@@ -667,7 +668,7 @@ describe('workstream progress', () => {
});
test('clamps progress percent when completed phase dirs exceed roadmap count', () => {
const isolatedDir = createTempProject();
const isolatedDir = createFixture();
try {
const wsDir = path.join(isolatedDir, '.planning', 'workstreams', 'overflow');
for (const phase of ['01-one', '02-two']) {
@@ -689,7 +690,7 @@ describe('workstream progress', () => {
});
test('returns flat mode when no workstreams exist', () => {
const emptyDir = createTempProject();
const emptyDir = createFixture();
try {
const result = runGsdTools(['workstream', 'progress', '--raw'], emptyDir);
assert.ok(result.success, `progress in flat mode failed: ${result.error}`);
@@ -707,7 +708,7 @@ describe('gsd-tools --ws flag integration', () => {
let tmpDir;
before(() => {
tmpDir = createTempProject();
tmpDir = createFixture();
// Create a workstream with roadmap
const wsDir = path.join(tmpDir, '.planning', 'workstreams', 'test-ws');
fs.mkdirSync(path.join(wsDir, 'phases', '01-setup'), { recursive: true });
@@ -741,7 +742,7 @@ describe('path traversal rejection', () => {
let tmpDir;
before(() => {
tmpDir = createTempProject();
tmpDir = createFixture();
fs.writeFileSync(path.join(tmpDir, '.planning', 'PROJECT.md'), '# Project\n');
const wsDir = path.join(tmpDir, '.planning', 'workstreams', 'legit');
fs.mkdirSync(path.join(wsDir, 'phases'), { recursive: true });