Skip to content

Commit

Permalink
Merge pull request #8873 from kenjis/fix-CLI-user-input
Browse files Browse the repository at this point in the history
fix: CLI::promptByMultipleKeys() and prompt()
  • Loading branch information
kenjis authored May 13, 2024
2 parents 6ceb3e5 + e772b9d commit c7c4eb4
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 9 deletions.
2 changes: 1 addition & 1 deletion phpstan-baseline.php
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@
];
$ignoreErrors[] = [
'message' => '#^Short ternary operator is not allowed\\. Use null coalesce operator if applicable or consider using long ternary\\.$#',
'count' => 5,
'count' => 2,
'path' => __DIR__ . '/system/CLI/CLI.php',
];
$ignoreErrors[] = [
Expand Down
17 changes: 11 additions & 6 deletions system/CLI/CLI.php
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,8 @@ public static function prompt(string $field, $options = null, $validation = null
static::fwrite(STDOUT, $field . (trim($field) !== '' ? ' ' : '') . $extraOutput . ': ');

// Read the input from keyboard.
$input = trim(static::$io->input()) ?: (string) $default;
$input = trim(static::$io->input());
$input = ($input === '') ? (string) $default : $input;

if ($validation !== []) {
while (! static::validate('"' . trim($field) . '"', $input, $validation)) {
Expand Down Expand Up @@ -330,7 +331,9 @@ public static function promptByMultipleKeys(string $text, array $options): array
CLI::write($text);
CLI::printKeysAndValues($options);
CLI::newLine();
$input = static::prompt($extraOutput) ?: 0; // 0 is default

$input = static::prompt($extraOutput);
$input = ($input === '') ? '0' : $input; // 0 is default

// validation
while (true) {
Expand All @@ -343,13 +346,15 @@ public static function promptByMultipleKeys(string $text, array $options): array
// find max from input
$maxInput = max($inputToArray);

// return the prompt again if $input contain(s) non-numeric charachter, except a comma.
// And if max from $options less than max from input
// it is mean user tried to access null value in $options
// return the prompt again if $input contain(s) non-numeric character, except a comma.
// And if max from $options less than max from input,
// it means user tried to access null value in $options
if (! $pattern || $maxOptions < $maxInput) {
static::error('Please select correctly.');
CLI::newLine();
$input = static::prompt($extraOutput) ?: 0;

$input = static::prompt($extraOutput);
$input = ($input === '') ? '0' : $input;
} else {
break;
}
Expand Down
113 changes: 111 additions & 2 deletions tests/system/CLI/CLITest.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ public function testWaitZero(): void
$time = time();
CLI::wait(0);

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

PhpStreamWrapper::restore();

$this->assertCloseEnough(0, time() - $time);
}

public function testPrompt(): void
Expand All @@ -90,9 +90,83 @@ public function testPrompt(): void

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

PhpStreamWrapper::restore();

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

public function testPromptInputNothing(): void
{
PhpStreamWrapper::register();

$input = '';
PhpStreamWrapper::setContent($input);

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

PhpStreamWrapper::restore();

$this->assertSame('red', $output);
}

public function testPromptInputZero(): void
{
PhpStreamWrapper::register();

$input = '0';
PhpStreamWrapper::setContent($input);

$output = CLI::prompt('What is your favorite number?', '7');

PhpStreamWrapper::restore();

$this->assertSame('0', $output);
}

public function testPromptByKey(): void
{
PhpStreamWrapper::register();

$input = '1';
PhpStreamWrapper::setContent($input);

$options = ['Playing game', 'Sleep', 'Badminton'];
$output = CLI::promptByKey('Select your hobbies:', $options);

PhpStreamWrapper::restore();

$this->assertSame($input, $output);
}

public function testPromptByKeyInputNothing(): void
{
PhpStreamWrapper::register();

$input = ''; // This is when you press the Enter key.
PhpStreamWrapper::setContent($input);

$options = ['Playing game', 'Sleep', 'Badminton'];
$output = CLI::promptByKey('Select your hobbies:', $options);

PhpStreamWrapper::restore();

$expected = '0';
$this->assertSame($expected, $output);
}

public function testPromptByKeyInputZero(): void
{
PhpStreamWrapper::register();

$input = '0';
PhpStreamWrapper::setContent($input);

$options = ['Playing game', 'Sleep', 'Badminton'];
$output = CLI::promptByKey('Select your hobbies:', $options);

PhpStreamWrapper::restore();

$this->assertSame($input, $output);
}

public function testPromptByMultipleKeys(): void
Expand All @@ -105,14 +179,49 @@ public function testPromptByMultipleKeys(): void
$options = ['Playing game', 'Sleep', 'Badminton'];
$output = CLI::promptByMultipleKeys('Select your hobbies:', $options);

PhpStreamWrapper::restore();

$expected = [
0 => 'Playing game',
1 => 'Sleep',
];
$this->assertSame($expected, $output);
}

public function testPromptByMultipleKeysInputNothing(): void
{
PhpStreamWrapper::register();

$input = ''; // This is when you press the Enter key.
PhpStreamWrapper::setContent($input);

$options = ['Playing game', 'Sleep', 'Badminton'];
$output = CLI::promptByMultipleKeys('Select your hobbies:', $options);

PhpStreamWrapper::restore();

$expected = [
0 => 'Playing game',
];
$this->assertSame($expected, $output);
}

public function testPromptByMultipleKeysInputZero(): void
{
PhpStreamWrapper::register();

$input = '0';
PhpStreamWrapper::setContent($input);

$options = ['Playing game', 'Sleep', 'Badminton'];
$output = CLI::promptByMultipleKeys('Select your hobbies:', $options);

PhpStreamWrapper::restore();

$expected = [
0 => 'Playing game',
];
$this->assertSame($expected, $output);
}

public function testNewLine(): void
Expand Down

0 comments on commit c7c4eb4

Please sign in to comment.