- 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
150 lines
3.8 KiB
PHP
150 lines
3.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Framework\Console\Helpers;
|
|
|
|
use App\Framework\Console\ConsoleColor;
|
|
use App\Framework\Console\ConsoleOutputInterface;
|
|
use App\Framework\Console\ConsoleStyle;
|
|
|
|
/**
|
|
* Enhanced test console output that captures all output for assertions
|
|
*/
|
|
final class TestConsoleOutput implements ConsoleOutputInterface
|
|
{
|
|
public array $capturedLines = [];
|
|
|
|
public array $capturedWrites = [];
|
|
|
|
public array $capturedErrors = [];
|
|
|
|
public array $capturedSuccesses = [];
|
|
|
|
public array $capturedWarnings = [];
|
|
|
|
public array $capturedInfos = [];
|
|
|
|
public int $newLineCount = 0;
|
|
|
|
public array $windowTitles = [];
|
|
|
|
public function write(string $message, ConsoleStyle|ConsoleColor|null $style = null): void
|
|
{
|
|
$this->capturedWrites[] = ['message' => $message, 'style' => $style];
|
|
}
|
|
|
|
public function writeLine(string $message = '', ?ConsoleColor $color = null): void
|
|
{
|
|
$this->capturedLines[] = ['message' => $message, 'color' => $color];
|
|
}
|
|
|
|
public function writeError(string $message): void
|
|
{
|
|
$this->capturedErrors[] = $message;
|
|
$this->capturedLines[] = ['message' => $message, 'type' => 'error'];
|
|
}
|
|
|
|
public function writeSuccess(string $message): void
|
|
{
|
|
$this->capturedSuccesses[] = $message;
|
|
$this->capturedLines[] = ['message' => $message, 'type' => 'success'];
|
|
}
|
|
|
|
public function writeWarning(string $message): void
|
|
{
|
|
$this->capturedWarnings[] = $message;
|
|
$this->capturedLines[] = ['message' => $message, 'type' => 'warning'];
|
|
}
|
|
|
|
public function writeInfo(string $message): void
|
|
{
|
|
$this->capturedInfos[] = $message;
|
|
$this->capturedLines[] = ['message' => $message, 'type' => 'info'];
|
|
}
|
|
|
|
public function newLine(int $count = 1): void
|
|
{
|
|
$this->newLineCount += $count;
|
|
for ($i = 0; $i < $count; $i++) {
|
|
$this->capturedLines[] = ['message' => '', 'type' => 'newline'];
|
|
}
|
|
}
|
|
|
|
public function askQuestion(string $question, ?string $default = null): string
|
|
{
|
|
$this->capturedLines[] = ['message' => $question, 'type' => 'question', 'default' => $default];
|
|
return $default ?? '';
|
|
}
|
|
|
|
public function confirm(string $question, bool $default = false): bool
|
|
{
|
|
$this->capturedLines[] = ['message' => $question, 'type' => 'confirm', 'default' => $default];
|
|
return $default;
|
|
}
|
|
|
|
public function writeWindowTitle(string $title, int $mode = 0): void
|
|
{
|
|
$this->windowTitles[] = ['title' => $title, 'mode' => $mode];
|
|
}
|
|
|
|
/**
|
|
* Get all captured output as plain text
|
|
*/
|
|
public function getOutput(): string
|
|
{
|
|
$output = [];
|
|
foreach ($this->capturedLines as $line) {
|
|
$output[] = $line['message'] ?? '';
|
|
}
|
|
|
|
return implode("\n", $output);
|
|
}
|
|
|
|
/**
|
|
* Get all captured writes
|
|
*/
|
|
public function getWrites(): array
|
|
{
|
|
return $this->capturedWrites;
|
|
}
|
|
|
|
/**
|
|
* Clear all captured output
|
|
*/
|
|
public function clear(): void
|
|
{
|
|
$this->capturedLines = [];
|
|
$this->capturedWrites = [];
|
|
$this->capturedErrors = [];
|
|
$this->capturedSuccesses = [];
|
|
$this->capturedWarnings = [];
|
|
$this->capturedInfos = [];
|
|
$this->newLineCount = 0;
|
|
$this->windowTitles = [];
|
|
}
|
|
|
|
/**
|
|
* Check if output contains a specific string
|
|
*/
|
|
public function contains(string $search): bool
|
|
{
|
|
$output = $this->getOutput();
|
|
return str_contains($output, $search);
|
|
}
|
|
|
|
/**
|
|
* Get last captured line
|
|
*/
|
|
public function getLastLine(): ?string
|
|
{
|
|
if (empty($this->capturedLines)) {
|
|
return null;
|
|
}
|
|
|
|
$last = end($this->capturedLines);
|
|
return $last['message'] ?? null;
|
|
}
|
|
}
|
|
|