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 = <<assertFormattedOutputMatches($expected, 'yaml', $data); } function testNestedYaml() { $data = [ 'one' => [ 'i' => ['a', 'b', 'c'], ], 'two' => [ 'ii' => ['q', 'r', 's'], ], 'three' => [ 'iii' => ['t', 'u', 'v'], ], ]; $expected = <<assertFormattedOutputMatches($expected, 'yaml', $data); } function testSimpleJson() { $data = [ 'one' => 'a', 'two' => 'b', 'three' => 'c', ]; $expected = <<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 = <<assertFormattedOutputMatches($expected, 'json', $data); } function testSimplePrintR() { $data = [ 'one' => 'a', 'two' => 'b', 'three' => 'c', ]; $expected = << 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 = << 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 = << '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 = << 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 = <<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 = <<assertFormattedOutputMatches($expected, 'csv', $data); } function testCsvWithEmbeddedDoubleQuote() { $data = ['The "best" solution']; $expected = <<assertFormattedOutputMatches($expected, 'csv', $data); } function testCsvBothKindsOfQuotes() { $data = ["John's \"new\" book", "Mary's \"modified\" laptop"]; $expected = <<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 = <<assertFormattedOutputMatches($expected, 'table', $data); $expectedCsv = <<assertFormattedOutputMatches($expectedCsv, 'csv', $data); $expectedTsv = <<assertFormattedOutputMatches($expectedTsv, 'tsv', $data); $expectedTsvWithHeaders = <<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 = <<setWidth(42); $this->assertFormattedOutputMatches($expected, 'table', $data, $options); $expected = <<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 = <<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 = <<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 = <<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 = <<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 = <<assertFormattedOutputMatches($expected, 'table', $data); $expectedBorderless = <<assertFormattedOutputMatches($expectedBorderless, 'table', $data, new FormatterOptions(['table-style' => 'borderless'])); $expectedJson = <<assertFormattedOutputMatches($expectedJson, 'json', $data); $expectedCsv = <<assertFormattedOutputMatches($expectedCsv, 'csv', $data); $expectedList = <<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 = <<assertFormattedOutputMatches($expected, 'table', $data); $expectedBorderless = <<assertFormattedOutputMatches($expectedBorderless, 'table', $data, new FormatterOptions(['table-style' => 'borderless'])); $expectedJson = <<assertFormattedOutputMatches($expectedJson, 'json', $data); $expectedCsv = <<assertFormattedOutputMatches($expectedCsv, 'csv', $data); $expectedList = <<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 = <<assertFormattedOutputMatches($expected, 'table', $data, $configurationData); $expectedSidewaysTable = <<assertFormattedOutputMatches($expectedSidewaysTable, 'table', $data, $configurationData->override(['list-orientation' => true])); $expectedAnnotationFormatConfigData = <<assertFormattedOutputMatches($expectedAnnotationFormatConfigData, 'table', $data, $configurationDataAnnotationFormat); $expectedWithNoFields = <<assertFormattedOutputMatches($expectedWithNoFields, 'table', $data, $configurationData, ['include-field-labels' => false]); $expectedWithReorderedFields = <<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 = <<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 = <<assertFormattedOutputMatches($expectedSections, 'sections', $data, $configurationData); $expectedJson = <<assertFormattedOutputMatches($expectedJson, 'json', $data, $configurationData, ['fields' => ['San', 'Ichi']]); $expectedSingleField = <<assertFormattedOutputMatches($expectedSingleField, 'table', $data, $configurationData, ['field' => 'San']); $expectedEmptyColumn = <<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 = <<setFieldLabels(['one' => 'I', 'two' => 'II', 'three' => 'III']); $this->assertFormattedOutputMatches($expected, 'table', $data, $formatterOptionsWithFieldLables); } function testSimpleList() { $expected = <<simpleListExampleDataUsingAssociativeList(); $this->assertFormattedOutputMatches($expected, 'table', $data); $data = $this->simpleListExampleData(); $this->assertFormattedOutputMatches($expected, 'table', $data); $expected = <<setFieldLabels(['one' => 'I', 'two' => 'II', 'three' => 'III']); $this->assertFormattedOutputMatches($expected, 'table', $data, $formatterOptionsWithFieldLables); $expectedDrushStyleTable = <<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 = <<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 = <<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 = <<assertFormattedOutputMatches($expected, 'table', $data, $configurationData); $expectedWithReorderedFields = <<assertFormattedOutputMatches($expectedWithReorderedFields, 'table', $data, $configurationData, ['fields' => ['three', 'one']]); $this->assertFormattedOutputMatches($expectedWithReorderedFields, 'table', $data, $configurationData, ['fields' => ['San', 'Ichi']]); $expectedJson = <<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 = << The primary colors of the color wheel. red yellow blue 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 = << The primary colors of the color wheel. red yellow blue EOT; $expectedJson = << A couple of widgets. red yellow blue square circle triangle muave puce umber elipse rhombus trapazoid EOT; $expectedComplexJson = <<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'); } }