fix(test): update worktree sync tests to use separate milestone IDs

The fix skips the current milestone in syncWorktreeStateBack to prevent
merge conflicts. Update tests to use a different milestone ID for the
milestoneId parameter vs the milestone being synced, matching the new
skip-current-milestone behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tibsfox 2026-04-06 22:49:02 -07:00
parent 2a2ad20592
commit 60bbf8f0b3
2 changed files with 29 additions and 26 deletions

View file

@ -221,7 +221,8 @@ describe('worktree-sync-milestones', async () => {
try {
// Build worktree milestone structure with slice-level and task-level files
const wtSliceDir = join(wtBase, '.gsd', 'milestones', 'M001', 'slices', 'S01');
// Use M002 as the milestone to sync, M001 as the "current" being merged (skipped)
const wtSliceDir = join(wtBase, '.gsd', 'milestones', 'M002', 'slices', 'S01');
const wtTasksDir = join(wtSliceDir, 'tasks');
mkdirSync(wtTasksDir, { recursive: true });
writeFileSync(join(wtSliceDir, 'S01-SUMMARY.md'), '# S01 Summary');
@ -229,11 +230,12 @@ describe('worktree-sync-milestones', async () => {
writeFileSync(join(wtTasksDir, 'T02-SUMMARY.md'), '# T02 Summary');
// Main project root starts with only the milestone directory (no slices yet)
mkdirSync(join(mainBase, '.gsd', 'milestones', 'M001'), { recursive: true });
mkdirSync(join(mainBase, '.gsd', 'milestones', 'M002'), { recursive: true });
// Pass M001 as milestoneId (the one being merged/skipped), M002 should still sync
const { synced } = syncWorktreeStateBack(mainBase, wtBase, 'M001');
const mainSliceDir = join(mainBase, '.gsd', 'milestones', 'M001', 'slices', 'S01');
const mainSliceDir = join(mainBase, '.gsd', 'milestones', 'M002', 'slices', 'S01');
const mainTasksDir = join(mainSliceDir, 'tasks');
assert.ok(
@ -341,16 +343,16 @@ describe('worktree-sync-milestones', async () => {
'M002 missing in main before sync',
);
// Sync with milestoneId = M001 (the current milestone)
// Sync with milestoneId = M001 (the current milestone being merged — skipped)
const { synced } = syncWorktreeStateBack(mainBase, wtBase, 'M001');
// M001 should be synced (current milestone — always synced)
// M001 should be SKIPPED (current milestone being merged — #3641)
assert.ok(
existsSync(join(mainBase, '.gsd', 'milestones', 'M001', 'M001-SUMMARY.md')),
'M001 SUMMARY synced to main',
!existsSync(join(mainBase, '.gsd', 'milestones', 'M001', 'M001-SUMMARY.md')),
'M001 SUMMARY NOT synced (current milestone skipped to prevent merge conflicts)',
);
// M002 should ALSO be synced (next milestone — the fix)
// M002 should be synced (other milestone — not skipped)
assert.ok(
existsSync(join(mainBase, '.gsd', 'milestones', 'M002-abc123', 'M002-abc123-CONTEXT.md')),
'M002 CONTEXT synced to main (next-milestone fix)',
@ -407,20 +409,17 @@ describe('worktree-sync-milestones', async () => {
writeFileSync(join(wtBase, '.gsd', 'REQUIREMENTS.md'), '# Requirements\n## R001-R089\n## R090 — SCIM\n## R091 — WebAuthn');
writeFileSync(join(wtBase, '.gsd', 'PROJECT.md'), '# Project\nMilestones: M001-M007');
// Sync with milestoneId = M006 (the completing milestone)
// Sync with milestoneId = M006 (the completing milestone — skipped by sync)
const { synced } = syncWorktreeStateBack(mainBase, wtBase, 'M006-589wvh');
// Verify M006 artifacts synced
// M006 is the current milestone being merged — it should be SKIPPED (#3641)
// Its files are already in the milestone branch and would conflict with squash merge.
assert.ok(
existsSync(join(mainBase, '.gsd', 'milestones', 'M006-589wvh', 'M006-589wvh-SUMMARY.md')),
'M006 SUMMARY synced',
);
assert.ok(
existsSync(join(mainBase, '.gsd', 'milestones', 'M006-589wvh', 'slices', 'S01', 'S01-SUMMARY.md')),
'M006 S01 SUMMARY synced',
!existsSync(join(mainBase, '.gsd', 'milestones', 'M006-589wvh', 'M006-589wvh-SUMMARY.md')),
'M006 SUMMARY NOT synced (current milestone skipped)',
);
// Verify M007 artifacts synced (the critical fix)
// Verify M007 artifacts synced (the critical fix — other milestones still sync)
assert.ok(
existsSync(join(mainBase, '.gsd', 'milestones', 'M007-wortc8', 'M007-wortc8-CONTEXT.md')),
'M007 CONTEXT synced to main (next-milestone)',

View file

@ -47,7 +47,8 @@ function writeFile(dir: string, relativePath: string, content: string): void {
test("syncWorktreeStateBack copies task summaries from tasks/ subdirectory (#1678)", () => {
const mainBase = makeTempDir("main");
const wtBase = makeTempDir("wt");
const mid = "M001";
const currentMid = "M000"; // milestone being merged (skipped by sync)
const mid = "M001"; // other milestone that should be synced
try {
// Set up worktree with milestone, slice, and task files
@ -64,8 +65,8 @@ test("syncWorktreeStateBack copies task summaries from tasks/ subdirectory (#167
// Set up main with empty .gsd
mkdirSync(join(mainBase, ".gsd"), { recursive: true });
// Run sync
const result = syncWorktreeStateBack(mainBase, wtBase, mid);
// Run sync — currentMid is skipped, mid (M001) should be synced
const result = syncWorktreeStateBack(mainBase, wtBase, currentMid);
// Verify milestone-level files synced
assert.ok(
@ -126,7 +127,8 @@ test("syncWorktreeStateBack copies task summaries from tasks/ subdirectory (#167
test("syncWorktreeStateBack handles multiple slices with tasks (#1678)", () => {
const mainBase = makeTempDir("main");
const wtBase = makeTempDir("wt");
const mid = "M002";
const currentMid = "M000"; // milestone being merged (skipped)
const mid = "M002"; // other milestone that should be synced
try {
// Set up two slices with tasks
@ -139,7 +141,7 @@ test("syncWorktreeStateBack handles multiple slices with tasks (#1678)", () => {
mkdirSync(join(mainBase, ".gsd"), { recursive: true });
const result = syncWorktreeStateBack(mainBase, wtBase, mid);
const result = syncWorktreeStateBack(mainBase, wtBase, currentMid);
// All task summaries from both slices should be synced
assert.ok(existsSync(join(mainBase, `.gsd/milestones/${mid}/slices/S01/tasks/T01-SUMMARY.md`)));
@ -160,7 +162,8 @@ test("syncWorktreeStateBack handles multiple slices with tasks (#1678)", () => {
test("syncWorktreeStateBack handles slices without tasks/ directory", () => {
const mainBase = makeTempDir("main");
const wtBase = makeTempDir("wt");
const mid = "M003";
const currentMid = "M000"; // milestone being merged (skipped)
const mid = "M003"; // other milestone that should be synced
try {
// Slice with no tasks/ subdirectory (legitimate case: pre-planning)
@ -168,7 +171,7 @@ test("syncWorktreeStateBack handles slices without tasks/ directory", () => {
mkdirSync(join(mainBase, ".gsd"), { recursive: true });
const result = syncWorktreeStateBack(mainBase, wtBase, mid);
const result = syncWorktreeStateBack(mainBase, wtBase, currentMid);
// Should sync the slice file without errors
assert.ok(existsSync(join(mainBase, `.gsd/milestones/${mid}/slices/S01/S01-RESEARCH.md`)));
@ -183,7 +186,8 @@ test("syncWorktreeStateBack handles slices without tasks/ directory", () => {
test("syncWorktreeStateBack ignores non-md files in tasks/", () => {
const mainBase = makeTempDir("main");
const wtBase = makeTempDir("wt");
const mid = "M004";
const currentMid = "M000"; // milestone being merged (skipped)
const mid = "M004"; // other milestone that should be synced
try {
writeFile(wtBase, `.gsd/milestones/${mid}/slices/S01/S01-PLAN.md`, "# Plan\n");
@ -194,7 +198,7 @@ test("syncWorktreeStateBack ignores non-md files in tasks/", () => {
mkdirSync(join(mainBase, ".gsd"), { recursive: true });
const result = syncWorktreeStateBack(mainBase, wtBase, mid);
const result = syncWorktreeStateBack(mainBase, wtBase, currentMid);
// Only .md files should be synced
assert.ok(existsSync(join(mainBase, `.gsd/milestones/${mid}/slices/S01/tasks/T01-SUMMARY.md`)));