From 102e17159c27e3fd563b815b5c868125f13df83d Mon Sep 17 00:00:00 2001 From: Adrien Loison Date: Sat, 18 Nov 2017 23:05:09 +0100 Subject: [PATCH] Make ODS reader return Row object --- src/Spout/Common/Helper/CellTypeHelper.php | 14 +++ src/Spout/Reader/Common/Entity/Cell.php | 20 +++- src/Spout/Reader/Common/Entity/Row.php | 2 +- .../Exception/InvalidValueException.php | 34 +++++++ .../ODS/Creator/InternalEntityFactory.php | 30 +++++- .../Reader/ODS/Creator/ManagerFactory.php | 20 ++++ .../Reader/ODS/Helper/CellValueFormatter.php | 19 ++-- src/Spout/Reader/ODS/Manager/RowManager.php | 29 ++++++ src/Spout/Reader/ODS/RowIterator.php | 93 ++++++++++++------- src/Spout/Reader/ReaderFactory.php | 3 +- .../Reader/XLSX/Helper/CellValueFormatter.php | 25 ++--- src/Spout/Reader/XLSX/RowIterator.php | 11 ++- .../Reader/ODS/Manager/RowManagerTest.php | 41 ++++++++ tests/Spout/Reader/ODS/ReaderTest.php | 7 +- .../XLSX/Helper/CellValueFormatterTest.php | 18 ++-- .../Reader/XLSX/Manager/RowManagerTest.php | 2 +- 16 files changed, 301 insertions(+), 67 deletions(-) create mode 100644 src/Spout/Reader/Exception/InvalidValueException.php create mode 100644 src/Spout/Reader/ODS/Creator/ManagerFactory.php create mode 100644 src/Spout/Reader/ODS/Manager/RowManager.php create mode 100644 tests/Spout/Reader/ODS/Manager/RowManagerTest.php diff --git a/src/Spout/Common/Helper/CellTypeHelper.php b/src/Spout/Common/Helper/CellTypeHelper.php index b9a6407..03d26a3 100644 --- a/src/Spout/Common/Helper/CellTypeHelper.php +++ b/src/Spout/Common/Helper/CellTypeHelper.php @@ -51,4 +51,18 @@ class CellTypeHelper { return gettype($value) === 'boolean'; } + + /** + * Returns whether the given value is a DateTime or DateInterval object. + * + * @param $value + * @return bool Whether the given value is a DateTime or DateInterval object + */ + public static function isDateTimeOrDateInterval($value) + { + return ( + $value instanceof \DateTime || + $value instanceof \DateInterval + ); + } } diff --git a/src/Spout/Reader/Common/Entity/Cell.php b/src/Spout/Reader/Common/Entity/Cell.php index 7b184cf..facf148 100644 --- a/src/Spout/Reader/Common/Entity/Cell.php +++ b/src/Spout/Reader/Common/Entity/Cell.php @@ -35,10 +35,15 @@ class Cell */ const TYPE_BOOLEAN = 4; + /** + * Date cell type + */ + const TYPE_DATE = 5; + /** * Error cell type */ - const TYPE_ERROR = 5; + const TYPE_ERROR = 6; /** * The value of this cell @@ -85,6 +90,14 @@ class Cell return $this->type; } + /** + * @param int $type + */ + public function setType($type) + { + $this->type = $type; + } + /** * Get the current value type * @@ -99,9 +112,12 @@ class Cell if (CellTypeHelper::isEmpty($value)) { return self::TYPE_EMPTY; } - if (CellTypeHelper::isNumeric($this->getValue())) { + if (CellTypeHelper::isNumeric($value)) { return self::TYPE_NUMERIC; } + if (CellTypeHelper::isDateTimeOrDateInterval($value)) { + return self::TYPE_DATE; + } if (CellTypeHelper::isNonEmptyString($value)) { return self::TYPE_STRING; } diff --git a/src/Spout/Reader/Common/Entity/Row.php b/src/Spout/Reader/Common/Entity/Row.php index 818cfdd..a63414a 100644 --- a/src/Spout/Reader/Common/Entity/Row.php +++ b/src/Spout/Reader/Common/Entity/Row.php @@ -71,7 +71,7 @@ class Row public function toArray() { return array_map(function (Cell $cell) { - return $cell->getValue(); + return !$cell->isError() ? $cell->getValue() : null; }, $this->cells); } } diff --git a/src/Spout/Reader/Exception/InvalidValueException.php b/src/Spout/Reader/Exception/InvalidValueException.php new file mode 100644 index 0000000..6ed0b6d --- /dev/null +++ b/src/Spout/Reader/Exception/InvalidValueException.php @@ -0,0 +1,34 @@ +invalidValue = $invalidValue; + parent::__construct($message, $code, $previous); + } + + /** + * @return mixed + */ + public function getInvalidValue() + { + return $this->invalidValue; + } +} diff --git a/src/Spout/Reader/ODS/Creator/InternalEntityFactory.php b/src/Spout/Reader/ODS/Creator/InternalEntityFactory.php index 5e89fb7..7df4d8b 100644 --- a/src/Spout/Reader/ODS/Creator/InternalEntityFactory.php +++ b/src/Spout/Reader/ODS/Creator/InternalEntityFactory.php @@ -3,7 +3,9 @@ namespace Box\Spout\Reader\ODS\Creator; use Box\Spout\Reader\Common\Creator\InternalEntityFactoryInterface; +use Box\Spout\Reader\Common\Entity\Cell; use Box\Spout\Reader\Common\Entity\Options; +use Box\Spout\Reader\Common\Entity\Row; use Box\Spout\Reader\Common\XMLProcessor; use Box\Spout\Reader\ODS\RowIterator; use Box\Spout\Reader\ODS\Sheet; @@ -19,12 +21,17 @@ class InternalEntityFactory implements InternalEntityFactoryInterface /** @var HelperFactory */ private $helperFactory; + /** @var ManagerFactory */ + private $managerFactory; + /** * @param HelperFactory $helperFactory + * @param ManagerFactory $managerFactory */ - public function __construct(HelperFactory $helperFactory) + public function __construct(HelperFactory $helperFactory, ManagerFactory $managerFactory) { $this->helperFactory = $helperFactory; + $this->managerFactory = $managerFactory; } /** @@ -66,8 +73,27 @@ class InternalEntityFactory implements InternalEntityFactoryInterface $shouldFormatDates = $optionsManager->getOption(Options::SHOULD_FORMAT_DATES); $cellValueFormatter = $this->helperFactory->createCellValueFormatter($shouldFormatDates); $xmlProcessor = $this->createXMLProcessor($xmlReader); + $rowManager = $this->managerFactory->createRowManager(); - return new RowIterator($xmlReader, $optionsManager, $cellValueFormatter, $xmlProcessor); + return new RowIterator($xmlReader, $optionsManager, $cellValueFormatter, $xmlProcessor, $rowManager, $this); + } + + /** + * @param Cell[] $cells + * @return Row + */ + public function createRow(array $cells) + { + return new Row($cells); + } + + /** + * @param mixed $cellValue + * @return Cell + */ + public function createCell($cellValue) + { + return new Cell($cellValue); } /** diff --git a/src/Spout/Reader/ODS/Creator/ManagerFactory.php b/src/Spout/Reader/ODS/Creator/ManagerFactory.php new file mode 100644 index 0000000..2543bdc --- /dev/null +++ b/src/Spout/Reader/ODS/Creator/ManagerFactory.php @@ -0,0 +1,20 @@ +nodeValue; } else { // otherwise, get it from the "date-value" attribute + $nodeValue = $node->getAttribute(self::XML_ATTRIBUTE_DATE_VALUE); try { - $nodeValue = $node->getAttribute(self::XML_ATTRIBUTE_DATE_VALUE); $cellValue = new \DateTime($nodeValue); } catch (\Exception $e) { - $cellValue = null; + throw new InvalidValueException($nodeValue); } } @@ -180,7 +184,8 @@ class CellValueFormatter * Returns the cell Time value from the given node. * * @param \DOMNode $node - * @return \DateInterval|string|null The value associated with the cell or NULL if invalid time value + * @throws InvalidValueException If the value is not a valid time + * @return \DateInterval|string The value associated with the cell */ protected function formatTimeCellValue($node) { @@ -195,11 +200,11 @@ class CellValueFormatter $cellValue = $nodeWithValueAlreadyFormatted->nodeValue; } else { // otherwise, get it from the "time-value" attribute + $nodeValue = $node->getAttribute(self::XML_ATTRIBUTE_TIME_VALUE); try { - $nodeValue = $node->getAttribute(self::XML_ATTRIBUTE_TIME_VALUE); $cellValue = new \DateInterval($nodeValue); } catch (\Exception $e) { - $cellValue = null; + throw new InvalidValueException($nodeValue); } } diff --git a/src/Spout/Reader/ODS/Manager/RowManager.php b/src/Spout/Reader/ODS/Manager/RowManager.php new file mode 100644 index 0000000..d9e8970 --- /dev/null +++ b/src/Spout/Reader/ODS/Manager/RowManager.php @@ -0,0 +1,29 @@ +getCells() as $cell) { + if (!$cell->isEmpty()) { + return false; + } + } + + return true; + } +} diff --git a/src/Spout/Reader/ODS/RowIterator.php b/src/Spout/Reader/ODS/RowIterator.php index 6af8a8d..e41a14d 100644 --- a/src/Spout/Reader/ODS/RowIterator.php +++ b/src/Spout/Reader/ODS/RowIterator.php @@ -3,12 +3,18 @@ namespace Box\Spout\Reader\ODS; use Box\Spout\Common\Exception\IOException; +use Box\Spout\Common\Manager\OptionsManagerInterface; +use Box\Spout\Reader\Common\Entity\Cell; use Box\Spout\Reader\Common\Entity\Options; +use Box\Spout\Reader\Common\Entity\Row; use Box\Spout\Reader\Common\XMLProcessor; +use Box\Spout\Reader\Exception\InvalidValueException; use Box\Spout\Reader\Exception\IteratorNotRewindableException; use Box\Spout\Reader\Exception\XMLProcessingException; use Box\Spout\Reader\IteratorInterface; +use Box\Spout\Reader\ODS\Creator\InternalEntityFactory; use Box\Spout\Reader\ODS\Helper\CellValueFormatter; +use Box\Spout\Reader\ODS\Manager\RowManager; use Box\Spout\Reader\Wrapper\XMLReader; /** @@ -38,14 +44,20 @@ class RowIterator implements IteratorInterface /** @var Helper\CellValueFormatter Helper to format cell values */ protected $cellValueFormatter; + /** @var RowManager Manages rows */ + protected $rowManager; + + /** @var InternalEntityFactory Factory to create entities */ + protected $entityFactory; + /** @var bool Whether the iterator has already been rewound once */ protected $hasAlreadyBeenRewound = false; - /** @var array Contains the data for the currently processed row (key = cell index, value = cell value) */ - protected $currentlyProcessedRowData = []; + /** @var Row The currently processed row */ + protected $currentlyProcessedRow; - /** @var array|null Buffer used to store the row data, while checking if there are more rows to read */ - protected $rowDataBuffer; + /** @var Row Buffer used to store the current row, while checking if there are more rows to read */ + protected $rowBuffer; /** @var bool Indicates whether all rows have been read */ protected $hasReachedEndOfFile = false; @@ -56,8 +68,8 @@ class RowIterator implements IteratorInterface /** @var int Row index to be processed next (one-based) */ protected $nextRowIndexToBeProcessed = 1; - /** @var mixed|null Value of the last processed cell (because when reading cell at column N+1, cell N is processed) */ - protected $lastProcessedCellValue; + /** @var Cell Last processed cell (because when reading cell at column N+1, cell N is processed) */ + protected $lastProcessedCell; /** @var int Number of times the last processed row should be repeated */ protected $numRowsRepeated = 1; @@ -70,15 +82,25 @@ class RowIterator implements IteratorInterface /** * @param XMLReader $xmlReader XML Reader, positioned on the "" element - * @param \Box\Spout\Common\Manager\OptionsManagerInterface $optionsManager Reader's options manager + * @param OptionsManagerInterface $optionsManager Reader's options manager * @param CellValueFormatter $cellValueFormatter Helper to format cell values * @param XMLProcessor $xmlProcessor Helper to process XML files + * @param RowManager $rowManager Manages rows + * @param InternalEntityFactory $entityFactory Factory to create entities */ - public function __construct($xmlReader, $optionsManager, $cellValueFormatter, $xmlProcessor) - { + public function __construct( + XMLReader $xmlReader, + OptionsManagerInterface $optionsManager, + CellValueFormatter $cellValueFormatter, + XMLProcessor $xmlProcessor, + RowManager $rowManager, + InternalEntityFactory $entityFactory + ) { $this->xmlReader = $xmlReader; $this->shouldPreserveEmptyRows = $optionsManager->getOption(Options::SHOULD_PRESERVE_EMPTY_ROWS); $this->cellValueFormatter = $cellValueFormatter; + $this->entityFactory = $entityFactory; + $this->rowManager = $rowManager; // Register all callbacks to process different nodes when reading the XML file $this->xmlProcessor = $xmlProcessor; @@ -108,7 +130,7 @@ class RowIterator implements IteratorInterface $this->hasAlreadyBeenRewound = true; $this->lastRowIndexProcessed = 0; $this->nextRowIndexToBeProcessed = 1; - $this->rowDataBuffer = null; + $this->rowBuffer = null; $this->hasReachedEndOfFile = false; $this->next(); @@ -168,7 +190,7 @@ class RowIterator implements IteratorInterface */ protected function readDataForNextRow() { - $this->currentlyProcessedRowData = []; + $this->currentlyProcessedRow = $this->entityFactory->createRow([]); try { $this->xmlProcessor->readUntilStopped(); @@ -176,7 +198,7 @@ class RowIterator implements IteratorInterface throw new IOException("The sheet's data cannot be read. [{$exception->getMessage()}]"); } - $this->rowDataBuffer = $this->currentlyProcessedRowData; + $this->rowBuffer = $this->currentlyProcessedRow; } /** @@ -187,7 +209,7 @@ class RowIterator implements IteratorInterface { // Reset data from current row $this->hasAlreadyReadOneCellInCurrentRow = false; - $this->lastProcessedCellValue = null; + $this->lastProcessedCell = null; $this->numColumnsRepeated = 1; $this->numRowsRepeated = $this->getNumRowsRepeatedForCurrentNode($xmlReader); @@ -204,17 +226,17 @@ class RowIterator implements IteratorInterface // NOTE: expand() will automatically decode all XML entities of the child nodes $node = $xmlReader->expand(); - $currentCellValue = $this->getCellValue($node); + $currentCell = $this->getCell($node); // process cell N only after having read cell N+1 (see below why) if ($this->hasAlreadyReadOneCellInCurrentRow) { for ($i = 0; $i < $this->numColumnsRepeated; $i++) { - $this->currentlyProcessedRowData[] = $this->lastProcessedCellValue; + $this->currentlyProcessedRow->addCell($this->lastProcessedCell); } } $this->hasAlreadyReadOneCellInCurrentRow = true; - $this->lastProcessedCellValue = $currentCellValue; + $this->lastProcessedCell = $currentCell; $this->numColumnsRepeated = $currentNumColumnsRepeated; return XMLProcessor::PROCESSING_CONTINUE; @@ -225,7 +247,7 @@ class RowIterator implements IteratorInterface */ protected function processRowEndingNode() { - $isEmptyRow = $this->isEmptyRow($this->currentlyProcessedRowData, $this->lastProcessedCellValue); + $isEmptyRow = $this->isEmptyRow($this->currentlyProcessedRow, $this->lastProcessedCell); // if the fetched row is empty and we don't want to preserve it... if (!$this->shouldPreserveEmptyRows && $isEmptyRow) { @@ -235,6 +257,7 @@ class RowIterator implements IteratorInterface // if the row is empty, we don't want to return more than one cell $actualNumColumnsRepeated = (!$isEmptyRow) ? $this->numColumnsRepeated : 1; + $numCellsInCurrentlyProcessedRow = count($this->currentlyProcessedRow->getCells()); // Only add the value if the last read cell is not a trailing empty cell repeater in Excel. // The current count of read columns is determined by counting the values in "$this->currentlyProcessedRowData". @@ -242,9 +265,9 @@ class RowIterator implements IteratorInterface // with a number-columns-repeated value equals to the number of (supported columns - used columns). // In Excel, the number of supported columns is 16384, but we don't want to returns rows with // always 16384 cells. - if ((count($this->currentlyProcessedRowData) + $actualNumColumnsRepeated) !== self::MAX_COLUMNS_EXCEL) { + if (($numCellsInCurrentlyProcessedRow + $actualNumColumnsRepeated) !== self::MAX_COLUMNS_EXCEL) { for ($i = 0; $i < $actualNumColumnsRepeated; $i++) { - $this->currentlyProcessedRowData[] = $this->lastProcessedCellValue; + $this->currentlyProcessedRow->addCell($this->lastProcessedCell); } } @@ -291,31 +314,39 @@ class RowIterator implements IteratorInterface } /** - * Returns the (unescaped) correctly marshalled, cell value associated to the given XML node. + * Returns the cell with (unescaped) correctly marshalled, cell value associated to the given XML node. * * @param \DOMNode $node - * @return string|int|float|bool|\DateTime|\DateInterval|null The value associated with the cell, empty string if cell's type is void/undefined, null on error + * @return Cell The cell set with the associated with the cell */ - protected function getCellValue($node) + protected function getCell($node) { - return $this->cellValueFormatter->extractAndFormatNodeValue($node); + try { + $cellValue = $this->cellValueFormatter->extractAndFormatNodeValue($node); + $cell = $this->entityFactory->createCell($cellValue); + } catch (InvalidValueException $exception) { + $cell = $this->entityFactory->createCell($exception->getInvalidValue()); + $cell->setType(Cell::TYPE_ERROR); + } + + return $cell; } /** * After finishing processing each cell, a row is considered empty if it contains - * no cells or if the value of the last read cell is an empty string. + * no cells or if the last read cell is empty. * After finishing processing each cell, the last read cell is not part of the * row data yet (as we still need to apply the "num-columns-repeated" attribute). * - * @param array $rowData - * @param string|int|float|bool|\DateTime|\DateInterval|null $lastReadCellValue The value of the last read cell + * @param Row $currentRow + * @param Cell $lastReadCell The last read cell * @return bool Whether the row is empty */ - protected function isEmptyRow($rowData, $lastReadCellValue) + protected function isEmptyRow($currentRow, $lastReadCell) { return ( - count($rowData) === 0 && - (!isset($lastReadCellValue) || trim($lastReadCellValue) === '') + $this->rowManager->isEmpty($currentRow) && + (!isset($lastReadCell) || $lastReadCell->isEmpty()) ); } @@ -323,11 +354,11 @@ class RowIterator implements IteratorInterface * Return the current element, from the buffer. * @see http://php.net/manual/en/iterator.current.php * - * @return array|null + * @return Row */ public function current() { - return $this->rowDataBuffer; + return $this->rowBuffer; } /** diff --git a/src/Spout/Reader/ReaderFactory.php b/src/Spout/Reader/ReaderFactory.php index 4687cd5..881a256 100644 --- a/src/Spout/Reader/ReaderFactory.php +++ b/src/Spout/Reader/ReaderFactory.php @@ -66,7 +66,8 @@ class ReaderFactory { $optionsManager = new ODS\Manager\OptionsManager(); $helperFactory = new ODS\Creator\HelperFactory(); - $entityFactory = new ODS\Creator\InternalEntityFactory($helperFactory); + $managerFactory = new ODS\Creator\ManagerFactory(); + $entityFactory = new ODS\Creator\InternalEntityFactory($helperFactory, $managerFactory); $globalFunctionsHelper = $helperFactory->createGlobalFunctionsHelper(); return new ODS\Reader($optionsManager, $globalFunctionsHelper, $entityFactory); diff --git a/src/Spout/Reader/XLSX/Helper/CellValueFormatter.php b/src/Spout/Reader/XLSX/Helper/CellValueFormatter.php index ccf7115..fba36b1 100644 --- a/src/Spout/Reader/XLSX/Helper/CellValueFormatter.php +++ b/src/Spout/Reader/XLSX/Helper/CellValueFormatter.php @@ -2,6 +2,7 @@ namespace Box\Spout\Reader\XLSX\Helper; +use Box\Spout\Reader\Exception\InvalidValueException; use Box\Spout\Reader\XLSX\Manager\SharedStringsManager; use Box\Spout\Reader\XLSX\Manager\StyleManager; @@ -74,7 +75,8 @@ class CellValueFormatter * Returns the (unescaped) correctly marshalled, cell value associated to the given XML node. * * @param \DOMNode $node - * @return string|int|float|bool|\DateTime|null The value associated with the cell (null when the cell has an error) + * @throws InvalidValueException If the value is not valid + * @return string|int|float|bool|\DateTime The value associated with the cell */ public function extractAndFormatNodeValue($node) { @@ -101,7 +103,7 @@ class CellValueFormatter case self::CELL_TYPE_DATE: return $this->formatDateCellValue($vNodeValue); default: - return null; + throw new InvalidValueException($vNodeValue); } } @@ -124,7 +126,7 @@ class CellValueFormatter * Returns the cell String value where string is inline. * * @param \DOMNode $node - * @return string The value associated with the cell (null when the cell has an error) + * @return string The value associated with the cell */ protected function formatInlineStringCellValue($node) { @@ -140,7 +142,7 @@ class CellValueFormatter * Returns the cell String value from shared-strings file using nodeValue index. * * @param string $nodeValue - * @return string The value associated with the cell (null when the cell has an error) + * @return string The value associated with the cell */ protected function formatSharedStringCellValue($nodeValue) { @@ -157,7 +159,7 @@ class CellValueFormatter * Returns the cell String value, where string is stored in value node. * * @param string $nodeValue - * @return string The value associated with the cell (null when the cell has an error) + * @return string The value associated with the cell */ protected function formatStrCellValue($nodeValue) { @@ -173,7 +175,7 @@ class CellValueFormatter * * @param string $nodeValue * @param int $cellStyleId 0 being the default style - * @return int|float|\DateTime|null The value associated with the cell + * @return int|float|\DateTime The value associated with the cell */ protected function formatNumericCellValue($nodeValue, $cellStyleId) { @@ -202,15 +204,15 @@ class CellValueFormatter * * @param float $nodeValue * @param int $cellStyleId 0 being the default style - * @return \DateTime|null The value associated with the cell or NULL if invalid date value + * @throws InvalidValueException If the value is not a valid timestamp + * @return \DateTime The value associated with the cell */ protected function formatExcelTimestampValue($nodeValue, $cellStyleId) { if ($this->isValidTimestampValue($nodeValue)) { $cellValue = $this->formatExcelTimestampValueAsDateTimeValue($nodeValue, $cellStyleId); } else { - // invalid date - $cellValue = null; + throw new InvalidValueException($nodeValue); } return $cellValue; @@ -280,7 +282,8 @@ class CellValueFormatter * @see ECMA-376 Part 1 - ยง18.17.4 * * @param string $nodeValue ISO 8601 Date string - * @return \DateTime|string|null The value associated with the cell or NULL if invalid date value + * @throws InvalidValueException If the value is not a valid date + * @return \DateTime|string The value associated with the cell */ protected function formatDateCellValue($nodeValue) { @@ -288,7 +291,7 @@ class CellValueFormatter try { $cellValue = ($this->shouldFormatDates) ? $nodeValue : new \DateTime($nodeValue); } catch (\Exception $e) { - $cellValue = null; + throw new InvalidValueException($nodeValue); } return $cellValue; diff --git a/src/Spout/Reader/XLSX/RowIterator.php b/src/Spout/Reader/XLSX/RowIterator.php index 478faf2..5f77f2f 100644 --- a/src/Spout/Reader/XLSX/RowIterator.php +++ b/src/Spout/Reader/XLSX/RowIterator.php @@ -6,6 +6,7 @@ use Box\Spout\Common\Exception\IOException; use Box\Spout\Reader\Common\Entity\Cell; use Box\Spout\Reader\Common\Entity\Row; use Box\Spout\Reader\Common\XMLProcessor; +use Box\Spout\Reader\Exception\InvalidValueException; use Box\Spout\Reader\Exception\XMLProcessingException; use Box\Spout\Reader\IteratorInterface; use Box\Spout\Reader\Wrapper\XMLReader; @@ -356,9 +357,15 @@ class RowIterator implements IteratorInterface */ protected function getCell($node) { - $cellValue = $this->cellValueFormatter->extractAndFormatNodeValue($node); + try { + $cellValue = $this->cellValueFormatter->extractAndFormatNodeValue($node); + $cell = $this->entityFactory->createCell($cellValue); + } catch (InvalidValueException $exception) { + $cell = $this->entityFactory->createCell($exception->getInvalidValue()); + $cell->setType(Cell::TYPE_ERROR); + } - return $this->entityFactory->createCell($cellValue); + return $cell; } /** diff --git a/tests/Spout/Reader/ODS/Manager/RowManagerTest.php b/tests/Spout/Reader/ODS/Manager/RowManagerTest.php new file mode 100644 index 0000000..c0f0b6d --- /dev/null +++ b/tests/Spout/Reader/ODS/Manager/RowManagerTest.php @@ -0,0 +1,41 @@ +assertEquals($expectedIsEmpty, $rowManager->isEmpty($row)); + } +} diff --git a/tests/Spout/Reader/ODS/ReaderTest.php b/tests/Spout/Reader/ODS/ReaderTest.php index 44ad830..3f99378 100644 --- a/tests/Spout/Reader/ODS/ReaderTest.php +++ b/tests/Spout/Reader/ODS/ReaderTest.php @@ -377,6 +377,7 @@ class ReaderTest extends \PHPUnit_Framework_TestCase $allRows = []; $resourcePath = $this->getResourcePath('two_sheets_with_strings.ods'); + /** @var Reader $reader */ $reader = EntityFactory::createReader(Type::ODS); $reader->open($resourcePath); @@ -387,7 +388,7 @@ class ReaderTest extends \PHPUnit_Framework_TestCase // this loop should only add the first row of each sheet foreach ($reader->getSheetIterator() as $sheet) { foreach ($sheet->getRowIterator() as $row) { - $allRows[] = $row; + $allRows[] = $row->toArray(); break; } } @@ -395,7 +396,7 @@ class ReaderTest extends \PHPUnit_Framework_TestCase // this loop should only add the first row of the first sheet foreach ($reader->getSheetIterator() as $sheet) { foreach ($sheet->getRowIterator() as $row) { - $allRows[] = $row; + $allRows[] = $row->toArray(); break; } @@ -536,7 +537,7 @@ class ReaderTest extends \PHPUnit_Framework_TestCase foreach ($reader->getSheetIterator() as $sheetIndex => $sheet) { foreach ($sheet->getRowIterator() as $rowIndex => $row) { - $allRows[] = $row; + $allRows[] = $row->toArray(); } } diff --git a/tests/Spout/Reader/XLSX/Helper/CellValueFormatterTest.php b/tests/Spout/Reader/XLSX/Helper/CellValueFormatterTest.php index 31bebd5..288e599 100644 --- a/tests/Spout/Reader/XLSX/Helper/CellValueFormatterTest.php +++ b/tests/Spout/Reader/XLSX/Helper/CellValueFormatterTest.php @@ -3,6 +3,7 @@ namespace Box\Spout\Reader\XLSX\Helper; use Box\Spout\Common\Helper\Escaper; +use Box\Spout\Reader\Exception\InvalidValueException; use Box\Spout\Reader\XLSX\Manager\StyleManager; /** @@ -96,13 +97,18 @@ class CellValueFormatterTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue(true)); $formatter = new CellValueFormatter(null, $styleManagerMock, false, $shouldUse1904Dates, new Escaper\XLSX()); - $result = $formatter->extractAndFormatNodeValue($nodeMock); - if ($expectedDateAsString === null) { - $this->assertNull($result); - } else { - $this->assertInstanceOf('DateTime', $result); - $this->assertSame($expectedDateAsString, $result->format('Y-m-d H:i:s')); + try { + $result = $formatter->extractAndFormatNodeValue($nodeMock); + + if ($expectedDateAsString === null) { + $this->fail('An exception should have been thrown'); + } else { + $this->assertInstanceOf('DateTime', $result); + $this->assertSame($expectedDateAsString, $result->format('Y-m-d H:i:s')); + } + } catch (InvalidValueException $exception) { + // do nothing } } diff --git a/tests/Spout/Reader/XLSX/Manager/RowManagerTest.php b/tests/Spout/Reader/XLSX/Manager/RowManagerTest.php index b0c25f4..91dd240 100644 --- a/tests/Spout/Reader/XLSX/Manager/RowManagerTest.php +++ b/tests/Spout/Reader/XLSX/Manager/RowManagerTest.php @@ -9,7 +9,7 @@ use Box\Spout\Reader\XLSX\Creator\InternalEntityFactory; use Box\Spout\Reader\XLSX\Creator\ManagerFactory; /** - * Class SharedStringsManagerTest + * Class RowManagerTest */ class RowManagerTest extends \PHPUnit_Framework_TestCase {