Files
michaelschiemer/tests/Framework/Console/CommandCategorizerTest.php
Michael Schiemer 8f3c15ddbb fix(console): comprehensive TUI rendering fixes
- Fix Enter key detection: handle multiple Enter key formats (\n, \r, \r\n)
- Reduce flickering: lower render frequency from 60 FPS to 30 FPS
- Fix menu bar visibility: re-render menu bar after content to prevent overwriting
- Fix content positioning: explicit line positioning for categories and commands
- Fix line shifting: clear lines before writing, control newlines manually
- Limit visible items: prevent overflow with maxVisibleCategories/Commands
- Improve CPU usage: increase sleep interval when no events processed

This fixes:
- Enter key not working for selection
- Strong flickering of the application
- Menu bar not visible or being overwritten
- Top half of selection list not displayed
- Lines being shifted/misaligned
2025-11-10 11:06:07 +01:00

153 lines
5.4 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Framework\Console;
use App\Framework\Console\CommandCategorizer;
use App\Framework\Console\CommandList;
use App\Framework\Console\ConsoleCommand;
describe('CommandCategorizer', function () {
it('categorizes commands by namespace prefix', function () {
$commands = [
new ConsoleCommand('demo:hello', 'Hello command'),
new ConsoleCommand('demo:colors', 'Colors command'),
new ConsoleCommand('db:migrate', 'Migrate command'),
new ConsoleCommand('db:rollback', 'Rollback command'),
];
$commandList = new CommandList(...$commands);
$categorizer = new CommandCategorizer();
$categories = $categorizer->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');
});
});