Feat: Added automatic determination of task number based on complexity (#884)
- Added 'defaultNumTasks: 10' to default config, now used in 'parse-prd' - Adjusted 'parse-prd' and 'expand-task' to: - Accept a 'numTasks' value of 0 - Updated tool and command descriptions - Updated prompts to 'an appropriate number of' when value is 0 - Updated 'README-task-master.md' and 'command-reference.md' docs - Added more tests for: 'parse-prd', 'expand-task' and 'config-manager' Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
This commit is contained in:
@@ -136,6 +136,7 @@ const DEFAULT_CONFIG = {
|
||||
global: {
|
||||
logLevel: 'info',
|
||||
debug: false,
|
||||
defaultNumTasks: 10,
|
||||
defaultSubtasks: 5,
|
||||
defaultPriority: 'medium',
|
||||
projectName: 'Task Master',
|
||||
@@ -738,5 +739,116 @@ describe('getAllProviders', () => {
|
||||
|
||||
// Add tests for getParametersForRole if needed
|
||||
|
||||
// --- defaultNumTasks Tests ---
|
||||
describe('Configuration Getters', () => {
|
||||
test('getDefaultNumTasks should return default value when config is valid', () => {
|
||||
// Arrange: Mock fs.readFileSync to return valid config when called with the expected path
|
||||
fsReadFileSyncSpy.mockImplementation((filePath) => {
|
||||
if (filePath === MOCK_CONFIG_PATH) {
|
||||
return JSON.stringify({
|
||||
global: {
|
||||
defaultNumTasks: 15
|
||||
}
|
||||
});
|
||||
}
|
||||
throw new Error(`Unexpected fs.readFileSync call: ${filePath}`);
|
||||
});
|
||||
fsExistsSyncSpy.mockReturnValue(true);
|
||||
|
||||
// Force reload to clear cache
|
||||
configManager.getConfig(MOCK_PROJECT_ROOT, true);
|
||||
|
||||
// Act: Call getDefaultNumTasks with explicit root
|
||||
const result = configManager.getDefaultNumTasks(MOCK_PROJECT_ROOT);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(15);
|
||||
});
|
||||
|
||||
test('getDefaultNumTasks should return fallback when config value is invalid', () => {
|
||||
// Arrange: Mock fs.readFileSync to return invalid config
|
||||
fsReadFileSyncSpy.mockImplementation((filePath) => {
|
||||
if (filePath === MOCK_CONFIG_PATH) {
|
||||
return JSON.stringify({
|
||||
global: {
|
||||
defaultNumTasks: 'invalid'
|
||||
}
|
||||
});
|
||||
}
|
||||
throw new Error(`Unexpected fs.readFileSync call: ${filePath}`);
|
||||
});
|
||||
fsExistsSyncSpy.mockReturnValue(true);
|
||||
|
||||
// Force reload to clear cache
|
||||
configManager.getConfig(MOCK_PROJECT_ROOT, true);
|
||||
|
||||
// Act: Call getDefaultNumTasks with explicit root
|
||||
const result = configManager.getDefaultNumTasks(MOCK_PROJECT_ROOT);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(10); // Should fallback to DEFAULTS.global.defaultNumTasks
|
||||
});
|
||||
|
||||
test('getDefaultNumTasks should return fallback when config value is missing', () => {
|
||||
// Arrange: Mock fs.readFileSync to return config without defaultNumTasks
|
||||
fsReadFileSyncSpy.mockImplementation((filePath) => {
|
||||
if (filePath === MOCK_CONFIG_PATH) {
|
||||
return JSON.stringify({
|
||||
global: {}
|
||||
});
|
||||
}
|
||||
throw new Error(`Unexpected fs.readFileSync call: ${filePath}`);
|
||||
});
|
||||
fsExistsSyncSpy.mockReturnValue(true);
|
||||
|
||||
// Force reload to clear cache
|
||||
configManager.getConfig(MOCK_PROJECT_ROOT, true);
|
||||
|
||||
// Act: Call getDefaultNumTasks with explicit root
|
||||
const result = configManager.getDefaultNumTasks(MOCK_PROJECT_ROOT);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(10); // Should fallback to DEFAULTS.global.defaultNumTasks
|
||||
});
|
||||
|
||||
test('getDefaultNumTasks should handle non-existent config file', () => {
|
||||
// Arrange: Mock file not existing
|
||||
fsExistsSyncSpy.mockReturnValue(false);
|
||||
|
||||
// Force reload to clear cache
|
||||
configManager.getConfig(MOCK_PROJECT_ROOT, true);
|
||||
|
||||
// Act: Call getDefaultNumTasks with explicit root
|
||||
const result = configManager.getDefaultNumTasks(MOCK_PROJECT_ROOT);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(10); // Should fallback to DEFAULTS.global.defaultNumTasks
|
||||
});
|
||||
|
||||
test('getDefaultNumTasks should accept explicit project root', () => {
|
||||
// Arrange: Mock fs.readFileSync to return valid config
|
||||
fsReadFileSyncSpy.mockImplementation((filePath) => {
|
||||
if (filePath === MOCK_CONFIG_PATH) {
|
||||
return JSON.stringify({
|
||||
global: {
|
||||
defaultNumTasks: 20
|
||||
}
|
||||
});
|
||||
}
|
||||
throw new Error(`Unexpected fs.readFileSync call: ${filePath}`);
|
||||
});
|
||||
fsExistsSyncSpy.mockReturnValue(true);
|
||||
|
||||
// Force reload to clear cache
|
||||
configManager.getConfig(MOCK_PROJECT_ROOT, true);
|
||||
|
||||
// Act: Call getDefaultNumTasks with explicit project root
|
||||
const result = configManager.getDefaultNumTasks(MOCK_PROJECT_ROOT);
|
||||
|
||||
// Assert
|
||||
expect(result).toBe(20);
|
||||
});
|
||||
});
|
||||
|
||||
// Note: Tests for setMainModel, setResearchModel were removed as the functions were removed in the implementation.
|
||||
// If similar setter functions exist, add tests for them following the writeConfig pattern.
|
||||
|
||||
Reference in New Issue
Block a user