Mercurial > hg > isophonics-drupal-site
view vendor/consolidation/output-formatters/tests/testFormatters.php @ 9:1fc0ff908d1f
Add another data file
author | Chris Cannam |
---|---|
date | Mon, 05 Feb 2018 12:34:32 +0000 |
parents | 4c8ae668cc8c |
children |
line wrap: on
line source
<?php namespace Consolidation\OutputFormatters; use Consolidation\TestUtils\PropertyListWithCsvCells; use Consolidation\TestUtils\RowsOfFieldsWithAlternatives; use Consolidation\OutputFormatters\Options\FormatterOptions; use Consolidation\OutputFormatters\StructuredData\AssociativeList; use Consolidation\OutputFormatters\StructuredData\RowsOfFields; use Consolidation\OutputFormatters\StructuredData\PropertyList; use Consolidation\OutputFormatters\StructuredData\ListDataFromKeys; use Symfony\Component\Console\Output\BufferedOutput; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\StringInput; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputDefinition; class FormattersTests extends \PHPUnit_Framework_TestCase { protected $formatterManager; function setup() { $this->formatterManager = new FormatterManager(); } function assertFormattedOutputMatches($expected, $format, $data, FormatterOptions $options = null, $userOptions = []) { if (!$options) { $options = new FormatterOptions(); } $options->setOptions($userOptions); $output = new BufferedOutput(); $this->formatterManager->write($output, $format, $data, $options); $actual = preg_replace('#[ \t]*$#sm', '', $output->fetch()); $this->assertEquals(rtrim($expected), rtrim($actual)); } function testSimpleYaml() { $data = [ 'one' => 'a', 'two' => 'b', 'three' => 'c', ]; $expected = <<<EOT one: a two: b three: c EOT; $this->assertFormattedOutputMatches($expected, 'yaml', $data); $expected = <<<EOT a b c EOT; $this->assertFormattedOutputMatches($expected, 'list', $data); $data = new ListDataFromKeys($data); $expected = <<<EOT one: a two: b three: c EOT; $this->assertFormattedOutputMatches($expected, 'yaml', $data); $expected = <<<EOT one two three EOT; $this->assertFormattedOutputMatches($expected, 'list', $data); } function testNestedYaml() { $data = [ 'one' => [ 'i' => ['a', 'b', 'c'], ], 'two' => [ 'ii' => ['q', 'r', 's'], ], 'three' => [ 'iii' => ['t', 'u', 'v'], ], ]; $expected = <<<EOT one: i: - a - b - c two: ii: - q - r - s three: iii: - t - u - v EOT; $this->assertFormattedOutputMatches($expected, 'yaml', $data); } function testSimpleJson() { $data = [ 'one' => 'a', 'two' => 'b', 'three' => 'c', ]; $expected = <<<EOT { "one": "a", "two": "b", "three": "c" } EOT; $this->assertFormattedOutputMatches($expected, 'json', $data); } function testSerializeFormat() { $data = [ 'one' => 'a', 'two' => 'b', 'three' => 'c', ]; $expected = 'a:3:{s:3:"one";s:1:"a";s:3:"two";s:1:"b";s:5:"three";s:1:"c";}'; $this->assertFormattedOutputMatches($expected, 'php', $data); } function testNestedJson() { $data = [ 'one' => [ 'i' => ['a', 'b', 'c'], ], 'two' => [ 'ii' => ['q', 'r', 's'], ], 'three' => [ 'iii' => ['t', 'u', 'v'], ], ]; $expected = <<<EOT { "one": { "i": [ "a", "b", "c" ] }, "two": { "ii": [ "q", "r", "s" ] }, "three": { "iii": [ "t", "u", "v" ] } } EOT; $this->assertFormattedOutputMatches($expected, 'json', $data); } function testSimplePrintR() { $data = [ 'one' => 'a', 'two' => 'b', 'three' => 'c', ]; $expected = <<<EOT Array ( [one] => a [two] => b [three] => c ) EOT; $this->assertFormattedOutputMatches($expected, 'print-r', $data); } function testNestedPrintR() { $data = [ 'one' => [ 'i' => ['a', 'b', 'c'], ], 'two' => [ 'ii' => ['q', 'r', 's'], ], 'three' => [ 'iii' => ['t', 'u', 'v'], ], ]; $expected = <<<EOT Array ( [one] => Array ( [i] => Array ( [0] => a [1] => b [2] => c ) ) [two] => Array ( [ii] => Array ( [0] => q [1] => r [2] => s ) ) [three] => Array ( [iii] => Array ( [0] => t [1] => u [2] => v ) ) ) EOT; $this->assertFormattedOutputMatches($expected, 'print-r', $data); } function testSimpleVarExport() { $data = [ 'one' => 'a', 'two' => 'b', 'three' => 'c', ]; $expected = <<<EOT array ( 'one' => 'a', 'two' => 'b', 'three' => 'c', ) EOT; $this->assertFormattedOutputMatches($expected, 'var_export', $data); } function testNestedVarExport() { $data = [ 'one' => [ 'i' => ['a', 'b', 'c'], ], 'two' => [ 'ii' => ['q', 'r', 's'], ], 'three' => [ 'iii' => ['t', 'u', 'v'], ], ]; $expected = <<<EOT array ( 'one' => array ( 'i' => array ( 0 => 'a', 1 => 'b', 2 => 'c', ), ), 'two' => array ( 'ii' => array ( 0 => 'q', 1 => 'r', 2 => 's', ), ), 'three' => array ( 'iii' => array ( 0 => 't', 1 => 'u', 2 => 'v', ), ), ) EOT; $this->assertFormattedOutputMatches($expected, 'var_export', $data); } function testList() { $data = [ 'one' => 'a', 'two' => 'b', 'three' => 'c', ]; $expected = <<<EOT a b c EOT; $this->assertFormattedOutputMatches($expected, 'list', $data); } /** * @expectedException \Consolidation\OutputFormatters\Exception\UnknownFormatException * @expectedExceptionCode 1 * @expectedExceptionMessage The requested format, 'no-such-format', is not available. */ function testBadFormat() { $this->assertFormattedOutputMatches('Will fail, not return', 'no-such-format', ['a' => 'b']); } /** * @expectedException \Consolidation\OutputFormatters\Exception\IncompatibleDataException * @expectedExceptionCode 1 * @expectedExceptionMessage Data provided to Consolidation\OutputFormatters\Formatters\CsvFormatter must be one of an instance of Consolidation\OutputFormatters\StructuredData\RowsOfFields, an instance of Consolidation\OutputFormatters\StructuredData\PropertyList or an array. Instead, a string was provided. */ function testBadDataTypeForCsv() { $this->assertFormattedOutputMatches('Will fail, not return', 'csv', 'String cannot be converted to csv'); } /** * @expectedException \Consolidation\OutputFormatters\Exception\IncompatibleDataException * @expectedExceptionCode 1 * @expectedExceptionMessage Data provided to Consolidation\OutputFormatters\Formatters\JsonFormatter must be an array. Instead, a string was provided. */ function testBadDataTypeForJson() { $this->assertFormattedOutputMatches('Will fail, not return', 'json', 'String cannot be converted to json'); } function testNoFormatterSelected() { $data = 'Hello'; $expected = $data; $this->assertFormattedOutputMatches($expected, '', $data); } function testRenderTableAsString() { $data = new RowsOfFields([['f1' => 'A', 'f2' => 'B', 'f3' => 'C'], ['f1' => 'x', 'f2' => 'y', 'f3' => 'z']]); $expected = "A\tB\tC\nx\ty\tz"; $this->assertFormattedOutputMatches($expected, 'string', $data); } function testRenderTableAsStringWithSingleField() { $data = new RowsOfFields([['f1' => 'q', 'f2' => 'r', 'f3' => 's'], ['f1' => 'x', 'f2' => 'y', 'f3' => 'z']]); $expected = "q\nx"; $options = new FormatterOptions([FormatterOptions::DEFAULT_STRING_FIELD => 'f1']); $this->assertFormattedOutputMatches($expected, 'string', $data, $options); } function testRenderTableAsStringWithSingleFieldAndUserSelectedField() { $data = new RowsOfFields([['f1' => 'q', 'f2' => 'r', 'f3' => 's'], ['f1' => 'x', 'f2' => 'y', 'f3' => 'z']]); $expected = "r\ny"; $options = new FormatterOptions([FormatterOptions::DEFAULT_STRING_FIELD => 'f1']); $this->assertFormattedOutputMatches($expected, 'string', $data, $options, ['fields' => 'f2']); } function testSimpleCsv() { $data = ['a', 'b', 'c']; $expected = "a,b,c"; $this->assertFormattedOutputMatches($expected, 'csv', $data); } function testLinesOfCsv() { $data = [['a', 'b', 'c'], ['x', 'y', 'z']]; $expected = "a,b,c\nx,y,z"; $this->assertFormattedOutputMatches($expected, 'csv', $data); } function testCsvWithEscapedValues() { $data = ["Red apple", "Yellow lemon"]; $expected = '"Red apple","Yellow lemon"'; $this->assertFormattedOutputMatches($expected, 'csv', $data); } function testCsvWithEmbeddedSingleQuote() { $data = ["John's book", "Mary's laptop"]; $expected = <<<EOT "John's book","Mary's laptop" EOT; $this->assertFormattedOutputMatches($expected, 'csv', $data); } function testCsvWithEmbeddedDoubleQuote() { $data = ['The "best" solution']; $expected = <<<EOT "The ""best"" solution" EOT; $this->assertFormattedOutputMatches($expected, 'csv', $data); } function testCsvBothKindsOfQuotes() { $data = ["John's \"new\" book", "Mary's \"modified\" laptop"]; $expected = <<<EOT "John's ""new"" book","Mary's ""modified"" laptop" EOT; $this->assertFormattedOutputMatches($expected, 'csv', $data); } function testSimpleTsv() { $data = ['a', 'b', 'c']; $expected = "a\tb\tc"; $this->assertFormattedOutputMatches($expected, 'tsv', $data); } function testLinesOfTsv() { $data = [['a', 'b', 'c'], ['x', 'y', 'z']]; $expected = "a\tb\tc\nx\ty\tz"; $this->assertFormattedOutputMatches($expected, 'tsv', $data); } function testTsvBothKindsOfQuotes() { $data = ["John's \"new\" book", "Mary's \"modified\" laptop"]; $expected = "John's \"new\" book\tMary's \"modified\" laptop"; $this->assertFormattedOutputMatches($expected, 'tsv', $data); } function testTsvWithEscapedValues() { $data = ["Red apple", "Yellow lemon", "Embedded\ttab"]; $expected = "Red apple\tYellow lemon\tEmbedded\\ttab"; $this->assertFormattedOutputMatches($expected, 'tsv', $data); } protected function missingCellTableExampleData() { $data = [ [ 'one' => 'a', 'two' => 'b', 'three' => 'c', ], [ 'one' => 'x', 'three' => 'z', ], ]; return new RowsOfFields($data); } function testTableWithMissingCell() { $data = $this->missingCellTableExampleData(); $expected = <<<EOT ----- ----- ------- One Two Three ----- ----- ------- a b c x z ----- ----- ------- EOT; $this->assertFormattedOutputMatches($expected, 'table', $data); $expectedCsv = <<<EOT One,Two,Three a,b,c x,,z EOT; $this->assertFormattedOutputMatches($expectedCsv, 'csv', $data); $expectedTsv = <<<EOT a\tb\tc x\t\tz EOT; $this->assertFormattedOutputMatches($expectedTsv, 'tsv', $data); $expectedTsvWithHeaders = <<<EOT One\tTwo\tThree a\tb\tc x\t\tz EOT; $this->assertFormattedOutputMatches($expectedTsvWithHeaders, 'tsv', $data, new FormatterOptions(), ['include-field-labels' => true]); } function testTableWithWordWrapping() { $options = new FormatterOptions(); $data = [ [ 'first' => 'This is a really long cell that contains a lot of data. When it is rendered, it should be wrapped across multiple lines.', 'second' => 'This is the second column of the same table. It is also very long, and should be wrapped across multiple lines, just like the first column.', ] ]; $data = new RowsOfFields($data); $expected = <<<EOT ------------------ -------------------- First Second ------------------ -------------------- This is a really This is the second long cell that column of the same contains a lot table. It is also of data. When it very long, and is rendered, it should be wrapped should be across multiple wrapped across lines, just like multiple lines. the first column. ------------------ -------------------- EOT; $options->setWidth(42); $this->assertFormattedOutputMatches($expected, 'table', $data, $options); $expected = <<<EOT ----------------------------------- --------------------------------------- First Second ----------------------------------- --------------------------------------- This is a really long cell that This is the second column of the same contains a lot of data. When it table. It is also very long, and is rendered, it should be wrapped should be wrapped across multiple across multiple lines. lines, just like the first column. ----------------------------------- --------------------------------------- EOT; $options->setWidth(78); $this->assertFormattedOutputMatches($expected, 'table', $data, $options); } function testWrappingLotsOfColumns() { $options = new FormatterOptions(); $data = [ [ 'id' => '4d87b545-b4c3-4ece-9908-20c5c5e67e81', 'name' => '123456781234567812345678123456781234567812345678', 'service_level' => 'business', 'framework' => 'wordpress-network', 'owner' => '8558a08d-8059-45f6-9c4b-908299a025ee', 'created' => '2017-05-24 19:28:45', 'memberships' => 'b3a42ba5-755d-42ca-9109-21bde32809d0: Team,9bfaaf50-ece3-4460-acb8-dc1b8dd536e8: pantheon-engineering-canary-sites', 'frozen' => 'false', ], [ 'id' => '3d87b545-b4c3-4ece-9908-20c5c5e67e80', 'name' => 'build-tools-136', 'service_level' => 'free', 'framework' => 'drupal8', 'owner' => '7558a08d-8059-45f6-9c4b-908299a025ef', 'created' => '2017-05-24 19:28:45', 'memberships' => '5ae1fa30-8cc4-4894-8ca9-d50628dcba17: ci-for-drupal-8-composer', 'frozen' => 'false', ] ]; $data = new RowsOfFields($data); $expected = <<<EOT ------------- ---------------- --------------- ----------- ------------- --------- ------------------------------------ -------- Id Name Service_level Framework Owner Created Memberships Frozen ------------- ---------------- --------------- ----------- ------------- --------- ------------------------------------ -------- 4d87b545-b4 12345678123456 business wordp 8558a08d-80 2017-0 b3a42ba5-755d-42ca-9109-21bde32809 false c3-4ece-990 78123456781234 ress- 59-45f6-9c4 5-24 d0: 8-20c5c5e67 56781234567812 netwo b-908299a02 19:28: Team,9bfaaf50-ece3-4460-acb8-dc1b8 e81 345678 rk 5ee 45 dd536e8: pantheon-engineering-canary-sites 3d87b545-b4 build-tools-13 free drupa 7558a08d-80 2017-0 5ae1fa30-8cc4-4894-8ca9-d50628dcba false c3-4ece-990 6 l8 59-45f6-9c4 5-24 17: ci-for-drupal-8-composer 8-20c5c5e67 b-908299a02 19:28: e80 5ef 45 ------------- ---------------- --------------- ----------- ------------- --------- ------------------------------------ -------- EOT; $options->setWidth(125); $this->assertFormattedOutputMatches($expected, 'table', $data, $options); } function testTableWithWordWrapping2() { $options = new FormatterOptions(); $data = [ [ 'id' => 42, 'vid' => 321, 'description' => 'Life, the Universe and Everything.', ], [ 'id' => 13, 'vid' => 789, 'description' => 'Why is six afraid of seven?', ], ]; $data = new RowsOfFields($data); $expected = <<<EOT ---- ----- ----------------------------- Id Vid Description ---- ----- ----------------------------- 42 321 Life, the Universe and Everything. 13 789 Why is six afraid of seven? ---- ----- ----------------------------- EOT; $options->setWidth(42); $this->assertFormattedOutputMatches($expected, 'table', $data, $options); } function testTableWithWordWrapping3() { $options = new FormatterOptions(); $data = [ 'name' => 'Rex', 'species' => 'dog', 'food' => 'kibble', 'legs' => '4', 'description' => 'Rex is a very good dog, Brett. He likes kibble, and has four legs.', ]; $data = new PropertyList($data); $expected = <<<EOT ------------- ------------------------- Name Rex Species dog Food kibble Legs 4 Description Rex is a very good dog, Brett. He likes kibble, and has four legs. ------------- ------------------------- EOT; $options->setWidth(42); $this->assertFormattedOutputMatches($expected, 'table', $data, $options); } function testTableWithWordWrapping4() { $options = new FormatterOptions(); $data = [ 'name' => ['label' => 'Name', 'sep' => ':', 'value' => 'Rex', ], 'species' => ['label' => 'Species', 'sep' => ':', 'value' => 'dog', ], 'food' => ['label' => 'Food', 'sep' => ':', 'value' => 'kibble', ], 'legs' => ['label' => 'Legs', 'sep' => ':', 'value' => '4', ], 'description' => ['label' => 'Description', 'sep' => ':', 'value' => 'Rex is a very good dog, Brett. He likes kibble, and has four legs.', ], ]; $data = new RowsOfFields($data); $expected = <<<EOT ------------- ----- ----------------------------------------------------- Label Sep Value ------------- ----- ----------------------------------------------------- Name : Rex Species : dog Food : kibble Legs : 4 Description : Rex is a very good dog, Brett. He likes kibble, and has four legs. ------------- ----- ----------------------------------------------------- EOT; $options->setWidth(78); $this->assertFormattedOutputMatches($expected, 'table', $data, $options); } function testTableWithWordWrapping5() { $options = new FormatterOptions(); $data = [ 'name' => ['Name', ':', 'Rex', ], 'species' => ['Species', ':', 'dog', ], 'food' => ['Food', ':', 'kibble', ], 'legs' => ['Legs', ':', '4', ], 'description' => ['Description', ':', 'Rex is a very good dog, Brett. He likes kibble, and has four legs.', ], ]; $data = new RowsOfFields($data); $expected = <<<EOT Name : Rex Species : dog Food : kibble Legs : 4 Description : Rex is a very good dog, Brett. He likes kibble, and has four legs. EOT; $options->setWidth(78); $options->setIncludeFieldLables(false); $options->setTableStyle('compact'); $this->assertFormattedOutputMatches($expected, 'table', $data, $options); } protected function simpleTableExampleData() { $data = [ 'id-123' => [ 'one' => 'a', 'two' => 'b', 'three' => 'c', ], 'id-456' => [ 'one' => 'x', 'two' => 'y', 'three' => 'z', ], ]; return new RowsOfFields($data); } /** * @expectedException \Consolidation\OutputFormatters\Exception\InvalidFormatException * @expectedExceptionCode 1 * @expectedExceptionMessage The format table cannot be used with the data produced by this command, which was an array. Valid formats are: csv,json,list,php,print-r,string,tsv,var_export,xml,yaml */ function testIncompatibleDataForTableFormatter() { $data = $this->simpleTableExampleData()->getArrayCopy(); $this->assertFormattedOutputMatches('Should throw an exception before comparing the table data', 'table', $data); } /** * @expectedException \Consolidation\OutputFormatters\Exception\InvalidFormatException * @expectedExceptionCode 1 * @expectedExceptionMessage The format sections cannot be used with the data produced by this command, which was an array. Valid formats are: csv,json,list,php,print-r,string,tsv,var_export,xml,yaml */ function testIncompatibleDataForSectionsFormatter() { $data = $this->simpleTableExampleData()->getArrayCopy(); $this->assertFormattedOutputMatches('Should throw an exception before comparing the table data', 'sections', $data); } function testSimpleTable() { $data = $this->simpleTableExampleData(); $expected = <<<EOT ----- ----- ------- One Two Three ----- ----- ------- a b c x y z ----- ----- ------- EOT; $this->assertFormattedOutputMatches($expected, 'table', $data); $expectedBorderless = <<<EOT ===== ===== ======= One Two Three ===== ===== ======= a b c x y z ===== ===== ======= EOT; $this->assertFormattedOutputMatches($expectedBorderless, 'table', $data, new FormatterOptions(['table-style' => 'borderless'])); $expectedJson = <<<EOT { "id-123": { "one": "a", "two": "b", "three": "c" }, "id-456": { "one": "x", "two": "y", "three": "z" } } EOT; $this->assertFormattedOutputMatches($expectedJson, 'json', $data); $expectedCsv = <<<EOT One,Two,Three a,b,c x,y,z EOT; $this->assertFormattedOutputMatches($expectedCsv, 'csv', $data); $expectedList = <<<EOT id-123 id-456 EOT; $this->assertFormattedOutputMatches($expectedList, 'list', $data); } protected function tableWithAlternativesExampleData() { $data = [ 'id-123' => [ 'one' => 'a', 'two' => ['this', 'that', 'the other thing'], 'three' => 'c', ], 'id-456' => [ 'one' => 'x', 'two' => 'y', 'three' => ['apples', 'oranges'], ], ]; return new RowsOfFieldsWithAlternatives($data); } function testTableWithAlternatives() { $data = $this->tableWithAlternativesExampleData(); $expected = <<<EOT ----- --------------------------- ---------------- One Two Three ----- --------------------------- ---------------- a this|that|the other thing c x y apples|oranges ----- --------------------------- ---------------- EOT; $this->assertFormattedOutputMatches($expected, 'table', $data); $expectedBorderless = <<<EOT ===== =========================== ================ One Two Three ===== =========================== ================ a this|that|the other thing c x y apples|oranges ===== =========================== ================ EOT; $this->assertFormattedOutputMatches($expectedBorderless, 'table', $data, new FormatterOptions(['table-style' => 'borderless'])); $expectedJson = <<<EOT { "id-123": { "one": "a", "two": [ "this", "that", "the other thing" ], "three": "c" }, "id-456": { "one": "x", "two": "y", "three": [ "apples", "oranges" ] } } EOT; $this->assertFormattedOutputMatches($expectedJson, 'json', $data); $expectedCsv = <<<EOT One,Two,Three a,"this|that|the other thing",c x,y,apples|oranges EOT; $this->assertFormattedOutputMatches($expectedCsv, 'csv', $data); $expectedList = <<<EOT id-123 id-456 EOT; $this->assertFormattedOutputMatches($expectedList, 'list', $data); } function testSimpleTableWithFieldLabels() { $data = $this->simpleTableExampleData(); $configurationData = new FormatterOptions( [ 'field-labels' => ['one' => 'Ichi', 'two' => 'Ni', 'three' => 'San'], 'row-labels' => ['id-123' => 'Walrus', 'id-456' => 'Carpenter'], ] ); $configurationDataAnnotationFormat = new FormatterOptions( [ 'field-labels' => "one: Uno\ntwo: Dos\nthree: Tres", ] ); $expected = <<<EOT ------ ---- ----- Ichi Ni San ------ ---- ----- a b c x y z ------ ---- ----- EOT; $this->assertFormattedOutputMatches($expected, 'table', $data, $configurationData); $expectedSidewaysTable = <<<EOT ------ --- --- Ichi a x Ni b y San c z ------ --- --- EOT; $this->assertFormattedOutputMatches($expectedSidewaysTable, 'table', $data, $configurationData->override(['list-orientation' => true])); $expectedAnnotationFormatConfigData = <<<EOT ----- ----- ------ Uno Dos Tres ----- ----- ------ a b c x y z ----- ----- ------ EOT; $this->assertFormattedOutputMatches($expectedAnnotationFormatConfigData, 'table', $data, $configurationDataAnnotationFormat); $expectedWithNoFields = <<<EOT --- --- --- a b c x y z --- --- --- EOT; $this->assertFormattedOutputMatches($expectedWithNoFields, 'table', $data, $configurationData, ['include-field-labels' => false]); $expectedWithReorderedFields = <<<EOT ----- ------ San Ichi ----- ------ c a z x ----- ------ EOT; $this->assertFormattedOutputMatches($expectedWithReorderedFields, 'table', $data, $configurationData, ['fields' => ['three', 'one']]); $this->assertFormattedOutputMatches($expectedWithReorderedFields, 'table', $data, $configurationData, ['fields' => ['San', 'Ichi']]); $this->assertFormattedOutputMatches($expectedWithReorderedFields, 'table', $data, $configurationData, ['fields' => 'San,Ichi']); $expectedWithRegexField = <<<EOT ------ ----- Ichi San ------ ----- a c x z ------ ----- EOT; $this->assertFormattedOutputMatches($expectedWithRegexField, 'table', $data, $configurationData, ['fields' => ['/e$/']]); $this->assertFormattedOutputMatches($expectedWithRegexField, 'table', $data, $configurationData, ['fields' => ['*e']]); $this->assertFormattedOutputMatches($expectedWithRegexField, 'table', $data, $configurationData, ['default-fields' => ['*e']]); $expectedSections = <<<EOT Walrus One a Two b Three c Carpenter One x Two y Three z EOT; $this->assertFormattedOutputMatches($expectedSections, 'sections', $data, $configurationData); $expectedJson = <<<EOT { "id-123": { "three": "c", "one": "a" }, "id-456": { "three": "z", "one": "x" } } EOT; $this->assertFormattedOutputMatches($expectedJson, 'json', $data, $configurationData, ['fields' => ['San', 'Ichi']]); $expectedSingleField = <<<EOT ----- San ----- c z ----- EOT; $this->assertFormattedOutputMatches($expectedSingleField, 'table', $data, $configurationData, ['field' => 'San']); $expectedEmptyColumn = <<<EOT ----- San ----- EOT; $this->assertFormattedOutputMatches($expectedEmptyColumn, 'table', new RowsOfFields([]), $configurationData, ['field' => 'San']); $this->assertFormattedOutputMatches('', '', new RowsOfFields([]), $configurationData, ['field' => 'San']); $this->assertFormattedOutputMatches('[]', 'json', new RowsOfFields([]), $configurationData, ['field' => 'San']); } /** * @expectedException \Consolidation\OutputFormatters\Exception\UnknownFieldException * @expectedExceptionCode 1 * @expectedExceptionMessage The requested field, 'Shi', is not defined. */ function testNoSuchFieldException() { $configurationData = new FormatterOptions( [ 'field-labels' => ['one' => 'Ichi', 'two' => 'Ni', 'three' => 'San'], 'row-labels' => ['id-123' => 'Walrus', 'id-456' => 'Carpenter'], ] ); $data = $this->simpleTableExampleData(); $this->assertFormattedOutputMatches('Will throw before comparing', 'table', $data, $configurationData, ['field' => 'Shi']); } protected function simpleListExampleData() { $data = [ 'one' => 'apple', 'two' => 'banana', 'three' => 'carrot', ]; return new PropertyList($data); } // Test with the deprecated data structure protected function simpleListExampleDataUsingAssociativeList() { $data = [ 'one' => 'apple', 'two' => 'banana', 'three' => 'carrot', ]; return new AssociativeList($data); } /** * @expectedException \Consolidation\OutputFormatters\Exception\InvalidFormatException * @expectedExceptionCode 1 * @expectedExceptionMessage The format table cannot be used with the data produced by this command, which was an array. Valid formats are: csv,json,list,php,print-r,string,tsv,var_export,xml,yaml */ function testIncompatibleListDataForTableFormatter() { $data = $this->simpleListExampleData(); $this->assertFormattedOutputMatches('Should throw an exception before comparing the table data', 'table', $data->getArrayCopy()); } function testEmptyList() { $data = new RowsOfFields([]); $expected = <<<EOT --- ---- ----- I II III --- ---- ----- EOT; // If we provide field labels, then the output will change to reflect that. $formatterOptionsWithFieldLables = new FormatterOptions(); $formatterOptionsWithFieldLables ->setFieldLabels(['one' => 'I', 'two' => 'II', 'three' => 'III']); $this->assertFormattedOutputMatches($expected, 'table', $data, $formatterOptionsWithFieldLables); } function testSimpleList() { $expected = <<<EOT ------- -------- One apple Two banana Three carrot ------- -------- EOT; $data = $this->simpleListExampleDataUsingAssociativeList(); $this->assertFormattedOutputMatches($expected, 'table', $data); $data = $this->simpleListExampleData(); $this->assertFormattedOutputMatches($expected, 'table', $data); $expected = <<<EOT ----- -------- I apple II banana III carrot ----- -------- EOT; // If we provide field labels, then the output will change to reflect that. $formatterOptionsWithFieldLables = new FormatterOptions(); $formatterOptionsWithFieldLables ->setFieldLabels(['one' => 'I', 'two' => 'II', 'three' => 'III']); $this->assertFormattedOutputMatches($expected, 'table', $data, $formatterOptionsWithFieldLables); $expectedDrushStyleTable = <<<EOT One : apple Two : banana Three : carrot EOT; // If we provide field labels, then the output will change to reflect that. $formatterOptionsWithFieldLables = new FormatterOptions(); $formatterOptionsWithFieldLables ->setTableStyle('compact') ->setListDelimiter(':'); $this->assertFormattedOutputMatches($expectedDrushStyleTable, 'table', $data, $formatterOptionsWithFieldLables); // Adding an extra field that does not exist in the data set should not change the output $formatterOptionsWithExtraFieldLables = new FormatterOptions(); $formatterOptionsWithExtraFieldLables ->setFieldLabels(['one' => 'I', 'two' => 'II', 'three' => 'III', 'four' => 'IV']); $this->assertFormattedOutputMatches($expected, 'table', $data, $formatterOptionsWithExtraFieldLables); $expectedRotated = <<<EOT ------- -------- -------- One Two Three ------- -------- -------- apple banana carrot ------- -------- -------- EOT; $this->assertFormattedOutputMatches($expectedRotated, 'table', $data, new FormatterOptions(['list-orientation' => false])); $expectedList = <<< EOT apple banana carrot EOT; $this->assertFormattedOutputMatches($expectedList, 'list', $data); $expectedReorderedList = <<< EOT carrot apple EOT; $options = new FormatterOptions([FormatterOptions::FIELDS => 'three,one']); $this->assertFormattedOutputMatches($expectedReorderedList, 'list', $data, $options); $expectedCsv = <<< EOT One,Two,Three apple,banana,carrot EOT; $this->assertFormattedOutputMatches($expectedCsv, 'csv', $data); $expectedCsvNoHeaders = 'apple,banana,carrot'; $this->assertFormattedOutputMatches($expectedCsvNoHeaders, 'csv', $data, new FormatterOptions(), ['include-field-labels' => false]); // Next, configure the formatter options with 'include-field-labels', // but set --include-field-labels to turn the option back on again. $options = new FormatterOptions(['include-field-labels' => false]); $input = new StringInput('test --include-field-labels'); $optionDefinitions = [ new InputArgument('unused', InputArgument::REQUIRED), new InputOption('include-field-labels', null, InputOption::VALUE_NONE), ]; $definition = new InputDefinition($optionDefinitions); $input->bind($definition); $testValue = $input->getOption('include-field-labels'); $this->assertTrue($testValue); $hasFieldLabels = $input->hasOption('include-field-labels'); $this->assertTrue($hasFieldLabels); $this->assertFormattedOutputMatches($expectedCsvNoHeaders, 'csv', $data, $options); $options->setInput($input); $this->assertFormattedOutputMatches($expectedCsv, 'csv', $data, $options); } protected function associativeListWithRenderer() { $data = [ 'one' => 'apple', 'two' => ['banana', 'plantain'], 'three' => 'carrot', 'four' => ['peaches', 'pumpkin pie'], ]; $list = new PropertyList($data); $list->addRendererFunction( function ($key, $cellData, FormatterOptions $options) { if (is_array($cellData)) { return implode(',', $cellData); } return $cellData; } ); return $list; } protected function associativeListWithCsvCells() { $data = [ 'one' => 'apple', 'two' => ['banana', 'plantain'], 'three' => 'carrot', 'four' => ['peaches', 'pumpkin pie'], ]; return new PropertyListWithCsvCells($data); } function testPropertyListWithCsvCells() { $this->doPropertyListWithCsvCells($this->associativeListWithRenderer()); $this->doPropertyListWithCsvCells($this->associativeListWithCsvCells()); } function doPropertyListWithCsvCells($data) { $expected = <<<EOT ------- --------------------- One apple Two banana,plantain Three carrot Four peaches,pumpkin pie ------- --------------------- EOT; $this->assertFormattedOutputMatches($expected, 'table', $data); $expectedList = <<< EOT apple banana,plantain carrot peaches,pumpkin pie EOT; $this->assertFormattedOutputMatches($expectedList, 'list', $data); $expectedCsv = <<< EOT One,Two,Three,Four apple,"banana,plantain",carrot,"peaches,pumpkin pie" EOT; $this->assertFormattedOutputMatches($expectedCsv, 'csv', $data); $expectedCsvNoHeaders = 'apple,"banana,plantain",carrot,"peaches,pumpkin pie"'; $this->assertFormattedOutputMatches($expectedCsvNoHeaders, 'csv', $data, new FormatterOptions(), ['include-field-labels' => false]); $expectedTsv = <<< EOT apple\tbanana,plantain\tcarrot\tpeaches,pumpkin pie EOT; $this->assertFormattedOutputMatches($expectedTsv, 'tsv', $data); } function testSimpleListWithFieldLabels() { $data = $this->simpleListExampleData(); $configurationData = new FormatterOptions( [ 'field-labels' => ['one' => 'Ichi', 'two' => 'Ni', 'three' => 'San'], ] ); $expected = <<<EOT ------ -------- Ichi apple Ni banana San carrot ------ -------- EOT; $this->assertFormattedOutputMatches($expected, 'table', $data, $configurationData); $expectedWithReorderedFields = <<<EOT ------ -------- San carrot Ichi apple ------ -------- EOT; $this->assertFormattedOutputMatches($expectedWithReorderedFields, 'table', $data, $configurationData, ['fields' => ['three', 'one']]); $this->assertFormattedOutputMatches($expectedWithReorderedFields, 'table', $data, $configurationData, ['fields' => ['San', 'Ichi']]); $expectedJson = <<<EOT { "three": "carrot", "one": "apple" } EOT; $this->assertFormattedOutputMatches($expectedJson, 'json', $data, $configurationData, ['fields' => ['San', 'Ichi']]); } function testSimpleXml() { $data = [ 'name' => 'primary', 'description' => 'The primary colors of the color wheel.', 'colors' => [ 'red', 'yellow', 'blue', ], ]; $expected = <<<EOT <?xml version="1.0" encoding="UTF-8"?> <document name="primary"> <description>The primary colors of the color wheel.</description> <colors> <color>red</color> <color>yellow</color> <color>blue</color> </colors> </document> EOT; $this->assertFormattedOutputMatches($expected, 'xml', $data); } function domDocumentData() { $dom = new \DOMDocument('1.0', 'UTF-8'); $document = $dom->createElement('document'); $dom->appendChild($document); $document->setAttribute('name', 'primary'); $description = $dom->createElement('description'); $document->appendChild($description); $description->appendChild($dom->createTextNode('The primary colors of the color wheel.')); $this->domCreateElements($dom, $document, 'color', ['red', 'yellow', 'blue']); return $dom; } function domCreateElements($dom, $element, $name, $data) { $container = $dom->createElement("{$name}s"); $element->appendChild($container); foreach ($data as $value) { $child = $dom->createElement($name); $container->appendChild($child); $child->appendChild($dom->createTextNode($value)); } } function complexDomDocumentData() { $dom = new \DOMDocument('1.0', 'UTF-8'); $document = $dom->createElement('document'); $dom->appendChild($document); $document->setAttribute('name', 'widget-collection'); $description = $dom->createElement('description'); $document->appendChild($description); $description->appendChild($dom->createTextNode('A couple of widgets.')); $widgets = $dom->createElement('widgets'); $document->appendChild($widgets); $widget = $dom->createElement('widget'); $widgets->appendChild($widget); $widget->setAttribute('name', 'usual'); $this->domCreateElements($dom, $widget, 'color', ['red', 'yellow', 'blue']); $this->domCreateElements($dom, $widget, 'shape', ['square', 'circle', 'triangle']); $widget = $dom->createElement('widget'); $widgets->appendChild($widget); $widget->setAttribute('name', 'unusual'); $this->domCreateElements($dom, $widget, 'color', ['muave', 'puce', 'umber']); $this->domCreateElements($dom, $widget, 'shape', ['elipse', 'rhombus', 'trapazoid']); return $dom; } function domDocumentTestValues() { $expectedXml = <<<EOT <?xml version="1.0" encoding="UTF-8"?> <document name="primary"> <description>The primary colors of the color wheel.</description> <colors> <color>red</color> <color>yellow</color> <color>blue</color> </colors> </document> EOT; $expectedJson = <<<EOT { "name": "primary", "description": "The primary colors of the color wheel.", "colors": [ "red", "yellow", "blue" ] } EOT; $expectedComplexXml = <<<EOT <?xml version="1.0" encoding="UTF-8"?> <document name="widget-collection"> <description>A couple of widgets.</description> <widgets> <widget name="usual"> <colors> <color>red</color> <color>yellow</color> <color>blue</color> </colors> <shapes> <shape>square</shape> <shape>circle</shape> <shape>triangle</shape> </shapes> </widget> <widget name="unusual"> <colors> <color>muave</color> <color>puce</color> <color>umber</color> </colors> <shapes> <shape>elipse</shape> <shape>rhombus</shape> <shape>trapazoid</shape> </shapes> </widget> </widgets> </document> EOT; $expectedComplexJson = <<<EOT { "name": "widget-collection", "description": "A couple of widgets.", "widgets": { "usual": { "name": "usual", "colors": [ "red", "yellow", "blue" ], "shapes": [ "square", "circle", "triangle" ] }, "unusual": { "name": "unusual", "colors": [ "muave", "puce", "umber" ], "shapes": [ "elipse", "rhombus", "trapazoid" ] } } } EOT; return [ [ $this->domDocumentData(), $expectedXml, $expectedJson, ], [ $this->complexDomDocumentData(), $expectedComplexXml, $expectedComplexJson, ], ]; } /** * @dataProvider domDocumentTestValues */ function testDomData($data, $expectedXml, $expectedJson) { $this->assertFormattedOutputMatches($expectedXml, 'xml', $data); $this->assertFormattedOutputMatches($expectedJson, 'json', $data); // Check to see if we get the same xml data if we convert from // DOM -> array -> DOM. $expectedJsonAsArray = (array)json_decode($expectedJson); $this->assertFormattedOutputMatches($expectedXml, 'xml', $expectedJsonAsArray); } /** * @expectedException \Exception * @expectedExceptionCode 1 * @expectedExceptionMessage Data provided to Consolidation\OutputFormatters\Formatters\XmlFormatter must be either an instance of DOMDocument or an array. Instead, a string was provided. */ function testDataTypeForXmlFormatter() { $this->assertFormattedOutputMatches('Will fail, not return', 'xml', 'Strings cannot be converted to XML'); } }