Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
9 changes: 4 additions & 5 deletions system/CLI/CLI.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,18 +175,17 @@ public static function init()
* php index.php user -v --v -name=John --name=John
*
* @param string $prefix
*
* @codeCoverageIgnore
*/
public static function input(?string $prefix = null): string
{
if (static::$readline_support) {
return readline($prefix);
// readline() can't be tested.
if (static::$readline_support && ENVIRONMENT !== 'testing') {
return readline($prefix); // @codeCoverageIgnore
}

echo $prefix;

return fgets(STDIN);
return fgets(fopen('php://stdin', 'rb'));
Comment thread
kenjis marked this conversation as resolved.
}

/**
Expand Down
70 changes: 70 additions & 0 deletions system/Test/PhpStreamWrapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace CodeIgniter\Test;

/**
* StreamWrapper for php protocol
*
* This class is used for mocking `php://stdin`.
*
* See https://www.php.net/manual/en/class.streamwrapper.php
*/
class PhpStreamWrapper
Comment thread
kenjis marked this conversation as resolved.
Outdated
{
private static string $content = '';
private int $position = 0;

public static function setContent(string $content)
{
self::$content = $content;
}

public static function register()
{
stream_wrapper_unregister('php');
stream_wrapper_register('php', self::class);
}

public static function restore()
{
stream_wrapper_restore('php');
}

public function stream_open(string $path): bool
{
return true;
}

/**
* @return false|string
*/
public function stream_read(int $count)
{
$return = substr(self::$content, $this->position, $count);
$this->position += strlen($return);

return $return;
}

/**
* @return array|false
*/
public function stream_stat()
{
return [];
}

public function stream_eof(): bool
{
return $this->position >= strlen(self::$content);
}
}
43 changes: 28 additions & 15 deletions tests/system/CLI/CLITest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace CodeIgniter\CLI;

use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\PhpStreamWrapper;
use CodeIgniter\Test\StreamFilterTrait;
use ReflectionProperty;
use RuntimeException;
Expand Down Expand Up @@ -59,22 +60,34 @@ public function testWait()
$time = time();
CLI::wait(1);
$this->assertCloseEnough(1, time() - $time);
}

public function testWaitZero()
{
PhpStreamWrapper::register();
PhpStreamWrapper::setContent(' ');

// test the press any key to continue...
$time = time();
CLI::wait(0);

$this->assertSame(0, time() - $time);

PhpStreamWrapper::restore();
}

public function testPrompt()
{
PhpStreamWrapper::register();

$expected = 'red';
PhpStreamWrapper::setContent($expected);

$output = CLI::prompt('What is your favorite color?');

$this->assertSame($expected, $output);

// Leaving the code fragment below in, to remind myself (or others)
// of what appears to be the most likely path to test this last
// bit of wait() functionality.
// The problem: if the block below is enabled, the phpunit tests
// go catatonic when it is executed, presumably because of
// the CLI::input() waiting for a key press
//
// // test the press any key to continue...
// stream_filter_register('CLITestKeyboardFilter', 'CodeIgniter\CLI\CLITestKeyboardFilter');
// $spoofer = stream_filter_append(STDIN, 'CLITestKeyboardFilter');
// $time = time();
// CLITestKeyboardFilter::$spoofed = ' ';
// CLI::wait(0);
// stream_filter_remove($spoofer);
// $this->assertEquals(0, time() - $time);
PhpStreamWrapper::restore();
}

public function testIsWindows()
Expand Down