Skip to content

Commit 55eed06

Browse files
committed
test: improve on-demand epic coverage and fix test cleanup
- Fix test cleanup: use delete for properties that were not originally set instead of assigning undefined (Copilot + CodeRabbit feedback) - Add test: on-demand epics should not count toward progress calculation - Add test: _calculateProgressFromState returns 0 when all epics are on-demand
1 parent 8667358 commit 55eed06

1 file changed

Lines changed: 52 additions & 4 deletions

File tree

tests/core/master-orchestrator.test.js

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ describe('MasterOrchestrator', () => {
433433
// Temporarily make all epics on-demand to trigger the zero-division guard
434434
const originalConfig = {};
435435
for (const [num, cfg] of Object.entries(EPIC_CONFIG)) {
436-
originalConfig[num] = cfg.onDemand;
436+
originalConfig[num] = { had: 'onDemand' in cfg, value: cfg.onDemand };
437437
cfg.onDemand = true;
438438
}
439439

@@ -442,9 +442,57 @@ describe('MasterOrchestrator', () => {
442442
expect(progress).toBe(0);
443443
expect(Number.isNaN(progress)).toBe(false);
444444
} finally {
445-
// Restore original config
446-
for (const [num, val] of Object.entries(originalConfig)) {
447-
EPIC_CONFIG[num].onDemand = val;
445+
// Restore original config — delete property when it was not originally set
446+
for (const [num, orig] of Object.entries(originalConfig)) {
447+
if (orig.had) {
448+
EPIC_CONFIG[num].onDemand = orig.value;
449+
} else {
450+
delete EPIC_CONFIG[num].onDemand;
451+
}
452+
}
453+
}
454+
});
455+
456+
it('should not count on-demand epics in progress calculation', async () => {
457+
await orchestrator.initialize();
458+
459+
// Epic 5 is on-demand — completing it should not affect progress
460+
await orchestrator.executeEpic(5);
461+
expect(orchestrator.getProgressPercentage()).toBe(0); // 0 of 3 non-on-demand
462+
463+
await orchestrator.executeEpic(3);
464+
expect(orchestrator.getProgressPercentage()).toBe(33); // 1 of 3 non-on-demand
465+
});
466+
467+
it('should return 0 from _calculateProgressFromState when all epics are on-demand', async () => {
468+
await orchestrator.initialize();
469+
470+
const originalConfig = {};
471+
for (const [num, cfg] of Object.entries(EPIC_CONFIG)) {
472+
originalConfig[num] = { had: 'onDemand' in cfg, value: cfg.onDemand };
473+
cfg.onDemand = true;
474+
}
475+
476+
try {
477+
const states = await orchestrator.listSavedStates();
478+
// _calculateProgressFromState is private, test via getStatus or direct state
479+
// Create a mock state with completed epics
480+
const mockState = {
481+
epics: {
482+
3: { status: EpicStatus.COMPLETED },
483+
5: { status: EpicStatus.COMPLETED },
484+
},
485+
};
486+
const progress = orchestrator._calculateProgressFromState(mockState);
487+
expect(progress).toBe(0);
488+
expect(Number.isNaN(progress)).toBe(false);
489+
} finally {
490+
for (const [num, orig] of Object.entries(originalConfig)) {
491+
if (orig.had) {
492+
EPIC_CONFIG[num].onDemand = orig.value;
493+
} else {
494+
delete EPIC_CONFIG[num].onDemand;
495+
}
448496
}
449497
}
450498
});

0 commit comments

Comments
 (0)