Skip to content

Commit

Permalink
[9.x] Adds expectsOutputToContain to the PendingCommand. (#40984)
Browse files Browse the repository at this point in the history
* feat: Adds `expectsOutputToContain` to the `PendingCommand`.

* formatting

Co-authored-by: Taylor Otwell <taylor@laravel.com>
  • Loading branch information
xiCO2k and taylorotwell authored Feb 16, 2022
1 parent bf90720 commit 35d9f9a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ trait InteractsWithConsole
*/
public $expectedOutput = [];

/**
* All of the expected text to be present on the output.
*
* @var array
*/
public $expectedOutputSubstrings = [];

/**
* All of the output lines that aren't expected to be displayed.
*
Expand Down
26 changes: 26 additions & 0 deletions src/Illuminate/Testing/PendingCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,19 @@ public function doesntExpectOutput($output)
return $this;
}

/**
* Specify that the given string should be contained in the command output.
*
* @param string $string
* @return $this
*/
public function expectsOutputToContain($string)
{
$this->test->expectedOutputSubstrings[] = $string;

return $this;
}

/**
* Specify a table that should be printed when the command runs.
*
Expand Down Expand Up @@ -311,6 +324,10 @@ protected function verifyExpectations()
$this->test->fail('Output "'.Arr::first($this->test->expectedOutput).'" was not printed.');
}

if (count($this->test->expectedOutputSubstrings)) {
$this->test->fail('Output does not contain "'.Arr::first($this->test->expectedOutputSubstrings).'".');
}

if ($output = array_search(true, $this->test->unexpectedOutput)) {
$this->test->fail('Output "'.$output.'" was printed.');
}
Expand Down Expand Up @@ -373,6 +390,14 @@ private function createABufferedOutputMock()
});
}

foreach ($this->test->expectedOutputSubstrings as $i => $text) {
$mock->shouldReceive('doWrite')
->withArgs(fn ($output) => str_contains($output, $text))
->andReturnUsing(function () use ($i) {
unset($this->test->expectedOutputSubstrings[$i]);
});
}

foreach ($this->test->unexpectedOutput as $output => $displayed) {
$mock->shouldReceive('doWrite')
->ordered()
Expand All @@ -393,6 +418,7 @@ private function createABufferedOutputMock()
protected function flushExpectations()
{
$this->test->expectedOutput = [];
$this->test->expectedOutputSubstrings = [];
$this->test->unexpectedOutput = [];
$this->test->expectedTables = [];
$this->test->expectedQuestions = [];
Expand Down
23 changes: 23 additions & 0 deletions tests/Integration/Testing/ArtisanCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ protected function setUp(): void
$this->line($this->ask('What?'));
$this->line($this->ask('Huh?'));
});

Artisan::command('contains', function () {
$this->line('My name is Taylor Otwell');
});
}

public function test_console_command_that_passes()
Expand Down Expand Up @@ -110,6 +114,25 @@ public function test_console_command_that_fails_from_unordered_output()
});
}

public function test_console_command_that_passes_if_the_output_contains()
{
$this->artisan('contains')
->expectsOutputToContain('Taylor Otwell')
->assertExitCode(0);
}

public function test_console_command_that_fails_if_the_output_does_not_contain()
{
$this->expectException(AssertionFailedError::class);
$this->expectExceptionMessage('Output does not contain "Otwell Taylor".');

$this->ignoringMockOnceExceptions(function () {
$this->artisan('contains')
->expectsOutputToContain('Otwell Taylor')
->assertExitCode(0);
});
}

/**
* Don't allow Mockery's InvalidCountException to be reported. Mocks setup
* in PendingCommand cause PHPUnit tearDown() to later throw the exception.
Expand Down

0 comments on commit 35d9f9a

Please sign in to comment.