diff --git a/Descriptor/TextDescriptor.php b/Descriptor/TextDescriptor.php index ef6d8afe1..bde620bfa 100644 --- a/Descriptor/TextDescriptor.php +++ b/Descriptor/TextDescriptor.php @@ -212,7 +212,7 @@ protected function describeApplication(Application $application, array $options // calculate max. width based on available commands per namespace $width = $this->getColumnWidth(array_merge(...array_values(array_map(function ($namespace) use ($commands) { return array_intersect($namespace['commands'], array_keys($commands)); - }, $namespaces)))); + }, array_values($namespaces))))); if ($describedNamespace) { $this->writeText(sprintf('Available commands for the "%s" namespace:', $describedNamespace), $options); diff --git a/Helper/Table.php b/Helper/Table.php index 7f3d4a3b6..fee5a416b 100644 --- a/Helper/Table.php +++ b/Helper/Table.php @@ -562,6 +562,9 @@ private function buildTableRows(array $rows): TableRows if (0 === $lineKey) { $rows[$rowKey][$column] = $line; } else { + if (!\array_key_exists($rowKey, $unmergedRows) || !\array_key_exists($lineKey, $unmergedRows[$rowKey])) { + $unmergedRows[$rowKey][$lineKey] = $this->copyRow($rows, $rowKey); + } $unmergedRows[$rowKey][$lineKey][$column] = $line; } } @@ -573,8 +576,8 @@ private function buildTableRows(array $rows): TableRows yield $this->fillCells($row); if (isset($unmergedRows[$rowKey])) { - foreach ($unmergedRows[$rowKey] as $row) { - yield $row; + foreach ($unmergedRows[$rowKey] as $unmergedRow) { + yield $this->fillCells($unmergedRow); } } } @@ -658,6 +661,7 @@ private function fillNextRows(array $rows, int $line): array private function fillCells($row) { $newRow = []; + foreach ($row as $column => $cell) { $newRow[] = $cell; if ($cell instanceof TableCell && $cell->getColspan() > 1) { diff --git a/Tests/ApplicationTest.php b/Tests/ApplicationTest.php index a37031f4b..38b7bf76c 100644 --- a/Tests/ApplicationTest.php +++ b/Tests/ApplicationTest.php @@ -559,9 +559,9 @@ public function testFindAlternativeExceptionMessageMultiple() $this->fail('->find() throws a CommandNotFoundException if command does not exist, with alternatives'); } catch (\Exception $e) { $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); - $this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); - $this->assertRegExp('/foo1:bar/', $e->getMessage()); - $this->assertRegExp('/foo:bar/', $e->getMessage()); + $this->assertMatchesRegularExpression('/Did you mean one of these/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); + $this->assertMatchesRegularExpression('/foo1:bar/', $e->getMessage()); + $this->assertMatchesRegularExpression('/foo:bar/', $e->getMessage()); } // Namespace + plural @@ -570,8 +570,8 @@ public function testFindAlternativeExceptionMessageMultiple() $this->fail('->find() throws a CommandNotFoundException if command does not exist, with alternatives'); } catch (\Exception $e) { $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); - $this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); - $this->assertRegExp('/foo1/', $e->getMessage()); + $this->assertMatchesRegularExpression('/Did you mean one of these/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); + $this->assertMatchesRegularExpression('/foo1/', $e->getMessage()); } $application->add(new \Foo3Command()); @@ -583,8 +583,8 @@ public function testFindAlternativeExceptionMessageMultiple() $this->fail('->find() should throw an Symfony\Component\Console\Exception\CommandNotFoundException if a command is ambiguous because of a subnamespace, with alternatives'); } catch (\Exception $e) { $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e); - $this->assertRegExp('/foo3:bar/', $e->getMessage()); - $this->assertRegExp('/foo3:bar:toh/', $e->getMessage()); + $this->assertMatchesRegularExpression('/foo3:bar/', $e->getMessage()); + $this->assertMatchesRegularExpression('/foo3:bar:toh/', $e->getMessage()); } } @@ -613,10 +613,10 @@ public function testFindAlternativeCommands() } catch (\Exception $e) { $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist'); $this->assertSame(['afoobar1', 'foo:bar1'], $e->getAlternatives()); - $this->assertRegExp(sprintf('/Command "%s" is not defined./', $commandName), $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); - $this->assertRegExp('/afoobar1/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternative : "afoobar1"'); - $this->assertRegExp('/foo:bar1/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternative : "foo:bar1"'); - $this->assertNotRegExp('/foo:bar(?!1)/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, without "foo:bar" alternative'); + $this->assertMatchesRegularExpression(sprintf('/Command "%s" is not defined./', $commandName), $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); + $this->assertMatchesRegularExpression('/afoobar1/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternative : "afoobar1"'); + $this->assertMatchesRegularExpression('/foo:bar1/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternative : "foo:bar1"'); + $this->assertDoesNotMatchRegularExpression('/foo:bar(?!1)/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, without "foo:bar" alternative'); } } @@ -664,10 +664,10 @@ public function testFindAlternativeNamespace() $this->assertContains('foo', $e->getAlternatives()); $this->assertContains('foo1', $e->getAlternatives()); $this->assertContains('foo3', $e->getAlternatives()); - $this->assertRegExp('/There are no commands defined in the "foo2" namespace./', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative'); - $this->assertRegExp('/foo/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo"'); - $this->assertRegExp('/foo1/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo1"'); - $this->assertRegExp('/foo3/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo3"'); + $this->assertMatchesRegularExpression('/There are no commands defined in the "foo2" namespace./', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative'); + $this->assertMatchesRegularExpression('/foo/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo"'); + $this->assertMatchesRegularExpression('/foo1/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo1"'); + $this->assertMatchesRegularExpression('/foo3/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo3"'); } } @@ -698,7 +698,7 @@ public function testFindAlternativesOutput() $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command is not defined'); $this->assertSame($expectedAlternatives, $e->getAlternatives()); - $this->assertRegExp('/Command "foo" is not defined\..*Did you mean one of these\?.*/Ums', $e->getMessage()); + $this->assertMatchesRegularExpression('/Command "foo" is not defined\..*Did you mean one of these\?.*/Ums', $e->getMessage()); } } @@ -799,9 +799,9 @@ public function testRenderException() $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3.txt', $tester->getErrorOutput(true), '->renderException() renders a pretty exceptions with previous exceptions'); $tester->run(['command' => 'foo3:bar'], ['decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE]); - $this->assertRegExp('/\[Exception\]\s*First exception/', $tester->getDisplay(), '->renderException() renders a pretty exception without code exception when code exception is default and verbosity is verbose'); - $this->assertRegExp('/\[Exception\]\s*Second exception/', $tester->getDisplay(), '->renderException() renders a pretty exception without code exception when code exception is 0 and verbosity is verbose'); - $this->assertRegExp('/\[Exception \(404\)\]\s*Third exception/', $tester->getDisplay(), '->renderException() renders a pretty exception with code exception when code exception is 404 and verbosity is verbose'); + $this->assertMatchesRegularExpression('/\[Exception\]\s*First exception/', $tester->getDisplay(), '->renderException() renders a pretty exception without code exception when code exception is default and verbosity is verbose'); + $this->assertMatchesRegularExpression('/\[Exception\]\s*Second exception/', $tester->getDisplay(), '->renderException() renders a pretty exception without code exception when code exception is 0 and verbosity is verbose'); + $this->assertMatchesRegularExpression('/\[Exception \(404\)\]\s*Third exception/', $tester->getDisplay(), '->renderException() renders a pretty exception with code exception when code exception is 404 and verbosity is verbose'); $tester->run(['command' => 'foo3:bar'], ['decorated' => true]); $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3decorated.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions'); @@ -883,8 +883,7 @@ public function testRenderAnonymousException() $application = new Application(); $application->setAutoExit(false); $application->register('foo')->setCode(function () { - throw new class('') extends \InvalidArgumentException { - }; + throw new class('') extends \InvalidArgumentException { }; }); $tester = new ApplicationTester($application); @@ -894,8 +893,7 @@ public function testRenderAnonymousException() $application = new Application(); $application->setAutoExit(false); $application->register('foo')->setCode(function () { - throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', \get_class(new class() { - }))); + throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', \get_class(new class() { }))); }); $tester = new ApplicationTester($application); @@ -908,8 +906,7 @@ public function testRenderExceptionStackTraceContainsRootException() $application = new Application(); $application->setAutoExit(false); $application->register('foo')->setCode(function () { - throw new class('') extends \InvalidArgumentException { - }; + throw new class('') extends \InvalidArgumentException { }; }); $tester = new ApplicationTester($application); @@ -919,8 +916,7 @@ public function testRenderExceptionStackTraceContainsRootException() $application = new Application(); $application->setAutoExit(false); $application->register('foo')->setCode(function () { - throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', \get_class(new class() { - }))); + throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', \get_class(new class() { }))); }); $tester = new ApplicationTester($application); @@ -1448,8 +1444,8 @@ public function testErrorIsRethrownIfNotHandledByConsoleErrorEvent() $application->setCatchExceptions(false); $application->setDispatcher(new EventDispatcher()); - $application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) { - new \UnknownClass(); + $application->register('dym')->setCode(function () { + throw new \Error('Something went wrong.'); }); $tester = new ApplicationTester($application); @@ -1458,7 +1454,7 @@ public function testErrorIsRethrownIfNotHandledByConsoleErrorEvent() $tester->run(['command' => 'dym']); $this->fail('->run() should rethrow PHP errors if not handled via ConsoleErrorEvent.'); } catch (\Error $e) { - $this->assertSame($e->getMessage(), 'Class \'UnknownClass\' not found'); + $this->assertSame('Something went wrong.', $e->getMessage()); } } @@ -1753,8 +1749,8 @@ public function testErrorIsRethrownIfNotHandledByConsoleErrorEventWithCatchingEn $application->setAutoExit(false); $application->setDispatcher(new EventDispatcher()); - $application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) { - new \UnknownClass(); + $application->register('dym')->setCode(function () { + throw new \Error('Something went wrong.'); }); $tester = new ApplicationTester($application); @@ -1763,7 +1759,7 @@ public function testErrorIsRethrownIfNotHandledByConsoleErrorEventWithCatchingEn $tester->run(['command' => 'dym']); $this->fail('->run() should rethrow PHP errors if not handled via ConsoleErrorEvent.'); } catch (\Error $e) { - $this->assertSame($e->getMessage(), 'Class \'UnknownClass\' not found'); + $this->assertSame('Something went wrong.', $e->getMessage()); } } diff --git a/Tests/Command/ListCommandTest.php b/Tests/Command/ListCommandTest.php index 57687d4c6..3908ca5bb 100644 --- a/Tests/Command/ListCommandTest.php +++ b/Tests/Command/ListCommandTest.php @@ -23,7 +23,7 @@ public function testExecuteListsCommands() $commandTester = new CommandTester($command = $application->get('list')); $commandTester->execute(['command' => $command->getName()], ['decorated' => false]); - $this->assertRegExp('/help\s{2,}Displays help for a command/', $commandTester->getDisplay(), '->execute() returns a list of available commands'); + $this->assertMatchesRegularExpression('/help\s{2,}Displays help for a command/', $commandTester->getDisplay(), '->execute() returns a list of available commands'); } public function testExecuteListsCommandsWithXmlOption() @@ -31,7 +31,7 @@ public function testExecuteListsCommandsWithXmlOption() $application = new Application(); $commandTester = new CommandTester($command = $application->get('list')); $commandTester->execute(['command' => $command->getName(), '--format' => 'xml']); - $this->assertRegExp('/