fix: use tag-specific complexity reports (#857)
* fix(expand-task): Use tag-specific complexity reports - Add getTagAwareFilePath utility function to resolve tag-specific file paths - Update expandTask to use tag-aware complexity report paths - Fix issue where expand-task always used default complexity report - Add comprehensive tests for getTagAwareFilePath utility - Ensure proper handling of file extensions and directory structures Fixes #850: Expanding tasks not using tag-specific complexity reports The expandTask function now correctly uses complexity reports specific to the current tag context (e.g., task-complexity-report_feature-branch.json) instead of always using the default task-complexity-report.json file. This enables proper task expansion behavior when working with multiple tag contexts, ensuring complexity analysis is tag-specific and accurate. * chore: Add changeset for tag-specific complexity reports fix * test(expand-task): Add tests for tag-specific complexity report integration - Introduced a new test suite for verifying the integration of tag-specific complexity reports in the expandTask function. - Added a test case to ensure the correct complexity report is used when available for a specific tag. - Mocked file system interactions to simulate the presence of tag-specific complexity reports. This enhances the test coverage for task expansion behavior, ensuring it accurately reflects the complexity analysis based on the current tag context. * refactor(task-manager): unify and simplify tag-aware file path logic and tests - Reformatted imports and cleaned up comments in test files for readability - Centralized mocks: moved getTagAwareFilePath & slugifyTagForFilePath mocks to setup.js for consistency and maintainability - Simplified utils/getTagAwareFilePath: replaced manual parsing with path.parse() & path.format(); improved extension handling - Enhanced test mocks for path.parse, path.format & reset path.join in beforeEach to avoid interference - All tests now pass consistently; no change in functionality
This commit is contained in:
@@ -3,6 +3,10 @@
|
||||
*/
|
||||
import { jest } from '@jest/globals';
|
||||
import fs from 'fs';
|
||||
import {
|
||||
createGetTagAwareFilePathMock,
|
||||
createSlugifyTagForFilePathMock
|
||||
} from './setup.js';
|
||||
|
||||
// Mock the dependencies before importing the module under test
|
||||
jest.unstable_mockModule('../../../../../scripts/modules/utils.js', () => ({
|
||||
@@ -36,6 +40,8 @@ jest.unstable_mockModule('../../../../../scripts/modules/utils.js', () => ({
|
||||
}
|
||||
return allTasks;
|
||||
}),
|
||||
getTagAwareFilePath: createGetTagAwareFilePathMock(),
|
||||
slugifyTagForFilePath: createSlugifyTagForFilePathMock(),
|
||||
readComplexityReport: jest.fn(),
|
||||
markMigrationForNotice: jest.fn(),
|
||||
performCompleteTagMigration: jest.fn(),
|
||||
@@ -649,6 +655,61 @@ describe('expandTask', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Complexity Report Integration (Tag-Specific)', () => {
|
||||
test('should use tag-specific complexity report when available', async () => {
|
||||
// Arrange
|
||||
const tasksPath = 'tasks/tasks.json';
|
||||
const taskId = '1'; // Task in feature-branch
|
||||
const context = {
|
||||
mcpLog: createMcpLogMock(),
|
||||
projectRoot: '/mock/project/root',
|
||||
tag: 'feature-branch'
|
||||
};
|
||||
|
||||
// Stub fs.existsSync to simulate complexity report exists for this tag
|
||||
const existsSpy = jest
|
||||
.spyOn(fs, 'existsSync')
|
||||
.mockImplementation((filepath) =>
|
||||
filepath.endsWith('task-complexity-report_feature-branch.json')
|
||||
);
|
||||
|
||||
// Stub readJSON to return complexity report when reading the report path
|
||||
readJSON.mockImplementation((filepath, projectRootParam, tagParam) => {
|
||||
if (filepath.includes('task-complexity-report_feature-branch.json')) {
|
||||
return {
|
||||
complexityAnalysis: [
|
||||
{
|
||||
taskId: 1,
|
||||
complexityScore: 8,
|
||||
recommendedSubtasks: 5,
|
||||
reasoning: 'Needs five detailed steps',
|
||||
expansionPrompt: 'Please break this task into 5 parts'
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
// Default tasks data for tasks.json
|
||||
const sampleTasksCopy = JSON.parse(JSON.stringify(sampleTasks));
|
||||
const selectedTag = tagParam || 'master';
|
||||
return {
|
||||
...sampleTasksCopy[selectedTag],
|
||||
tag: selectedTag,
|
||||
_rawTaggedData: sampleTasksCopy
|
||||
};
|
||||
});
|
||||
|
||||
// Act
|
||||
await expandTask(tasksPath, taskId, undefined, false, '', context, false);
|
||||
|
||||
// Assert - generateTextService called with systemPrompt for 5 subtasks
|
||||
const callArg = generateTextService.mock.calls[0][0];
|
||||
expect(callArg.systemPrompt).toContain('Generate exactly 5 subtasks');
|
||||
|
||||
// Clean up stub
|
||||
existsSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Error Handling', () => {
|
||||
test('should handle non-existent task ID', async () => {
|
||||
// Arrange
|
||||
|
||||
Reference in New Issue
Block a user