categorize($commandList); expect($categories)->toHaveKey('demo'); expect($categories)->toHaveKey('db'); expect($categories['demo'])->toHaveCount(2); expect($categories['db'])->toHaveCount(2); }); it('sorts categories alphabetically', function () { $commands = [ new ConsoleCommand('zebra:command', 'Zebra command'), new ConsoleCommand('alpha:command', 'Alpha command'), new ConsoleCommand('beta:command', 'Beta command'), ]; $commandList = new CommandList(...$commands); $categorizer = new CommandCategorizer(); $categories = $categorizer->categorize($commandList); $keys = array_keys($categories); expect($keys)->toBe(['alpha', 'beta', 'zebra']); }); it('handles commands without namespace', function () { $commands = [ new ConsoleCommand('standalone', 'Standalone command'), new ConsoleCommand('demo:hello', 'Hello command'), ]; $commandList = new CommandList(...$commands); $categorizer = new CommandCategorizer(); $categories = $categorizer->categorize($commandList); expect($categories)->toHaveKey('standalone'); expect($categories)->toHaveKey('demo'); expect($categories['standalone'])->toHaveCount(1); }); it('handles empty command list', function () { $commandList = CommandList::empty(); $categorizer = new CommandCategorizer(); $categories = $categorizer->categorize($commandList); expect($categories)->toBeEmpty(); }); it('groups multiple commands in same category', function () { $commands = [ new ConsoleCommand('demo:hello', 'Hello'), new ConsoleCommand('demo:colors', 'Colors'), new ConsoleCommand('demo:interactive', 'Interactive'), new ConsoleCommand('demo:menu', 'Menu'), ]; $commandList = new CommandList(...$commands); $categorizer = new CommandCategorizer(); $categories = $categorizer->categorize($commandList); expect($categories['demo'])->toHaveCount(4); }); it('handles commands with multiple colons', function () { $commands = [ new ConsoleCommand('db:migrate:up', 'Migrate up'), new ConsoleCommand('db:migrate:down', 'Migrate down'), ]; $commandList = new CommandList(...$commands); $categorizer = new CommandCategorizer(); $categories = $categorizer->categorize($commandList); // Should use first part before first colon expect($categories)->toHaveKey('db'); expect($categories['db'])->toHaveCount(2); }); it('gets category description for known category', function () { $categorizer = new CommandCategorizer(); expect($categorizer->getCategoryDescription('db'))->toBe('Database operations (migrations, health checks)'); expect($categorizer->getCategoryDescription('demo'))->toBe('Demo and example commands'); expect($categorizer->getCategoryDescription('cache'))->toBe('Cache management operations'); }); it('returns default description for unknown category', function () { $categorizer = new CommandCategorizer(); expect($categorizer->getCategoryDescription('unknown'))->toBe('Various commands'); }); it('gets all category info', function () { $categorizer = new CommandCategorizer(); $info = $categorizer->getCategoryInfo(); expect($info)->toBeArray(); expect($info)->toHaveKey('db'); expect($info)->toHaveKey('demo'); expect($info)->toHaveKey('cache'); }); it('handles single command in category', function () { $commands = [ new ConsoleCommand('unique:command', 'Unique command'), ]; $commandList = new CommandList(...$commands); $categorizer = new CommandCategorizer(); $categories = $categorizer->categorize($commandList); expect($categories)->toHaveKey('unique'); expect($categories['unique'])->toHaveCount(1); }); it('preserves command order within category', function () { $commands = [ new ConsoleCommand('demo:first', 'First'), new ConsoleCommand('demo:second', 'Second'), new ConsoleCommand('demo:third', 'Third'), ]; $commandList = new CommandList(...$commands); $categorizer = new CommandCategorizer(); $categories = $categorizer->categorize($commandList); $demoCommands = $categories['demo']; expect($demoCommands[0]->name)->toBe('demo:first'); expect($demoCommands[1]->name)->toBe('demo:second'); expect($demoCommands[2]->name)->toBe('demo:third'); }); });