From c3863861cfb219c2bfee6c5518424ab8e4758c65 Mon Sep 17 00:00:00 2001 From: Francisco Madeira Date: Mon, 14 Feb 2022 08:34:56 +0000 Subject: [PATCH 1/2] feat: Adds `expectsOutputToContain` to the `PendingCommand`. --- .../Testing/Concerns/InteractsWithConsole.php | 7 +++++ src/Illuminate/Testing/PendingCommand.php | 26 +++++++++++++++++++ .../Testing/ArtisanCommandTest.php | 23 ++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php index 38409d3d697f..aead281bc7bd 100644 --- a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php +++ b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php @@ -22,6 +22,13 @@ trait InteractsWithConsole */ public $expectedOutput = []; + /** + * All of the expected text to be present on the output. + * + * @var array + */ + public $expectedOutputToContain = []; + /** * All of the output lines that aren't expected to be displayed. * diff --git a/src/Illuminate/Testing/PendingCommand.php b/src/Illuminate/Testing/PendingCommand.php index 870108644336..1603319511c7 100644 --- a/src/Illuminate/Testing/PendingCommand.php +++ b/src/Illuminate/Testing/PendingCommand.php @@ -154,6 +154,19 @@ public function doesntExpectOutput($output) return $this; } + /** + * Specifies that a given text is present when the command runs. + * + * @param string $text + * @return $this + */ + public function expectsOutputToContain($text) + { + $this->test->expectedOutputToContain[] = $text; + + return $this; + } + /** * Specify a table that should be printed when the command runs. * @@ -311,6 +324,10 @@ protected function verifyExpectations() $this->test->fail('Output "'.Arr::first($this->test->expectedOutput).'" was not printed.'); } + if (count($this->test->expectedOutputToContain)) { + $this->test->fail('Output does not contain "'.Arr::first($this->test->expectedOutputToContain).'".'); + } + if ($output = array_search(true, $this->test->unexpectedOutput)) { $this->test->fail('Output "'.$output.'" was printed.'); } @@ -373,6 +390,14 @@ private function createABufferedOutputMock() }); } + foreach ($this->test->expectedOutputToContain as $i => $text) { + $mock->shouldReceive('doWrite') + ->withArgs(fn ($output) => str_contains($output, $text)) + ->andReturnUsing(function () use ($i) { + unset($this->test->expectedOutputToContain[$i]); + }); + } + foreach ($this->test->unexpectedOutput as $output => $displayed) { $mock->shouldReceive('doWrite') ->ordered() @@ -393,6 +418,7 @@ private function createABufferedOutputMock() protected function flushExpectations() { $this->test->expectedOutput = []; + $this->test->expectedOutputToContain = []; $this->test->unexpectedOutput = []; $this->test->expectedTables = []; $this->test->expectedQuestions = []; diff --git a/tests/Integration/Testing/ArtisanCommandTest.php b/tests/Integration/Testing/ArtisanCommandTest.php index 82e827732597..23f1f3a4fcfc 100644 --- a/tests/Integration/Testing/ArtisanCommandTest.php +++ b/tests/Integration/Testing/ArtisanCommandTest.php @@ -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() @@ -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. From 013659f8d84a7368dab75066b81132aa22cef461 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Wed, 16 Feb 2022 12:54:45 -0600 Subject: [PATCH 2/2] formatting --- .../Testing/Concerns/InteractsWithConsole.php | 2 +- src/Illuminate/Testing/PendingCommand.php | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php index aead281bc7bd..9f8fbcc88f73 100644 --- a/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php +++ b/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php @@ -27,7 +27,7 @@ trait InteractsWithConsole * * @var array */ - public $expectedOutputToContain = []; + public $expectedOutputSubstrings = []; /** * All of the output lines that aren't expected to be displayed. diff --git a/src/Illuminate/Testing/PendingCommand.php b/src/Illuminate/Testing/PendingCommand.php index 1603319511c7..496215fa4aa1 100644 --- a/src/Illuminate/Testing/PendingCommand.php +++ b/src/Illuminate/Testing/PendingCommand.php @@ -155,14 +155,14 @@ public function doesntExpectOutput($output) } /** - * Specifies that a given text is present when the command runs. + * Specify that the given string should be contained in the command output. * - * @param string $text + * @param string $string * @return $this */ - public function expectsOutputToContain($text) + public function expectsOutputToContain($string) { - $this->test->expectedOutputToContain[] = $text; + $this->test->expectedOutputSubstrings[] = $string; return $this; } @@ -324,8 +324,8 @@ protected function verifyExpectations() $this->test->fail('Output "'.Arr::first($this->test->expectedOutput).'" was not printed.'); } - if (count($this->test->expectedOutputToContain)) { - $this->test->fail('Output does not contain "'.Arr::first($this->test->expectedOutputToContain).'".'); + 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)) { @@ -390,11 +390,11 @@ private function createABufferedOutputMock() }); } - foreach ($this->test->expectedOutputToContain as $i => $text) { + foreach ($this->test->expectedOutputSubstrings as $i => $text) { $mock->shouldReceive('doWrite') ->withArgs(fn ($output) => str_contains($output, $text)) ->andReturnUsing(function () use ($i) { - unset($this->test->expectedOutputToContain[$i]); + unset($this->test->expectedOutputSubstrings[$i]); }); } @@ -418,7 +418,7 @@ private function createABufferedOutputMock() protected function flushExpectations() { $this->test->expectedOutput = []; - $this->test->expectedOutputToContain = []; + $this->test->expectedOutputSubstrings = []; $this->test->unexpectedOutput = []; $this->test->expectedTables = []; $this->test->expectedQuestions = [];