From 94f8e895c0fe6e384aa65548251209bb57714f1e Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sat, 25 Apr 2026 12:04:16 -0400 Subject: [PATCH] test(#2692): add behavioral --wave N test, annotate source-text assertions (#2704) Adds two behavioral tests for wave filtering via phase-plan-index: - Verifies plans with wave frontmatter are correctly grouped by wave number - Verifies plans with no wave field default to wave 1 Co-authored-by: Claude Sonnet 4.6 --- tests/execute-phase-wave.test.cjs | 97 +++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/tests/execute-phase-wave.test.cjs b/tests/execute-phase-wave.test.cjs index 7b7440a45..ff2e05b22 100644 --- a/tests/execute-phase-wave.test.cjs +++ b/tests/execute-phase-wave.test.cjs @@ -128,6 +128,103 @@ describe('execute-phase docs: user-facing wave flag', () => { }); }); +describe('phase-plan-index: wave grouping behavior', () => { + test('phase-plan-index groups plans by wave frontmatter field', () => { + // allow-test-rule: behavioral — calls gsd-tools and asserts structured output + const fs = require('fs'); + const path = require('path'); + const tmpDir = createTempProject(); + try { + const phaseDir = path.join(tmpDir, '.planning', 'phases', '01-alpha'); + fs.mkdirSync(phaseDir, { recursive: true }); + + // Wave 1 plan + fs.writeFileSync(path.join(phaseDir, 'P001-PLAN.md'), [ + '---', + 'wave: 1', + 'objective: First wave task', + 'autonomous: true', + '---', + '', + '# Plan 001', + '', + 'First wave task', + '', + 'Do the thing', + ].join('\n')); + + // Wave 2 plan + fs.writeFileSync(path.join(phaseDir, 'P002-PLAN.md'), [ + '---', + 'wave: 2', + 'objective: Second wave task', + 'autonomous: true', + '---', + '', + '# Plan 002', + '', + 'Second wave task', + '', + 'Do the other thing', + ].join('\n')); + + const result = runGsdTools(['phase-plan-index', '1', '--raw'], tmpDir); + assert.ok(result.success, `phase-plan-index should succeed: ${result.error}`); + + const data = JSON.parse(result.output); + + // Wave grouping must be present + assert.ok(data.waves, 'output should have a waves property'); + assert.deepEqual(data.waves['1'], ['P001'], 'wave 1 should contain P001'); + assert.deepEqual(data.waves['2'], ['P002'], 'wave 2 should contain P002'); + + // Individual plan records must carry their wave numbers + const p001 = data.plans.find(p => p.id === 'P001'); + const p002 = data.plans.find(p => p.id === 'P002'); + assert.ok(p001, 'P001 should be in plans array'); + assert.ok(p002, 'P002 should be in plans array'); + assert.equal(p001.wave, 1, 'P001 should have wave=1'); + assert.equal(p002.wave, 2, 'P002 should have wave=2'); + } finally { + cleanup(tmpDir); + } + }); + + test('phase-plan-index defaults missing wave frontmatter to wave 1', () => { + // allow-test-rule: behavioral — exercises gsd-tools wave-defaulting logic + const fs = require('fs'); + const path = require('path'); + const tmpDir = createTempProject(); + try { + const phaseDir = path.join(tmpDir, '.planning', 'phases', '01-alpha'); + fs.mkdirSync(phaseDir, { recursive: true }); + + // Plan with no wave field in frontmatter + fs.writeFileSync(path.join(phaseDir, 'P001-PLAN.md'), [ + '---', + 'objective: No wave specified', + 'autonomous: true', + '---', + '', + '# Plan 001', + '', + 'Some work', + ].join('\n')); + + const result = runGsdTools(['phase-plan-index', '1', '--raw'], tmpDir); + assert.ok(result.success, `phase-plan-index should succeed: ${result.error}`); + + const data = JSON.parse(result.output); + const p001 = data.plans.find(p => p.id === 'P001'); + assert.ok(p001, 'P001 should appear in plans'); + assert.equal(p001.wave, 1, 'plan with no wave frontmatter should default to wave 1'); + assert.deepEqual(data.waves['1'], ['P001'], 'defaulted plan should land in wave 1 group'); + } finally { + cleanup(tmpDir); + } + }); +}); + describe('use_worktrees config: cross-workflow structural coverage', () => { const QUICK_PATH = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'quick.md'); const DIAGNOSE_PATH = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'diagnose-issues.md');