Skip to content

Commit c7c4eb4

Browse files
authored
Merge pull request #8873 from kenjis/fix-CLI-user-input
fix: CLI::promptByMultipleKeys() and prompt()
2 parents 6ceb3e5 + e772b9d commit c7c4eb4

File tree

3 files changed

+123
-9
lines changed

3 files changed

+123
-9
lines changed

phpstan-baseline.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@
378378
];
379379
$ignoreErrors[] = [
380380
'message' => '#^Short ternary operator is not allowed\\. Use null coalesce operator if applicable or consider using long ternary\\.$#',
381-
'count' => 5,
381+
'count' => 2,
382382
'path' => __DIR__ . '/system/CLI/CLI.php',
383383
];
384384
$ignoreErrors[] = [

system/CLI/CLI.php

+11-6
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,8 @@ public static function prompt(string $field, $options = null, $validation = null
258258
static::fwrite(STDOUT, $field . (trim($field) !== '' ? ' ' : '') . $extraOutput . ': ');
259259

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

263264
if ($validation !== []) {
264265
while (! static::validate('"' . trim($field) . '"', $input, $validation)) {
@@ -330,7 +331,9 @@ public static function promptByMultipleKeys(string $text, array $options): array
330331
CLI::write($text);
331332
CLI::printKeysAndValues($options);
332333
CLI::newLine();
333-
$input = static::prompt($extraOutput) ?: 0; // 0 is default
334+
335+
$input = static::prompt($extraOutput);
336+
$input = ($input === '') ? '0' : $input; // 0 is default
334337

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

346-
// return the prompt again if $input contain(s) non-numeric charachter, except a comma.
347-
// And if max from $options less than max from input
348-
// it is mean user tried to access null value in $options
349+
// return the prompt again if $input contain(s) non-numeric character, except a comma.
350+
// And if max from $options less than max from input,
351+
// it means user tried to access null value in $options
349352
if (! $pattern || $maxOptions < $maxInput) {
350353
static::error('Please select correctly.');
351354
CLI::newLine();
352-
$input = static::prompt($extraOutput) ?: 0;
355+
356+
$input = static::prompt($extraOutput);
357+
$input = ($input === '') ? '0' : $input;
353358
} else {
354359
break;
355360
}

tests/system/CLI/CLITest.php

+111-2
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ public function testWaitZero(): void
7676
$time = time();
7777
CLI::wait(0);
7878

79-
$this->assertCloseEnough(0, time() - $time);
80-
8179
PhpStreamWrapper::restore();
80+
81+
$this->assertCloseEnough(0, time() - $time);
8282
}
8383

8484
public function testPrompt(): void
@@ -90,9 +90,83 @@ public function testPrompt(): void
9090

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

93+
PhpStreamWrapper::restore();
94+
9395
$this->assertSame($expected, $output);
96+
}
97+
98+
public function testPromptInputNothing(): void
99+
{
100+
PhpStreamWrapper::register();
101+
102+
$input = '';
103+
PhpStreamWrapper::setContent($input);
104+
105+
$output = CLI::prompt('What is your favorite color?', 'red');
94106

95107
PhpStreamWrapper::restore();
108+
109+
$this->assertSame('red', $output);
110+
}
111+
112+
public function testPromptInputZero(): void
113+
{
114+
PhpStreamWrapper::register();
115+
116+
$input = '0';
117+
PhpStreamWrapper::setContent($input);
118+
119+
$output = CLI::prompt('What is your favorite number?', '7');
120+
121+
PhpStreamWrapper::restore();
122+
123+
$this->assertSame('0', $output);
124+
}
125+
126+
public function testPromptByKey(): void
127+
{
128+
PhpStreamWrapper::register();
129+
130+
$input = '1';
131+
PhpStreamWrapper::setContent($input);
132+
133+
$options = ['Playing game', 'Sleep', 'Badminton'];
134+
$output = CLI::promptByKey('Select your hobbies:', $options);
135+
136+
PhpStreamWrapper::restore();
137+
138+
$this->assertSame($input, $output);
139+
}
140+
141+
public function testPromptByKeyInputNothing(): void
142+
{
143+
PhpStreamWrapper::register();
144+
145+
$input = ''; // This is when you press the Enter key.
146+
PhpStreamWrapper::setContent($input);
147+
148+
$options = ['Playing game', 'Sleep', 'Badminton'];
149+
$output = CLI::promptByKey('Select your hobbies:', $options);
150+
151+
PhpStreamWrapper::restore();
152+
153+
$expected = '0';
154+
$this->assertSame($expected, $output);
155+
}
156+
157+
public function testPromptByKeyInputZero(): void
158+
{
159+
PhpStreamWrapper::register();
160+
161+
$input = '0';
162+
PhpStreamWrapper::setContent($input);
163+
164+
$options = ['Playing game', 'Sleep', 'Badminton'];
165+
$output = CLI::promptByKey('Select your hobbies:', $options);
166+
167+
PhpStreamWrapper::restore();
168+
169+
$this->assertSame($input, $output);
96170
}
97171

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

182+
PhpStreamWrapper::restore();
183+
108184
$expected = [
109185
0 => 'Playing game',
110186
1 => 'Sleep',
111187
];
188+
$this->assertSame($expected, $output);
189+
}
190+
191+
public function testPromptByMultipleKeysInputNothing(): void
192+
{
193+
PhpStreamWrapper::register();
194+
195+
$input = ''; // This is when you press the Enter key.
196+
PhpStreamWrapper::setContent($input);
112197

198+
$options = ['Playing game', 'Sleep', 'Badminton'];
199+
$output = CLI::promptByMultipleKeys('Select your hobbies:', $options);
200+
201+
PhpStreamWrapper::restore();
202+
203+
$expected = [
204+
0 => 'Playing game',
205+
];
113206
$this->assertSame($expected, $output);
207+
}
208+
209+
public function testPromptByMultipleKeysInputZero(): void
210+
{
211+
PhpStreamWrapper::register();
212+
213+
$input = '0';
214+
PhpStreamWrapper::setContent($input);
215+
216+
$options = ['Playing game', 'Sleep', 'Badminton'];
217+
$output = CLI::promptByMultipleKeys('Select your hobbies:', $options);
114218

115219
PhpStreamWrapper::restore();
220+
221+
$expected = [
222+
0 => 'Playing game',
223+
];
224+
$this->assertSame($expected, $output);
116225
}
117226

118227
public function testNewLine(): void

0 commit comments

Comments
 (0)