Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bin/phunkie
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ use function Phunkie\Console\Functions\{setColors, printBanner, loadHistory, sav

if (isset($args[1]) && !str_starts_with($args[1], '-')) {
$className = $args[1];

if (class_exists($className) && is_subclass_of($className, IOApp::class)) {
$app = new $className();
}
Expand Down
93 changes: 81 additions & 12 deletions tests/Acceptance/ReplSteps.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,33 @@ public function __construct()

private function startRepl(string $command = 'php bin/phunkie'): void
{
if ($command !== 'php bin/phunkie' && $command !== 'php bin/phunkie -c') {
$isIOAppCommand = $command !== 'php bin/phunkie' && $command !== 'php bin/phunkie -c';

if ($isIOAppCommand) {
// Non-standard command means we need to test the actual process
$this->useProcessManager = true;
}

if ($this->useProcessManager) {
$this->processManager->start($command);
$stdout = $this->processManager->getStdout();
if ($stdout !== null) {
$newOutput = ReplOutputReader::readOutput($stdout);
$this->output .= $newOutput;
}
// Also capture stderr for debugging
$stderr = $this->processManager->getStderr();
if ($stderr !== null) {
$errorOutput = ReplOutputReader::readOutput($stderr);
if ($errorOutput !== '') {
$this->output .= "\n[STDERR]: " . $errorOutput;

if ($isIOAppCommand) {
// For IOApp commands, wait for the process to complete and capture all output
$this->waitForProcessAndCaptureOutput();
} else {
// For REPL mode, read available output
$stdout = $this->processManager->getStdout();
if ($stdout !== null) {
$newOutput = ReplOutputReader::readOutput($stdout);
$this->output .= $newOutput;
}
// Also capture stderr for debugging
$stderr = $this->processManager->getStderr();
if ($stderr !== null) {
$errorOutput = ReplOutputReader::readOutput($stderr);
if ($errorOutput !== '') {
$this->output .= "\n[STDERR]: " . $errorOutput;
}
}
}
} else {
Expand All @@ -71,6 +80,66 @@ private function startRepl(string $command = 'php bin/phunkie'): void
}
}

private function waitForProcessAndCaptureOutput(): void
{
$stdout = $this->processManager->getStdout();
$stderr = $this->processManager->getStderr();

// Wait for the process to complete (up to 5 seconds)
$maxWait = 5.0;
$startTime = microtime(true);

while ((microtime(true) - $startTime) < $maxWait) {
// Read any available stdout
if ($stdout !== null) {
$read = [$stdout];
$write = null;
$except = null;
if (stream_select($read, $write, $except, 0, 100000) > 0) { // 100ms timeout
$chunk = stream_get_contents($stdout);
if ($chunk !== false && $chunk !== '') {
$this->output .= $chunk;
}
}
}

// Read any available stderr
if ($stderr !== null) {
$read = [$stderr];
$write = null;
$except = null;
if (stream_select($read, $write, $except, 0, 10000) > 0) { // 10ms timeout
$chunk = stream_get_contents($stderr);
if ($chunk !== false && $chunk !== '') {
$this->output .= "\n[STDERR]: " . $chunk;
}
}
}

// Check if process has exited
$status = $this->processManager->getStatus();
if ($status !== null && !$status['running']) {
// Process has exited, read any remaining output
usleep(50000); // 50ms grace period for buffered output
if ($stdout !== null) {
$remaining = stream_get_contents($stdout);
if ($remaining !== false && $remaining !== '') {
$this->output .= $remaining;
}
}
if ($stderr !== null) {
$remaining = stream_get_contents($stderr);
if ($remaining !== false && $remaining !== '') {
$this->output .= "\n[STDERR]: " . $remaining;
}
}
break;
}

usleep(10000); // 10ms sleep between checks
}
}

private function sendInput(string $input): void
{
// Check if input defines a class/function/trait/interface/enum
Expand Down
8 changes: 8 additions & 0 deletions tests/Acceptance/Support/ReplProcessManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ public function isRunning(): bool
return $this->process !== null;
}

public function getStatus(): ?array
{
if ($this->process === null) {
return null;
}
return proc_get_status($this->process);
}

public function terminate(): void
{
if ($this->process !== null) {
Expand Down