diff --git a/Tester/ApplicationTester.php b/Tester/ApplicationTester.php index a6dc8e1c..5b1aeab4 100644 --- a/Tester/ApplicationTester.php +++ b/Tester/ApplicationTester.php @@ -58,6 +58,28 @@ class ApplicationTester $this->initOutput($options); - return $this->statusCode = $this->application->run($this->input, $this->output); + // Temporarily clear SHELL_VERBOSITY to prevent Application::configureIO + // from overriding the interactive and verbosity settings set above + $prevShellVerbosity = [getenv('SHELL_VERBOSITY'), $_ENV['SHELL_VERBOSITY'] ?? false, $_SERVER['SHELL_VERBOSITY'] ?? false]; + if (\function_exists('putenv')) { + @putenv('SHELL_VERBOSITY'); + } + unset($_ENV['SHELL_VERBOSITY'], $_SERVER['SHELL_VERBOSITY']); + + try { + return $this->statusCode = $this->application->run($this->input, $this->output); + } finally { + if (false !== $prevShellVerbosity[0]) { + if (\function_exists('putenv')) { + @putenv('SHELL_VERBOSITY='.$prevShellVerbosity[0]); + } + } + if (false !== $prevShellVerbosity[1]) { + $_ENV['SHELL_VERBOSITY'] = $prevShellVerbosity[1]; + } + if (false !== $prevShellVerbosity[2]) { + $_SERVER['SHELL_VERBOSITY'] = $prevShellVerbosity[2]; + } + } } } diff --git a/Tests/Tester/ApplicationTesterTest.php b/Tests/Tester/ApplicationTesterTest.php index f8994cad..d9b25a35 100644 --- a/Tests/Tester/ApplicationTesterTest.php +++ b/Tests/Tester/ApplicationTesterTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Console\Tests\Tester; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Application; use Symfony\Component\Console\Helper\QuestionHelper; @@ -91,6 +92,46 @@ class ApplicationTesterTest extends TestCase $this->tester->assertCommandIsSuccessful('->getStatusCode() returns the status code'); } + #[DataProvider('provideShellVerbositySources')] + public function testShellVerbosityDoesNotOverrideInteractiveAndVerbosity(callable $setShellVerbosity, callable $cleanUp) + { + $setShellVerbosity(); + + try { + $application = new Application(); + $application->setAutoExit(false); + $application->register('foo') + ->setCode(static function ($input, $output) { + $output->writeln('foo'); + }) + ; + + $tester = new ApplicationTester($application); + $tester->run(['command' => 'foo'], ['interactive' => true]); + + $this->assertTrue($tester->getInput()->isInteractive()); + $this->assertSame('foo'.\PHP_EOL, $tester->getDisplay()); + } finally { + $cleanUp(); + } + } + + public static function provideShellVerbositySources(): iterable + { + yield 'putenv' => [ + static function () { putenv('SHELL_VERBOSITY=-1'); }, + static function () { putenv('SHELL_VERBOSITY'); }, + ]; + yield '$_ENV' => [ + static function () { $_ENV['SHELL_VERBOSITY'] = '-1'; }, + static function () { unset($_ENV['SHELL_VERBOSITY']); }, + ]; + yield '$_SERVER' => [ + static function () { $_SERVER['SHELL_VERBOSITY'] = '-1'; }, + static function () { unset($_SERVER['SHELL_VERBOSITY']); }, + ]; + } + public function testErrorOutput() { $application = new Application();