diff options
-rw-r--r-- | src/Reader.php | 78 | ||||
-rw-r--r-- | test/ReaderTest.php | 41 |
2 files changed, 76 insertions, 43 deletions
diff --git a/src/Reader.php b/src/Reader.php index 23c0e90..2d53b71 100644 --- a/src/Reader.php +++ b/src/Reader.php @@ -18,6 +18,7 @@ use Iterator; use League\Csv\Modifier\MapIterator; use LimitIterator; use SplFileObject; +use UnexpectedValueException; /** * A class to manage extracting and filtering a CSV @@ -28,9 +29,9 @@ use SplFileObject; */ class Reader extends AbstractCsv { - const FETCH_ARRAY = 1; + const TYPE_ARRAY = 1; - const FETCH_ITERATOR = 2; + const TYPE_ITERATOR = 2; /** * @inheritdoc @@ -38,34 +39,38 @@ class Reader extends AbstractCsv protected $stream_filter_mode = STREAM_FILTER_READ; /** - * Reader fetch mode + * Reader return type * * @var int */ - protected $fetchMode = self::FETCH_ARRAY; + protected $returnType = self::TYPE_ARRAY; /** - * returns the current fetch mode + * Returns the return type for the next fetch call * * @return int */ - public function getFetchMode() + public function getReturnType() { - return $this->fetchMode; + return $this->returnType; } /** - * Set the Reader fetch mode for the next call + * Set the return type for the next fetch call * - * @param static + * @param int $type + * + * @throws UnexpectedValueException If the value is not one of the defined constant + * + * @return static */ - public function setFetchMode($mode) + public function setReturnType($type) { - $modes = [static::FETCH_ARRAY => 1, static::FETCH_ITERATOR => 1]; - if (!isset($modes[$mode])) { - throw new InvalidArgumentException('Unknown return type mode'); + $modes = [static::TYPE_ARRAY => 1, static::TYPE_ITERATOR => 1]; + if (!isset($modes[$type])) { + throw new UnexpectedValueException('Unknown return type'); } - $this->fetchMode = $mode; + $this->returnType = $type; return $this; } @@ -87,6 +92,7 @@ class Reader extends AbstractCsv $iterator = $this->applyIteratorFilter($iterator); $iterator = $this->applyIteratorSortBy($iterator); $iterator = $this->applyIteratorInterval($iterator); + $this->returnType = static::TYPE_ARRAY; if (!is_null($callable)) { return new MapIterator($iterator, $callable); } @@ -184,44 +190,45 @@ class Reader extends AbstractCsv }; $this->addFilter($filterColumn); + $type = $this->returnType; $iterator = $this->fetch($selectColumn); if (!is_null($callable)) { $iterator = new MapIterator($iterator, $callable); } - return $this->toArray($iterator, false); + return $this->applyReturnType($type, $iterator, false); } /** - * Convert the Iterator into an array depending on the class fetchMode + * Validate a CSV row index * - * @param Iterator $iterator - * @param bool $use_keys Whether to use the iterator element keys as index + * @param int $index * - * @return Iterator|array + * @throws InvalidArgumentException If the column index is not a positive integer or 0 */ - protected function toArray(Iterator $iterator, $use_keys = true) + protected function assertValidColumnIndex($index) { - if (static::FETCH_ARRAY == $this->fetchMode) { - return iterator_to_array($iterator, $use_keys); + if (false === filter_var($index, FILTER_VALIDATE_INT, ['options' => ['min_range' => 0]])) { + throw new InvalidArgumentException('the column index must be a positive integer or 0'); } - $this->fetchMode = static::FETCH_ARRAY; - - return $iterator; } /** - * Validate a CSV row index + * Convert the Iterator into an array depending on the class returnType * - * @param int $index + * @param int $type + * @param Iterator $iterator + * @param bool $use_keys Whether to use the iterator element keys as index * - * @throws InvalidArgumentException If the column index is not a positive integer or 0 + * @return Iterator|array */ - protected function assertValidColumnIndex($index) + protected function applyReturnType($type, Iterator $iterator, $use_keys = true) { - if (false === filter_var($index, FILTER_VALIDATE_INT, ['options' => ['min_range' => 0]])) { - throw new InvalidArgumentException('the column index must be a positive integer or 0'); + if (static::TYPE_ARRAY == $type) { + return iterator_to_array($iterator, $use_keys); } + + return $iterator; } /** @@ -251,13 +258,14 @@ class Reader extends AbstractCsv return [$row[$offsetColumnIndex], $row[$valueColumnIndex]]; }; $this->addFilter($filterPairs); + $type = $this->returnType; $iterator = $this->fetch($selectPairs); if (!is_null($callable)) { $iterator = new MapIterator($iterator, $callable); } - return $this->toArray($this->fetchPairsGenerator($iterator), true); + return $this->applyReturnType($type, $this->fetchPairsGenerator($iterator), true); } /** @@ -301,7 +309,11 @@ class Reader extends AbstractCsv return array_combine($keys, $row); }; - return $this->toArray(new MapIterator($this->fetch($callable), $combineArray), false); + return $this->applyReturnType( + $this->returnType, + new MapIterator($this->fetch($callable), $combineArray), + false + ); } /** diff --git a/test/ReaderTest.php b/test/ReaderTest.php index 4ff96dc..9a0c630 100644 --- a/test/ReaderTest.php +++ b/test/ReaderTest.php @@ -165,7 +165,7 @@ class ReaderTest extends AbstractTestCase public function testFetchAssocReturnsIterator() { $keys = ['firstname', 'lastname', 'email']; - $res = $this->csv->setFetchMode(Reader::FETCH_ITERATOR)->fetchAssoc($keys); + $res = $this->csv->setReturnType(Reader::TYPE_ITERATOR)->fetchAssoc($keys); $this->assertInstanceof('\Iterator', $res); foreach ($res as $offset => $row) { $this->assertSame($keys, array_keys($row)); @@ -375,8 +375,8 @@ class ReaderTest extends AbstractTestCase public function testFetchColumnReturnsIterator() { - $this->assertContains('john', $this->csv->setFetchMode(Reader::FETCH_ITERATOR)->fetchColumn(0)); - $this->assertContains('jane', $this->csv->setFetchMode(Reader::FETCH_ITERATOR)->fetchColumn()); + $this->assertContains('john', $this->csv->setReturnType(Reader::TYPE_ITERATOR)->fetchColumn(0)); + $this->assertContains('jane', $this->csv->setReturnType(Reader::TYPE_ITERATOR)->fetchColumn()); } public function testFetchColumnInconsistentColumnCSV() @@ -478,7 +478,7 @@ class ReaderTest extends AbstractTestCase */ public function testFetchPairsIteratorMode($key, $value, $callable, $expected) { - $iterator = $this->csv->setFetchMode(Reader::FETCH_ITERATOR)->fetchPairs($key, $value, $callable); + $iterator = $this->csv->setReturnType(Reader::TYPE_ITERATOR)->fetchPairs($key, $value, $callable); foreach ($iterator as $key => $value) { $res = current($expected); $this->assertSame($value, $res[$key]); @@ -563,13 +563,34 @@ class ReaderTest extends AbstractTestCase } /** - * @expectedException \InvalidArgumentException + * @expectedException \UnexpectedValueException + */ + public function testReturnTypeThrowsException() + { + $this->csv->setReturnType('toto'); + } + + /** + * @dataProvider readerReturnTypeProvider */ - public function testFetchMode() + public function testReturnTypeResetBetweenCallToArray($method, array $args = []) { - $this->assertSame(Reader::FETCH_ARRAY, $this->csv->getFetchMode()); - $this->csv->setFetchMode(Reader::FETCH_ITERATOR); - $this->assertSame(Reader::FETCH_ITERATOR, $this->csv->getFetchMode()); - $this->csv->setFetchMode('toto'); + $this->assertSame(Reader::TYPE_ARRAY, $this->csv->getReturnType()); + $this->csv->setReturnType(Reader::TYPE_ITERATOR); + call_user_func_array([$this->csv, $method], $args); + $this->assertSame(Reader::TYPE_ARRAY, $this->csv->getReturnType()); + } + + public function readerReturnTypeProvider() + { + return [ + ['fetch'], + ['fetchOne'], + ['fetchAll'], + ['fetchColumn'], + ['fetchPairs'], + ['fetchAssoc'], + ['each', [function (array $row) { return true; }]], + ]; } } |