Files
michaelschiemer/tests/Framework/Console/Helpers/MockStdin.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

129 lines
2.6 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Framework\Console\Helpers;
/**
* Mock STDIN for testing interactive console components
*/
final class MockStdin
{
private array $inputs = [];
private int $currentIndex = 0;
private ?resource $originalStdin = null;
private bool $isActive = false;
public function __construct(array $inputs = [])
{
$this->inputs = $inputs;
}
/**
* Add input to the queue
*/
public function addInput(string $input): self
{
$this->inputs[] = $input;
return $this;
}
/**
* Add multiple inputs
*/
public function addInputs(array $inputs): self
{
foreach ($inputs as $input) {
$this->addInput($input);
}
return $this;
}
/**
* Activate the mock (replace STDIN)
*/
public function activate(): void
{
if ($this->isActive) {
return;
}
// Create a temporary file for input
$tempFile = tmpfile();
if ($tempFile === false) {
throw new \RuntimeException('Could not create temporary file for STDIN mock');
}
// Write all inputs to the temp file
$content = implode("\n", $this->inputs) . "\n";
fwrite($tempFile, $content);
rewind($tempFile);
// Store original STDIN if we can
if (defined('STDIN') && is_resource(STDIN)) {
$this->originalStdin = STDIN;
}
// Replace STDIN constant (not possible in PHP, so we use a workaround)
// We'll need to use a different approach - create a stream wrapper
$this->isActive = true;
}
/**
* Deactivate the mock (restore original STDIN)
*/
public function deactivate(): void
{
if (!$this->isActive) {
return;
}
$this->isActive = false;
}
/**
* Get next input (simulates fgets)
*/
public function getNextInput(): ?string
{
if ($this->currentIndex >= count($this->inputs)) {
return null;
}
$input = $this->inputs[$this->currentIndex];
$this->currentIndex++;
return $input . "\n";
}
/**
* Reset to beginning
*/
public function reset(): void
{
$this->currentIndex = 0;
}
/**
* Check if there are more inputs
*/
public function hasMoreInputs(): bool
{
return $this->currentIndex < count($this->inputs);
}
/**
* Get all remaining inputs
*/
public function getRemainingInputs(): array
{
return array_slice($this->inputs, $this->currentIndex);
}
}