12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481 |
- <?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 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);
- }
- 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 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');
- }
- }
|