diff --git a/.gitignore b/.gitignore
index 57872d0..f2a5df1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,4 @@
+*.swp
+tags
+
/vendor/
diff --git a/.woodpecker.yml b/.woodpecker.yml
deleted file mode 100644
index f338970..0000000
--- a/.woodpecker.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-matrix:
- PHP_VERSION:
- - 7.3
- - 7.4
- - 8.0
- - 8.1
-
-pipeline:
- dependencies:
- image: gitnet.fr/deblan/php:${PHP_VERSION}
- commands:
- - php /usr/local/bin/composer install
- - php /usr/local/bin/composer require --dev phpunit/phpunit
- tests:
- image: gitnet.fr/deblan/php:${PHP_VERSION}
- commands:
- - php ./vendor/bin/phpunit
diff --git a/LICENSE b/LICENSE
index 80445fb..b57a6c2 100644
--- a/LICENSE
+++ b/LICENSE
@@ -20,5 +20,4 @@ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/README.md b/README.md
index 1afed82..7c89d21 100644
--- a/README.md
+++ b/README.md
@@ -1,20 +1,12 @@
CSV parser/generator
====================
-[](https://ci.gitnet.fr/deblan/csv)
-
-A simple PHP library to:
-
-* parse a CSV file
-* parse a stream as CSV datas
-* generate CSV files.
-
-PHP >= 7.1 required.
+A simple PHP library to parse and generate CSV files.
## Composer installation
```
-$ composer require deblan/csv "~3"
+$ composer require deblan/csv
```
Or in your composer.json:
@@ -22,7 +14,8 @@ Or in your composer.json:
```
{
"require": {
- "deblan/csv": "~3"
+ [...]
+ "deblan/csv": "dev-master"
}
}
```
@@ -36,85 +29,33 @@ use Deblan\Csv\Csv;
$csv = new Csv();
-// Defines the delimiter (default is ;)
-$csv->setDelimiter(";");
+$csv->addLine(array('Foo', '$1000'));
+$csv->addLine(array('Bar', '$600'));
-// Defines the enclosure (default is ")
-$csv->setEnclosure('"');
-
-// Defines the end of line (default is \n)
-$csv->setEndOfLine("\n");
-
-// Defines the charset (default is UTF-8)
-$csv->setCharset("UTF-8");
-
-// Add a new line at the end
-$csv->addData(['Foo', '$1000'));
-
-// Add a new line at the end
-$csv->appendData(['Bar', '$600']);
-
-// Add a new line at the beginning
-$csv->prependData(['Boo', '$3000']);
-
-// Defines all the datas
-$csv->setDatas([[...], [...]]);
-
-// Defines the header
-$csv->setHeaders(['Product', 'Price']);
-
-// Rendering
-$result = $csv->render();
-
-// Rendering to a file
-$result = $csv->render('products.csv');
-
-// Appending to a file
-$result = $csv->render('products.csv', FILE_APPEND);
+$result = $csv->compile();
```
-### Parse a file
+```php
+use Deblan\Csv\Csv;
+
+$csv = new Csv();
+
+$csv->setLegend(array('product name', 'price'));
+$csv->addLine(array('Foo', '$1000'));
+$csv->addLine(array('Bar', '$600'));
+
+$csv->compileToFile('products.csv');
+```
+
+### Parser
```php
use Deblan\Csv\CsvParser;
-$csv = new CsvParser();
+$csv = new CsvParser('products.csv');
+$csv->setHasLegend(true);
+$csv->parse();
-// Defines the delimiter (default is ;)
-$csv->setDelimiter(";");
-
-// Defines the enclosure (default is ")
-$csv->setEnclosure('"');
-
-// Defines the end of line (default is \n)
-$csv->setEndOfLine("\n");
-
-// Headers?
-$csv->setHasHeaders(true);
-
-// Parse a file
-$csv->parseFile('products.csv');
-
-// Parse a string
-$csv->parseString($myString);
-
-// Headers and datas
-$headers = $csv->getHeaders();
+$legend = $csv->getLegend();
$products = $csv->getDatas();
```
-
-### Parse a stream
-
-```php
-use Deblan\Csv\CsvStreamParser;
-
-// CsvStreamParser is a CsvParser
-$csv = new CsvStreamParser();
-
-// Parse a stream
-$csv->parseStream(fopen('products.csv', 'r'));
-
-while ($data = $csv->getData()) {
- // ...
-}
-```
diff --git a/phpunit.xml b/phpunit.xml
index 2fd344a..eabb967 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -7,11 +7,12 @@
convertWarningsToExceptions = "true"
processIsolation = "false"
stopOnFailure = "false"
+ syntaxCheck = "false"
bootstrap = "vendor/autoload.php" >
-
-
- tests/
-
-
+
+
+ tests/
+
+
diff --git a/src/Deblan/Csv/Csv.php b/src/Deblan/Csv/Csv.php
index fa57d8f..1054f20 100644
--- a/src/Deblan/Csv/Csv.php
+++ b/src/Deblan/Csv/Csv.php
@@ -2,340 +2,192 @@
namespace Deblan\Csv;
-/**
- * class Csv.
- *
- * @author Simon Vieille
- */
+use Deblan\Csv\Exception\CsvInvalidParameterException;
+
class Csv
{
- /**
- * @var string
- */
- protected $delimiter = ';';
+ private $delimiter;
- /**
- * @var string
- */
- protected $enclosure = '"';
+ private $enclosure;
- /**
- * @var string
- */
- protected $endOfLine = "\n";
+ private $endline;
- /**
- * @var array
- */
- protected $datas = [];
+ private $datas;
- /**
- * @var array
- */
- protected $headers = [];
+ private $legend;
- /**
- * @var string
- */
- protected $charset = 'UTF-8';
+ private $render;
- /**
- * @var bool
- */
- protected $isModified = false;
+ private $encoding;
- /**
- * @var string
- */
- protected $render;
+ private $hasLegend = false;
- /**
- * Set the value of "delimiter".
- *
- * @param string $delimiter
- *
- * @return Csv
- */
- public function setDelimiter($delimiter)
+ public function __construct($delimiter = ';', $enclosure = '"', $endline = "\n", $encoding = 'UTF-8')
{
- if ($this->delimiter !== $delimiter) {
- $this->delimiter = $delimiter;
- $this->isModified = true;
+ $this->setDelimiter($delimiter);
+ $this->setEnclosure($enclosure);
+ $this->setEndLine($endline);
+ $this->setEncoding($encoding);
+ $this->datas = array(0 => null);
+ $this->legend = array();
+ $this->render = "";
+ }
+
+ public function setFilename($v)
+ {
+ if (!is_string($v)) {
+ throw new CsvInvalidParameterException(sprintf('"%s" is not a valid string.', $v));
}
+ $this->filename = $v;
+ }
+
+ protected function setHasLegend($hasLegend)
+ {
+ $this->hasLegend = $hasLegend;
+
return $this;
}
- /**
- * Get the value of "delimiter".
- *
- * @return array
- */
- public function getDelimiter()
+ public function getHasLegend()
{
- return $this->delimiter;
+ return $this->hasLegend;
}
- /**
- * Set the value of "enclosure".
- *
- * @param string $enclosure
- *
- * @return Csv
- */
- public function setEnclosure($enclosure)
+ public function hasLegend()
{
- $enclosure = (string) $enclosure;
+ return $this->hasLegend;
+ }
- if ($this->enclosure !== $enclosure) {
- $this->enclosure = $enclosure;
- $this->isModified = true;
+ public function setLegend(array $values)
+ {
+ $this->setHasLegend(true);
+
+ $this->legend = $values;
+
+ $this->addLine($values, 0);
+ }
+
+ public function addLine(array $values, $key = null)
+ {
+ if ($key !== null) {
+ $this->datas[$key] = $values;
+
+ return true;
}
+ $this->datas[] = $values;
+ }
+
+ public function setEncoding($encoding)
+ {
+ $this->encoding = $encoding;
+
return $this;
}
- /**
- * Get the value of "enclosure".
- *
- * @return string
- */
- public function getEnclosure()
+ public function getEncoding()
{
- return $this->enclosure;
+ return $this->encoding;
}
- /**
- * Set the value of "endOfLine".
- *
- * @param string $endOfLine
- *
- * @return Csv
- */
- public function setEndOfLine($endOfLine)
+ public function setDelimiter($v)
{
- if ($this->endOfLine !== $endOfLine) {
- $this->endOfLine = (string) $endOfLine;
- $this->isModified = true;
+ if (!is_string($v)) {
+ throw new CsvInvalidParameterException(sprintf('"%s" is not a valid string.', $v));
}
- return $this;
+ $this->delimiter = $v;
}
- /**
- * Get the value of "endOfLine".
- *
- * @return string
- */
- public function getEndOfLine()
+ public function setEndline($v)
{
- return $this->endOfLine;
- }
-
- /**
- * Set the value of "headers".
- *
- * @param array $headers
- *
- * @return Csv
- */
- public function setHeaders(array $headers)
- {
- $this->headers = $headers;
-
- if ($this->headers !== $headers) {
- $this->headers = $headers;
- $this->isModified = true;
+ if (!is_string($v)) {
+ throw new CsvInvalidParameterException(sprintf('"%s" is not a valid string.', $v));
}
- return $this;
+ $this->endline = $v;
}
- /**
- * Get the value of "headers".
- *
- * @return array
- */
- public function getHeaders()
+ public function setEnclosure($v)
{
- return $this->headers;
- }
-
- /**
- * Set the value of "charset".
- *
- * @param string $charset
- *
- * @return Csv
- */
- public function setCharset($charset)
- {
- if ($this->charset !== $charset) {
- $this->charset = (string) $charset;
- $this->isModified = true;
+ if (!is_string($v)) {
+ throw new CsvInvalidParameterException(sprintf('"%s" is not a valid string.', $v));
}
- return $this;
+ $this->enclose = $v;
}
- /**
- * Get the value of "charset".
- *
- * @return string
- */
- public function getCharset()
+ public function getLegend()
{
- return $this->charset;
+ return $this->legend;
}
- /*
- * Sets the value of "datas".
- *
- * @param array $datas
- *
- * @return Csv
- */
- public function setDatas(array $datas)
- {
- if ($this->datas !== $datas) {
- $this->datas = $datas;
- $this->isModified = true;
- }
-
- return $this;
- }
-
- /**
- * Get the value of "datas".
- *
- * @return array
- */
public function getDatas()
{
return $this->datas;
}
- /*
- * Appends data.
- *
- * @param array $data
- *
- * @return Csv
- */
- public function appendData(array $data)
+ public function compile()
{
- $this->datas[] = $data;
- $this->isModified = true;
+ $this->render = "";
- return $this;
- }
-
- /*
- * Alias of "appendData()".
- *
- * {@inheritdoc self::appendData()}
- */
- public function addData(array $data)
- {
- return $this->appendData($data);
- }
-
- /*
- * Prepends data.
- *
- * @param array $data
- *
- * @return Csv
- */
- public function preprendData(array $data)
- {
- array_unshift($this->datas, $data);
- $this->isModified = true;
-
- return $this;
- }
-
- /**
- * Formats an array data to a CSV string.
- *
- * @param array $data
- *
- * @return array
- */
- protected function formatData(array $data)
- {
- $columns = [];
-
- foreach ($data as $value) {
- $value = (string) $value;
-
- if (!empty($this->enclosure)) {
- $value = str_replace($this->enclosure, str_repeat($this->enclosure, 2), $value);
- }
-
- $value = sprintf('%1$s%2$s%1$s', $this->enclosure, (string) $value);
-
- $columns[] = $value;
+ if ($this->datas[0] !== null) {
+ $this->append($this->datasToCsvLine($this->datas[0]));
}
- $data = implode($this->delimiter, $columns);
- $data = $this->encode($data);
+ unset($this->datas[0]);
- return $data;
- }
-
- /*
- * Changes the charset if needed.
- *
- * @param string $value
- *
- * @return string
- */
- public function encode($value)
- {
- return mb_convert_encoding(
- $value,
- $this->charset,
- mb_detect_encoding($value, mb_list_encodings())
- );
- }
-
- /*
- * Renders the CSV.
- *
- * @param string $filename @see file_put_contents
- * @param int $flags @see file_put_contents
- *
- * @return string
- */
- public function render($filename = null, $flags = null)
- {
- if ($this->isModified || empty($this->render)) {
- $lines = [];
-
- if (!empty($this->headers)) {
- $lines[] = $this->formatData($this->headers);
- }
-
- foreach ($this->datas as $data) {
- $lines[] = $this->formatData($data);
- }
-
- $this->render = implode($this->encode($this->endOfLine), $lines);
+ foreach ($this->datas as $v) {
+ $this->append($this->datasToCsvLine($v));
}
- $this->isModified = false;
-
- if ($filename !== null) {
- $content = $this->render;
-
- if ($flags === FILE_APPEND && file_exists($filename)) {
- $content = $this->endOfLine.$content;
- }
-
- file_put_contents($filename, $content, $flags);
+ if ($this->encoding !== 'UTF-8') {
+ $this->render = iconv(
+ mb_detect_encoding($this->render),
+ $this->encoding,
+ $this->render
+ );
}
return $this->render;
}
+
+ public function hasDatas()
+ {
+ return count($this->datas) > 1;
+ }
+
+ protected function datasToCsvLine($datas)
+ {
+ foreach ($datas as $k => $v) {
+ $v = str_replace('\\', '\\\\', $v);
+
+ if ($this->enclose) {
+ $v = str_replace($this->enclose, '\\'.$this->enclose, $v);
+ } else {
+ $v = str_replace($this->delimiter, '\\'.$this->delimiter, $v);
+ }
+
+ $datas[$k] = $this->enclose.$v.$this->enclose;
+ }
+
+ $datas = implode($this->delimiter, $datas);
+
+ return $datas;
+ }
+
+ protected function append($line)
+ {
+ $this->render.= sprintf("%s%s", $line, $this->endline);
+ }
+
+ public function compileToFile($filename)
+ {
+ if (file_exists($filename)) {
+ unlink($filename);
+ }
+
+ file_put_contents($filename, $this->compile());
+ }
}
diff --git a/src/Deblan/Csv/CsvParser.php b/src/Deblan/Csv/CsvParser.php
index 7d92af2..99abe49 100644
--- a/src/Deblan/Csv/CsvParser.php
+++ b/src/Deblan/Csv/CsvParser.php
@@ -2,225 +2,149 @@
namespace Deblan\Csv;
-/**
- * class Csv.
- *
- * @author Simon Vieille
- */
+use Deblan\Csv\Exception\CsvParserInvalidParameterException;
+use Deblan\Csv\Exception\CsvParserException;
+
class CsvParser
{
- /**
- * @var string
- */
- protected $delimiter = ';';
+ private $filename;
- /**
- * @var string
- */
- protected $enclosure = '"';
+ private $delimiter;
- /**
- * @var string
- */
- protected $endOfLine = "\n";
+ private $enclosure;
- /**
- * @var array
- */
- protected $datas = [];
+ private $escapeChar;
- /**
- * @var array
- */
- protected $headers = [];
+ private $hasLegend;
- /**
- * @var bool
- */
- protected $hasHeaders = false;
+ private $datas = array();
- /**
- * Set the value of "delimiter".
- *
- * @param string $delimiter
- *
- * @return Csv
- */
- public function setDelimiter($delimiter)
+ private $legend = array();
+
+ private $nullValues = array();
+
+ public function __construct($filename, $delimiter = ';', $enclosure = '"', $escapeChar = '\\', $hasLegend = false, array $nullValues = array(''))
{
- $this->delimiter = (string) $delimiter;
+ $this->setFilename($filename);
+ $this->setDelimiter($delimiter);
+ $this->setEnclosure($enclosure);
+ $this->setEscapeChar($escapeChar);
+ $this->setHasLegend($hasLegend);
+ $this->setNullValues($nullValues);
+ }
- return $this;
+ public function setFilename($v)
+ {
+ if (!is_string($v)) {
+ throw new CsvParserInvalidParameterException(sprintf('"%s" is not a valid string.', $v));
+ }
+
+ if (!file_exists($v)) {
+ throw new CsvParserException(sprintf('"%s" does not exist.', $v));
+ }
+
+ if (!is_readable($v)) {
+ throw new CsvParserException(sprintf('"%s" is not readable.', $v));
+ }
+
+ $this->filename = $v;
+ }
+
+ public function setDelimiter($v)
+ {
+ if (!is_string($v)) {
+ throw new CsvParserInvalidParameterException(sprintf('"%s" is not a valid string.', $v));
+ }
+
+ $this->delimiter = $v;
+ }
+
+ public function setEnclosure($v)
+ {
+ if (!is_string($v)) {
+ throw new CsvParserInvalidParameterException(sprintf('"%s" is not a valid string.', $v));
+ }
+
+ $this->enclosure = $v;
+ }
+
+ public function setEscapeChar($v)
+ {
+ if (!is_string($v)) {
+ throw new CsvParserInvalidParameterException(sprintf('"%s" is not a valid string.', $v));
+ }
+
+ $this->escapeChar = $v;
+ }
+
+ public function setHasLegend($v)
+ {
+ if (!is_bool($v)) {
+ throw new CsvParserInvalidParameterException(sprintf('"%s" is not a valid bool.', $v));
+ }
+
+ $this->hasLegend = $v;
+ }
+
+ public function getHasLegend()
+ {
+ return $this->hasLegend;
+ }
+
+ public function getLegend()
+ {
+ return $this->legend;
+ }
+
+ public function setNullValues(array $v)
+ {
+ $this->nullValues = $v;
}
/**
- * Get the value of "delimiter".
*
- * @return array
+ * To improve...
+ *
*/
- public function getDelimiter()
+ protected function cleanNullValues($line)
{
- return $this->delimiter;
+ return str_replace($this->nullValues, '', $line);
}
- /**
- * Set the value of "enclosure".
- *
- * @param string $enclosure
- *
- * @return Csv
- */
- public function setEnclosure($enclosure)
- {
- $this->enclosure = (string) $enclosure;
-
- return $this;
- }
-
- /**
- * Get the value of "enclosure".
- *
- * @return string
- */
- public function getEnclosure()
- {
- return $this->enclosure;
- }
-
- /**
- * Set the value of "endOfLine".
- *
- * @param string $endOfLine
- *
- * @return Csv
- */
- public function setEndOfLine($endOfLine)
- {
- $this->endOfLine = (string) $endOfLine;
-
- return $this;
- }
-
- /**
- * Get the value of "endOfLine".
- *
- * @return string
- */
- public function getEndOfLine()
- {
- return $this->endOfLine;
- }
-
- /**
- * Get the value of "hasHeaders".
- *
- * @return bool
- */
- public function getHasHeaders()
- {
- return $this->hasHeaders;
- }
-
- /**
- * Set the value of "headers".
- *
- * @param bool $hasHeaders
- *
- * @return Csv
- */
- public function setHasHeaders($hasHeaders)
- {
- $this->hasHeaders = (bool) $hasHeaders;
-
- return $this;
- }
-
- /**
- * Get the value of "headers".
- *
- * @return array
- */
- public function getHeaders()
- {
- return $this->headers;
- }
-
- /**
- * Get the value of "datas".
- *
- * @return array
- */
public function getDatas()
{
return $this->datas;
}
- /*
- * Parses a string.
- *
- * @param string $string
- *
- * @return CsvParser
- */
- public function parseString($string)
+ public function parse()
{
- $this->datas = [];
- $this->headers = [];
- $lines = str_getcsv($string, $this->endOfLine);
-
- foreach ($lines as $key => $line) {
- $data = $this->parseLine($line, $this->hasHeaders && $key === 0);
-
- if ($data === null) {
- continue;
- }
-
- if ($this->hasHeaders && $key === 0) {
- $this->headers = $data;
- } else {
- $this->datas[] = $data;
- }
+ if (!empty($this->datas)) {
+ return $this->datas;
}
- return $this;
- }
+ $lines = file($this->filename);
- /*
- * Parses a line.
- *
- * @param string $line
- * @param bool $isHeaders
- *
- * @return array
- */
- public function parseLine($line, $isHeaders = false)
- {
- $line = trim($line);
-
- if (empty($line)) {
- return null;
+ if (empty($lines)) {
+ return true;
}
- $csv = str_getcsv($line, $this->delimiter, $this->enclosure);
+ if ($this->hasLegend) {
+ $this->legend = str_getcsv($lines[0], $this->delimiter, $this->enclosure, $this->escapeChar);
+ unset($lines[0]);
+ }
- if (!$isHeaders && $this->hasHeaders && !empty($this->headers)) {
- foreach ($this->headers as $key => $header) {
- $csv[$header] = isset($csv[$key]) ? $csv[$key] : null;
+ foreach ($lines as $l => $line) {
+ $datas = str_getcsv($this->cleanNullValues($line), $this->delimiter, $this->enclosure, $this->escapeChar);
+
+ if ($this->hasLegend) {
+ foreach ($this->legend as $k => $v) {
+ $datas[$v] = isset($datas[$k]) ? $datas[$k] : null;
+ }
}
+
+ $this->datas[] = $datas;
}
- return $csv;
- }
-
- /*
- * Parses a file.
- *
- * @param string $filaname
- *
- * @return CsvParser
- */
- public function parseFile($filename)
- {
- return $this->parseString(file_get_contents($filename));
+ return true;
}
}
diff --git a/src/Deblan/Csv/CsvStreamParser.php b/src/Deblan/Csv/CsvStreamParser.php
deleted file mode 100644
index e12b7e4..0000000
--- a/src/Deblan/Csv/CsvStreamParser.php
+++ /dev/null
@@ -1,69 +0,0 @@
-
- */
-class CsvStreamParser extends CsvParser
-{
- /**
- * @var resource
- */
- protected $resource;
-
- /**
- * @var int
- */
- protected $length;
-
- /**
- * Parse a stream.
- *
- * @param resource $resource
- * @param int $length
- */
- public function parseStream($resource, ? int $length = 0): void
- {
- if (!is_resource($resource)) {
- throw new \InvalidArgumentException('First argument must be a valid resource.');
- }
-
- $this->resource = $resource;
- $this->length = $length;
- }
-
- /**
- * Get data of the stream parsing.
- *
- * @return null|array
- */
- public function getData(): ? array
- {
- $csv = fgetcsv($this->resource, $this->length, $this->delimiter, $this->enclosure);
-
- if ($csv === false) {
- return null;
- }
-
- $isHeaders = $this->hasHeaders && empty($this->headers);
-
- if ($isHeaders) {
- $this->headers = $csv;
-
- return $csv;
- }
-
- if (!$isHeaders && $this->hasHeaders && !empty($this->headers)) {
- foreach ($this->headers as $key => $header) {
- $csv[$header] = isset($csv[$key]) ? $csv[$key] : null;
- }
- }
-
- $this->datas[] = $csv;
-
- return $csv;
- }
-}
diff --git a/src/Deblan/Csv/Exception/CsvException.php b/src/Deblan/Csv/Exception/CsvException.php
new file mode 100644
index 0000000..c7369b3
--- /dev/null
+++ b/src/Deblan/Csv/Exception/CsvException.php
@@ -0,0 +1,7 @@
+assertEquals(';', $parser->getDelimiter());
- $parser->setDelimiter('#');
- $this->assertEquals('#', $parser->getDelimiter());
-
- $parser = new CsvParser();
- $this->assertEquals("\n", $parser->getEndOfLine());
- $parser->setEndOfLine("\r\n");
- $this->assertEquals("\r\n", $parser->getEndOfLine());
-
- $parser = new CsvParser();
- $this->assertEquals('"', $parser->getEnclosure());
- $parser->setEnclosure("'");
- $this->assertEquals("'", $parser->getEnclosure());
-
- $parser = new CsvParser();
- $this->assertEquals([], $parser->getDatas());
- $this->assertEquals([], $parser->getHeaders());
- $this->assertEquals(false, $parser->getHasHeaders());
- $parser->setHasHeaders(true);
- $this->assertEquals(true, $parser->getHasHeaders());
- }
-
- public function testParser()
- {
- $parser = new CsvParser();
- $this->assertEquals(['foo', 'bar'], $parser->parseLine('"foo";"bar"'));
- $this->assertEquals([], $parser->getDatas());
- $this->assertEquals([], $parser->getHeaders());
-
- $parser = new CsvParser();
- $parser->parseString('"foo";"bar"');
- $this->assertEquals([['foo', 'bar']], $parser->getDatas());
- $this->assertEquals([], $parser->getHeaders());
-
- $parser = new CsvParser();
- $parser->parseString('"foo";"bar"'."\n".'"foo2";"bar2"');
- $this->assertEquals([['foo', 'bar'], ['foo2', 'bar2']], $parser->getDatas());
- $this->assertEquals([], $parser->getHeaders());
-
- $parser = new CsvParser();
- $parser->setHasHeaders(true);
- $parser->parseString('"foo";"bar"'."\n".'"foo2";"bar2"');
- $this->assertEquals([['foo2', 'bar2', 'foo' => 'foo2', 'bar' => 'bar2']], $parser->getDatas());
- $this->assertEquals(['foo', 'bar'], $parser->getHeaders());
-
- $parser = new CsvParser();
- $parser->setHasHeaders(true);
- $parser->setEnclosure(null);
- $parser->parseString('foo;bar'."\n".'foo2;bar2;boo2');
- $this->assertEquals([['foo2', 'bar2', 'boo2', 'foo' => 'foo2', 'bar' => 'bar2']], $parser->getDatas());
- $this->assertEquals(['foo', 'bar'], $parser->getHeaders());
-
- $parser = new CsvParser();
- $parser->setHasHeaders(true);
- $parser->parseString('foo;bar'."\n".'foo2');
- $this->assertEquals([['foo2', 'foo' => 'foo2', 'bar' => null]], $parser->getDatas());
- $this->assertEquals(['foo', 'bar'], $parser->getHeaders());
-
- $parser = new CsvParser();
- $parser->setHasHeaders(true);
- $parser->parseFile(__DIR__.'/fixtures/example.csv');
- $this->assertEquals(
- [
- [
- 'foo 1',
- 'bar 1',
- 'FOO' => 'foo 1',
- 'BAR' => 'bar 1',
- ],
- [
- 'foo 2',
- 'bar 2',
- 'FOO' => 'foo 2',
- 'BAR' => 'bar 2',
- ],
- [
- 'foo 3',
- 'bar 3',
- 'FOO' => 'foo 3',
- 'BAR' => 'bar 3',
- ],
- ],
- $parser->getDatas()
- );
- $this->assertEquals(['FOO', 'BAR'], $parser->getHeaders());
-
- $parser = new CsvParser();
- $parser->setHasHeaders(false);
- $parser->parseFile(__DIR__.'/fixtures/example2.csv');
- $this->assertEquals(
- [
- [
- 'foo 1',
- 'bar 1',
- ],
- [
- 'foo 2',
- 'ba"r 2',
- ],
- [
- 'foo 3',
- 'bar 3',
- ],
- ],
- $parser->getDatas()
- );
-
- $parser = new CsvParser();
- $parser->setHasHeaders(true);
- $parser->setEnclosure("'");
- $parser->setDelimiter('#');
- $parser->parseFile(__DIR__.'/fixtures/example3.csv');
- $this->assertEquals(
- [
- [
- 'foo 1',
- '',
- "FO'O" => 'foo 1',
- 'BAR' => '',
- ],
- [
- 'foo 1b',
- "FO'O" => 'foo 1b',
- 'BAR' => null,
- ],
- [
- 'foo 2',
- 'bar 2',
- 'unexpected 3',
- "FO'O" => 'foo 2',
- 'BAR' => 'bar 2',
- ],
- [
- 'foo 3',
- 'bar 3',
- "FO'O" => 'foo 3',
- 'BAR' => 'bar 3',
- ],
- ],
- $parser->getDatas()
- );
-
- $parser = new CsvParser();
- $parser->setHasHeaders(true);
- $parser->setEnclosure("'");
- $parser->setDelimiter('#');
- $parser->setEndOfLine("\r\n");
- $parser->parseFile(__DIR__.'/fixtures/example4.csv');
- $this->assertEquals(
- [
- [
- 'foo 1',
- '',
- "FO'O" => 'foo 1',
- 'BAR' => '',
- ],
- [
- 'foo 1b',
- "FO'O" => 'foo 1b',
- 'BAR' => null,
- ],
- [
- 'foo 2',
- 'bar 2',
- 'unexpected 3',
- "FO'O" => 'foo 2',
- 'BAR' => 'bar 2',
- ],
- [
- 'foo 3',
- 'bar 3',
- "FO'O" => 'foo 3',
- 'BAR' => 'bar 3',
- ],
- ],
- $parser->getDatas()
- );
- }
+ public function testTest()
+ {
+ }
}
diff --git a/tests/CsvStreamParserTest.php b/tests/CsvStreamParserTest.php
deleted file mode 100644
index 8a6fb8c..0000000
--- a/tests/CsvStreamParserTest.php
+++ /dev/null
@@ -1,176 +0,0 @@
-assertEquals([], $parser->getDatas());
- $this->assertEquals([], $parser->getHeaders());
-
- $parser = new CsvStreamParser();
- $this->expectException('\InvalidArgumentException');
- $parser->parseStream(null);
- }
-
- public function testStreamParser2()
- {
- $parser = new CsvStreamParser();
- $parser->setHasHeaders(true);
-
- $parser->parseStream(fopen(__DIR__.'/fixtures/example.csv', 'r'));
- $this->assertEquals([], $parser->getDatas());
- $this->assertEquals([], $parser->getHeaders());
-
- $this->assertEquals([
- 'FOO',
- 'BAR',
- ], $parser->getData());
- $this->assertEquals([], $parser->getDatas());
- $this->assertEquals(['FOO', 'BAR'], $parser->getHeaders());
-
- $this->assertEquals([
- 'foo 1',
- 'bar 1',
- 'FOO' => 'foo 1',
- 'BAR' => 'bar 1',
- ], $parser->getData());
- $this->assertEquals([
- [
- 'foo 1',
- 'bar 1',
- 'FOO' => 'foo 1',
- 'BAR' => 'bar 1',
- ],
- ], $parser->getDatas());
- $this->assertEquals(['FOO', 'BAR'], $parser->getHeaders());
-
- $parser->getData();
- $this->assertEquals([
- [
- 'foo 1',
- 'bar 1',
- 'FOO' => 'foo 1',
- 'BAR' => 'bar 1',
- ],
- [
- 'foo 2',
- 'bar 2',
- 'FOO' => 'foo 2',
- 'BAR' => 'bar 2',
- ],
- ], $parser->getDatas());
- $this->assertEquals(['FOO', 'BAR'], $parser->getHeaders());
-
- $parser->getData();
- $this->assertEquals([
- [
- 'foo 1',
- 'bar 1',
- 'FOO' => 'foo 1',
- 'BAR' => 'bar 1',
- ],
- [
- 'foo 2',
- 'bar 2',
- 'FOO' => 'foo 2',
- 'BAR' => 'bar 2',
- ],
- [
- 'foo 3',
- 'bar 3',
- 'FOO' => 'foo 3',
- 'BAR' => 'bar 3',
- ],
- ], $parser->getDatas());
- $this->assertEquals(['FOO', 'BAR'], $parser->getHeaders());
- }
-
- public function testStreamParser3()
- {
- $parser = new CsvStreamParser();
- $parser->setHasHeaders(false);
-
- $parser->parseStream(fopen(__DIR__.'/fixtures/example.csv', 'r'));
- $this->assertEquals([], $parser->getDatas());
- $this->assertEquals([], $parser->getHeaders());
-
- $this->assertEquals([
- 'FOO',
- 'BAR'
- ], $parser->getData());
- $this->assertEquals([
- [
- 'FOO',
- 'BAR'
- ]
- ], $parser->getDatas());
- $this->assertEquals([], $parser->getHeaders());
-
- $this->assertEquals([
- 'foo 1',
- 'bar 1',
- ], $parser->getData());
- $this->assertEquals([
- [
- 'FOO',
- 'BAR',
- ],
- [
- 'foo 1',
- 'bar 1',
- ],
- ], $parser->getDatas());
- $this->assertEquals([], $parser->getHeaders());
-
- $this->assertEquals([
- 'foo 2',
- 'bar 2',
- ], $parser->getData());
- $this->assertEquals([
- [
- 'FOO',
- 'BAR',
- ],
- [
- 'foo 1',
- 'bar 1',
- ],
- [
- 'foo 2',
- 'bar 2',
- ],
- ], $parser->getDatas());
- $this->assertEquals([], $parser->getHeaders());
-
- $this->assertEquals([
- 'foo 3',
- 'bar 3',
- ], $parser->getData());
- $this->assertEquals([
- [
- 'FOO',
- 'BAR',
- ],
- [
- 'foo 1',
- 'bar 1',
- ],
- [
- 'foo 2',
- 'bar 2',
- ],
- [
- 'foo 3',
- 'bar 3',
- ],
- ], $parser->getDatas());
- $this->assertEquals([], $parser->getHeaders());
-
- $this->assertEquals(null, $parser->getData());
- }
-}
diff --git a/tests/CsvTest.php b/tests/CsvTest.php
index ebea607..4ae789c 100644
--- a/tests/CsvTest.php
+++ b/tests/CsvTest.php
@@ -1,143 +1,94 @@
- */
-class CsvTest extends TestCase
+class CsvTest extends \PHPUnit_Framework_TestCase
{
- public function testGettersAndSettersAndDefaultValues()
+ public function testAddLine()
{
$csv = new Csv();
- $this->assertEquals(';', $csv->getDelimiter());
- $csv->setDelimiter('#');
- $this->assertEquals('#', $csv->getDelimiter());
+ $csv->addLine(array('foo', 'bar'));
+ $this->assertEquals('"foo";"bar"'."\n", $csv->compile());
+ }
+
+ public function testSetLegend()
+ {
+ $csv = new Csv();
+
+ $this->assertEquals(false, $csv->getHasLegend());
+
+ $csv->setLegend($a = array('bim', 'bam'));
+
+ $this->assertEquals($a, $csv->getLegend());
+
+ $csv->addLine(array('foo', 'bar'));
+
+ $this->assertEquals(true, $csv->getHasLegend());
+ $this->assertEquals(
+ '"bim";"bam"'."\n".
+ '"foo";"bar"'."\n",
+ $csv->compile()
+ );
+
+ $csv = new Csv();
+
+ $csv->addLine(array('foo', 'bar'));
+ $csv->setLegend(array('bim', 'bam'));
+
+ $this->assertEquals(true, $csv->getHasLegend());
+ $this->assertEquals(
+ '"bim";"bam"'."\n".
+ '"foo";"bar"'."\n",
+ $csv->compile()
+ );
+ }
+
+ public function testHasDatas()
+ {
+ $csv = new Csv();
+ $this->assertEquals(false, $csv->hasDatas());
+
+ $csv->setLegend(array('bim', 'bam'));
+ $this->assertEquals(false, $csv->hasDatas());
+
+ $csv->addLine(array('foo', 'bar'));
+ $this->assertEquals(true, $csv->hasDatas());
+
+ $csv = new Csv();
+ $csv->addLine(array('foo', 'bar'));
+ $this->assertEquals(true, $csv->hasDatas());
+ }
+
+ public function testDatasToCsvLine()
+ {
+ $csv = new Csv();
+ $csv->addLine(array('fo\\o', 'bar'));
+ $this->assertEquals('"fo\\\\o";"bar"'."\n", $csv->compile());
+
+ $csv = new Csv();
+ $csv->setDelimiter(':');
+ $csv->addLine(array('foo', 'bar'));
+ $this->assertEquals('"foo":"bar"'."\n", $csv->compile());
+
+ $csv = new Csv();
+ $csv->setDelimiter(':');
+ $csv->addLine(array('fo:o', 'bar'));
+ $this->assertEquals('"fo:o":"bar"'."\n", $csv->compile());
+
+ $csv = new Csv();
+ $csv->setDelimiter(':');
+ $csv->setEnclosure('');
+ $csv->addLine(array('fo:o', 'bar'));
+ $this->assertEquals('fo\\:o:bar'."\n", $csv->compile());
$csv = new Csv();
- $this->assertEquals('"', $csv->getEnclosure());
$csv->setEnclosure('#');
- $this->assertEquals('#', $csv->getEnclosure());
+ $csv->addLine(array('foo', 'bar'));
+ $this->assertEquals('#foo#;#bar#'."\n", $csv->compile());
$csv = new Csv();
- $this->assertEquals("\n", $csv->getEndOfLine());
- $csv->setEndOfLine("\r\n");
- $this->assertEquals("\r\n", $csv->getEndOfLine());
-
- $csv = new Csv();
- $this->assertEquals([], $csv->getDatas());
- $csv->setDatas([['a', 'b', 'c'], ['d', 'e', 'f']]);
- $this->assertEquals([['a', 'b', 'c'], ['d', 'e', 'f']], $csv->getDatas());
-
- $csv = new Csv();
- $this->assertEquals([], $csv->getHeaders());
- $csv->setHeaders(['a', 'b', 'c']);
- $this->assertEquals(['a', 'b', 'c'], $csv->getHeaders());
-
- $csv = new Csv();
- $this->assertEquals('UTF-8', $csv->getCharset());
- $csv->setCharset('ISO-8859-1');
- $this->assertEquals('ISO-8859-1', $csv->getCharset());
- }
-
- public function testRender()
- {
- $csv = new Csv();
- $this->assertEquals(null, $csv->render());
- $csv->addData(['foo', 'bar']);
- $this->assertEquals('"foo";"bar"', $csv->render());
-
- $csv = new Csv();
- $csv->appendData(['foo', 'bar']);
- $csv->appendData(['foo2', 'bar2']);
- $this->assertEquals('"foo";"bar"'."\n".'"foo2";"bar2"', $csv->render());
-
- $csv = new Csv();
- $csv->preprendData(['foo2', 'bar2']);
- $csv->preprendData(['foo', 'bar']);
- $this->assertEquals('"foo";"bar"'."\n".'"foo2";"bar2"', $csv->render());
-
- $csv = new Csv();
- $csv->addData(['foo', 'bar']);
- $csv->preprendData(['foo2', 'bar2']);
- $csv->appendData(['foo3', 'bar3']);
- $this->assertEquals('"foo2";"bar2"'."\n".'"foo";"bar"'."\n".'"foo3";"bar3"', $csv->render());
-
- $csv = new Csv();
- $csv->setHeaders(['a', 'b']);
- $csv->addData(['foo', 'bar']);
- $this->assertEquals('"a";"b"'."\n".'"foo";"bar"', $csv->render());
-
- $csv = new Csv();
- $csv->setHeaders(['a"b', 'cd"']);
- $csv->addData(['f"oo', 'b""ar']);
- $this->assertEquals('"a""b";"cd"""'."\n".'"f""oo";"b""""ar"', $csv->render());
-
- $csv = new Csv();
- $csv->addData(['foo', 'bar']);
- $csv->setHeaders(['a', 'b']);
- $this->assertEquals('"a";"b"'."\n".'"foo";"bar"', $csv->render());
-
- $csv = new Csv();
- $csv->addData(['foo', 'bar']);
- $csv->addData(['foo2', 'bar2']);
- $csv->setHeaders(['a', 'b']);
- $csv->setEndOfLine("\r\n");
- $this->assertEquals('"a";"b"'."\r\n".'"foo";"bar"'."\r\n".'"foo2";"bar2"', $csv->render());
-
- $csv = new Csv();
- $csv->setHeaders(['a', "b'd"]);
- $csv->addData(["fo'o", 'bar']);
- $csv->setEnclosure("'");
- $this->assertEquals("'a';'b''d'"."\n"."'fo''o';'bar'", $csv->render());
-
- $csv = new Csv();
- $csv->setHeaders(['a', 'b']);
- $csv->addData(['foo', 'bar']);
- $csv->setDelimiter('#');
- $this->assertEquals('"a"#"b"'."\n".'"foo"#"bar"', $csv->render());
-
- $filename = tempnam(sys_get_temp_dir(), 'csvtests');
-
- $csv = new Csv();
- $csv->setHeaders(['a', 'b']);
- $csv->addData(['foo', 'bar']);
- $render = $csv->render($filename);
- $this->assertEquals('"a";"b"'."\n".'"foo";"bar"', $render);
- $this->assertEquals('"a";"b"'."\n".'"foo";"bar"', file_get_contents($filename));
- $render = $csv->render($filename);
- $this->assertEquals('"a";"b"'."\n".'"foo";"bar"', $render);
- $this->assertEquals('"a";"b"'."\n".'"foo";"bar"', file_get_contents($filename));
-
- unlink($filename);
-
- $csv = new Csv();
- $csv->setHeaders(['a', 'b']);
- $csv->addData(['foo', 'bar']);
- $csv->render($filename);
-
- $csv = new Csv();
- $csv->addData(['foo2', 'bar2']);
- $render = $csv->render($filename, FILE_APPEND);
- $this->assertEquals('"a";"b"'."\n".'"foo";"bar"'."\n".'"foo2";"bar2"', file_get_contents($filename));
-
- unlink($filename);
- }
-
- public function testEncoding()
- {
- $csv = new Csv();
- $csv->addData(['é']);
- $render = $csv->render();
- $this->assertEquals('"é"', $csv->render());
-
- $csv = new Csv();
- $csv->addData(['é']);
- $csv->setCharset('ISO-8859-1');
- $render = $csv->render();
- $this->assertEquals('"é"', utf8_encode($csv->render()));
+ $csv->setEnclosure('#');
+ $csv->addLine(array('f#oo', 'bar'));
+ $this->assertEquals('#f\\#oo#;#bar#'."\n", $csv->compile());
}
}
diff --git a/tests/fixtures/example.csv b/tests/fixtures/example.csv
deleted file mode 100644
index d6b62ce..0000000
--- a/tests/fixtures/example.csv
+++ /dev/null
@@ -1,4 +0,0 @@
-"FOO";"BAR"
-"foo 1";"bar 1"
-"foo 2";"bar 2"
-"foo 3";"bar 3"
diff --git a/tests/fixtures/example2.csv b/tests/fixtures/example2.csv
deleted file mode 100644
index a4e9ac5..0000000
--- a/tests/fixtures/example2.csv
+++ /dev/null
@@ -1,3 +0,0 @@
-"foo 1";"bar 1"
-"foo 2";"ba""r 2"
-"foo 3";"bar 3"
diff --git a/tests/fixtures/example3.csv b/tests/fixtures/example3.csv
deleted file mode 100644
index 9077a11..0000000
--- a/tests/fixtures/example3.csv
+++ /dev/null
@@ -1,5 +0,0 @@
-'FO''O'#'BAR'
-'foo 1'#
-'foo 1b'
-'foo 2'#'bar 2'#'unexpected 3'
-'foo 3'#'bar 3'
diff --git a/tests/fixtures/example4.csv b/tests/fixtures/example4.csv
deleted file mode 100644
index e56aef3..0000000
--- a/tests/fixtures/example4.csv
+++ /dev/null
@@ -1,5 +0,0 @@
-'FO''O'#'BAR'
-'foo 1'#
-'foo 1b'
-'foo 2'#'bar 2'#'unexpected 3'
-'foo 3'#'bar 3'