From a7d3bb948bf0dd950f3644da03de71574bb28f7d Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sun, 26 Apr 2026 10:23:41 -0400 Subject: [PATCH] test(phase-lifecycle): add failing test for active milestone in
block Closes #2641 --- sdk/src/query/phase-lifecycle.test.ts | 76 +++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/sdk/src/query/phase-lifecycle.test.ts b/sdk/src/query/phase-lifecycle.test.ts index 9a4a0200d..9969149cd 100644 --- a/sdk/src/query/phase-lifecycle.test.ts +++ b/sdk/src/query/phase-lifecycle.test.ts @@ -150,6 +150,82 @@ describe('replaceInCurrentMilestone', () => { expect(before).toContain('3 plans'); // old milestone untouched expect(after).toContain('4 plans'); // current milestone updated }); + + it('replaces only in current milestone when older milestones are wrapped in
', async () => { + const { replaceInCurrentMilestone } = await import('./phase-lifecycle.js'); + const content = [ + '# Roadmap', + '', + '
', + '✅ v1.18 (shipped)', + '', + '### Phase 1: Old Phase', + '', + '- [ ] Phase 1: Old Phase', + '', + '
', + '', + '
', + '✅ v1.19 (shipped)', + '', + '### Phase 2: Another Old Phase', + '', + '
', + '', + '## Current Milestone: v1.20', + '', + '- [ ] Phase 3: Current work', + '', + '### Phase 3: Current work', + '', + '**Plans:** 0/2 plans', + '', + ].join('\n'); + + const pattern = /\*\*Plans:\*\* [^\n]+/; + const result = replaceInCurrentMilestone(content, pattern, '**Plans:** 2/2 plans complete'); + + // Should update Phase 3's Plans line (current milestone) + expect(result).toContain('**Plans:** 2/2 plans complete'); + // Should NOT touch v1.18 or v1.19 sections + expect(result).toContain('✅ v1.18'); + expect(result).toContain('✅ v1.19'); + }); + + it('replaces inside active milestone when it is wrapped in a
block', async () => { + const { replaceInCurrentMilestone } = await import('./phase-lifecycle.js'); + // Scenario: active milestone is collapsed in
(e.g. user collapsed it) + const content = [ + '# Roadmap', + '', + '
', + '✅ v1.18 (shipped)', + '', + '### Phase 1: Old Phase', + '', + '**Plans:** 1/1 plans', + '', + '
', + '', + '
', + '🚧 v1.19 in-progress', + '', + '### Phase 2: Current Work', + '', + '**Plans:** 1/2 plans', + '', + '
', + '', + ].join('\n'); + + const pattern = /\*\*Plans:\*\* [^\n]+/g; + const result = replaceInCurrentMilestone(content, pattern, '**Plans:** 2/2 plans complete'); + + // The replacement should happen somewhere in the content (not silently dropped) + expect(result).toContain('**Plans:** 2/2 plans complete'); + // v1.18 old plans line should remain untouched + expect(result).toContain('**Plans:** 1/1 plans'); + }); }); // ─── readModifyWriteRoadmapMd ───────────────────────────────────────────