Skip to content

Commit

Permalink
[11.x] Add Prompts textarea fallback for tests and add assertion te…
Browse files Browse the repository at this point in the history
…sts (#51055)

* add textarea fallback

* add text and textarea assertion tests

* add input tests

* add tests

* add multiselect test

* add select test

* update composer.json

* styles

* Use multiline fallback

* Formatting

---------

Co-authored-by: Jess Archer <[email protected]>
  • Loading branch information
lioneaglesolutions and jessarcher authored Apr 15, 2024
1 parent 21d7ad9 commit 61716c9
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 3 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"fruitcake/php-cors": "^1.3",
"guzzlehttp/guzzle": "^7.8",
"guzzlehttp/uri-template": "^1.0",
"laravel/prompts": "^0.1.15",
"laravel/prompts": "^0.1.18",
"laravel/serializable-closure": "^1.3",
"league/commonmark": "^2.2.1",
"league/flysystem": "^3.8.0",
Expand Down
7 changes: 7 additions & 0 deletions src/Illuminate/Console/Concerns/ConfiguresPrompts.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Laravel\Prompts\SearchPrompt;
use Laravel\Prompts\SelectPrompt;
use Laravel\Prompts\SuggestPrompt;
use Laravel\Prompts\TextareaPrompt;
use Laravel\Prompts\TextPrompt;
use stdClass;
use Symfony\Component\Console\Input\InputInterface;
Expand Down Expand Up @@ -40,6 +41,12 @@ protected function configurePrompts(InputInterface $input)
$prompt->validate
));

TextareaPrompt::fallbackUsing(fn (TextareaPrompt $prompt) => $this->promptUntilValid(
fn () => $this->components->ask($prompt->label, $prompt->default ?: null, multiline: true) ?? '',
$prompt->required,
$prompt->validate
));

PasswordPrompt::fallbackUsing(fn (PasswordPrompt $prompt) => $this->promptUntilValid(
fn () => $this->components->secret($prompt->label) ?? '',
$prompt->required,
Expand Down
11 changes: 9 additions & 2 deletions src/Illuminate/Console/View/Components/Ask.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Illuminate\Console\View\Components;

use Symfony\Component\Console\Question\Question;

class Ask extends Component
{
/**
Expand All @@ -11,8 +13,13 @@ class Ask extends Component
* @param string $default
* @return mixed
*/
public function render($question, $default = null)
public function render($question, $default = null, $multiline = false)
{
return $this->usingQuestionHelper(fn () => $this->output->ask($question, $default));
return $this->usingQuestionHelper(
fn () => $this->output->askQuestion(
(new Question($question, $default))
->setMultiline($multiline)
)
);
}
}
165 changes: 165 additions & 0 deletions tests/Integration/Console/PromptsAssertionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
<?php

namespace Illuminate\Tests\Integration\Console;

use Illuminate\Console\Command;
use Illuminate\Contracts\Console\Kernel;
use Orchestra\Testbench\TestCase;

use function Laravel\Prompts\confirm;
use function Laravel\Prompts\multiselect;
use function Laravel\Prompts\password;
use function Laravel\Prompts\select;
use function Laravel\Prompts\text;
use function Laravel\Prompts\textarea;

class PromptsAssertionTest extends TestCase
{
public function testAssertionForTextPrompt()
{
$this->app[Kernel::class]->registerCommand(
new class extends Command
{
protected $signature = 'test:text';

public function handle()
{
$name = text('What is your name?', 'John');

$this->line($name);
}
}
);

$this
->artisan('test:text')
->expectsQuestion('What is your name?', 'Jane')
->expectsOutput('Jane');
}

public function testAssertionForTextareaPrompt()
{
$this->app[Kernel::class]->registerCommand(
new class extends Command
{
protected $signature = 'test:textarea';

public function handle()
{
$name = textarea('What is your name?', 'John');

$this->line($name);
}
}
);

$this
->artisan('test:textarea')
->expectsQuestion('What is your name?', 'Jane')
->expectsOutput('Jane');
}

public function testAssertionForPasswordPrompt()
{
$this->app[Kernel::class]->registerCommand(
new class extends Command
{
protected $signature = 'test:password';

public function handle()
{
$name = password('What is your password?');

$this->line($name);
}
}
);

$this
->artisan('test:password')
->expectsQuestion('What is your password?', 'secret')
->expectsOutput('secret');
}

public function testAssertionForConfirmPrompt()
{
$this->app[Kernel::class]->registerCommand(
new class extends Command
{
protected $signature = 'test:confirm';

public function handle()
{
$confirmed = confirm('Is your name John?');

if ($confirmed) {
$this->line('Your name is John.');
} else {
$this->line('Your name is not John.');
}
}
}
);

$this
->artisan('test:confirm')
->expectsConfirmation('Is your name John?', 'no')
->expectsOutput('Your name is not John.');

$this
->artisan('test:confirm')
->expectsConfirmation('Is your name John?', 'yes')
->expectsOutput('Your name is John.');
}

public function testAssertionForSelectPrompt()
{
$this->app[Kernel::class]->registerCommand(
new class extends Command
{
protected $signature = 'test:select';

public function handle()
{
$name = select(
label: 'What is your name?',
options: ['John', 'Jane']
);

$this->line("Your name is $name.");
}
}
);

$this
->artisan('test:select')
->expectsChoice('What is your name?', 'Jane', ['John', 'Jane'])
->expectsOutput('Your name is Jane.');
}

public function testAssertionForRequiredMultiselectPrompt()
{
$this->app[Kernel::class]->registerCommand(
new class extends Command
{
protected $signature = 'test:multiselect';

public function handle()
{
$names = multiselect(
label: 'Which names do you like?',
options: ['John', 'Jane', 'Sally', 'Jack'],
required: true
);

$this->line(sprintf('You like %s.', implode(', ', $names)));
}
}
);

$this
->artisan('test:multiselect')
->expectsChoice('Which names do you like?', ['John', 'Jane'], ['John', 'Jane', 'Sally', 'Jack'])
->expectsOutput('You like John, Jane.');
}
}

0 comments on commit 61716c9

Please sign in to comment.