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('//', $commandTester->getDisplay(), '->execute() returns a list of available commands in XML if --xml is passed');
+ $this->assertMatchesRegularExpression('//', $commandTester->getDisplay(), '->execute() returns a list of available commands in XML if --xml is passed');
}
public function testExecuteListsCommandsWithRawOption()
diff --git a/Tests/Formatter/NullOutputFormatterStyleTest.php b/Tests/Formatter/NullOutputFormatterStyleTest.php
index 616e7f714..08b24ceca 100644
--- a/Tests/Formatter/NullOutputFormatterStyleTest.php
+++ b/Tests/Formatter/NullOutputFormatterStyleTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Console\Tests\Output;
+namespace Symfony\Component\Console\Tests\Formatter;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Formatter\NullOutputFormatterStyle;
diff --git a/Tests/Formatter/NullOutputFormatterTest.php b/Tests/Formatter/NullOutputFormatterTest.php
index a717cf3d5..78dab00ca 100644
--- a/Tests/Formatter/NullOutputFormatterTest.php
+++ b/Tests/Formatter/NullOutputFormatterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\Component\Console\Tests\Output;
+namespace Symfony\Component\Console\Tests\Formatter;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Formatter\NullOutputFormatter;
diff --git a/Tests/Helper/TableTest.php b/Tests/Helper/TableTest.php
index daa09feed..070b87b03 100644
--- a/Tests/Helper/TableTest.php
+++ b/Tests/Helper/TableTest.php
@@ -333,6 +333,45 @@ public function renderProvider()
| Cupiditate dicta atque porro, tempora exercitationem modi animi nulla nemo vel nihil! |
+-------------------------------+-------------------------------+-----------------------------+
+TABLE
+ ],
+ 'Cell after colspan contains new line break' => [
+ ['Foo', 'Bar', 'Baz'],
+ [
+ [
+ new TableCell("foo\nbar", ['colspan' => 2]),
+ "baz\nqux",
+ ],
+ ],
+ 'default',
+<<<'TABLE'
++-----+-----+-----+
+| Foo | Bar | Baz |
++-----+-----+-----+
+| foo | baz |
+| bar | qux |
++-----+-----+-----+
+
+TABLE
+ ],
+ 'Cell after colspan contains multiple new lines' => [
+ ['Foo', 'Bar', 'Baz'],
+ [
+ [
+ new TableCell("foo\nbar", ['colspan' => 2]),
+ "baz\nqux\nquux",
+ ],
+ ],
+ 'default',
+<<<'TABLE'
++-----+-----+------+
+| Foo | Bar | Baz |
++-----+-----+------+
+| foo | baz |
+| bar | qux |
+| | quux |
++-----+-----+------+
+
TABLE
],
'Cell with rowspan' => [