From 0eabbb5e46b12f84fc65592cad1eb27db0ae6f75 Mon Sep 17 00:00:00 2001 From: Greg Anderson Date: Mon, 4 Apr 2016 14:43:59 -0700 Subject: [PATCH] Add csv formatter. --- src/FormatterManager.php | 1 + src/Formatters/CsvFormatter.php | 45 +++++++++++++++++++++++++++ tests/testFormatters.php | 54 +++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 src/Formatters/CsvFormatter.php diff --git a/src/FormatterManager.php b/src/FormatterManager.php index c4d11e9..7c0a2cd 100644 --- a/src/FormatterManager.php +++ b/src/FormatterManager.php @@ -16,6 +16,7 @@ public function __construct() 'print-r' => \Consolidation\OutputFormatters\Formatters\PrintRFormatter::class, 'var_export' => \Consolidation\OutputFormatters\Formatters\VarExportFormatter::class, 'list' => \Consolidation\OutputFormatters\Formatters\ListFormatter::class, + 'csv' => \Consolidation\OutputFormatters\Formatters\CsvFormatter::class, 'table' => \Consolidation\OutputFormatters\Formatters\TableFormatter::class, ]; } diff --git a/src/Formatters/CsvFormatter.php b/src/Formatters/CsvFormatter.php new file mode 100644 index 0000000..11d54cf --- /dev/null +++ b/src/Formatters/CsvFormatter.php @@ -0,0 +1,45 @@ +writeCsvLine($data, $options, $output); + return; + } + $this->writeCsvLines($data, $options, $output); + } + + public function writeCsvLines($data, $options, OutputInterface $output) + { + foreach ($data as $line) { + $this->writeCsvLine($line, $options, $output); + } + } + + public function writeCsvLine($data, $options, OutputInterface $output) + { + $output->write($this->csvEscape($data)); + } + + protected function csvEscape($data, $delimiter = ',') + { + $buffer = fopen('php://temp', 'r+'); + fputcsv($buffer, $data, $delimiter); + rewind($buffer); + $csv = fgets($buffer); + fclose($buffer); + return $csv; + } +} diff --git a/tests/testFormatters.php b/tests/testFormatters.php index bd153fa..a4c8156 100644 --- a/tests/testFormatters.php +++ b/tests/testFormatters.php @@ -298,6 +298,60 @@ function testList() $this->assertFormattedOutputMatches($expected, 'list', $data); } + 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 testSimpleTable() { $data = [