Improve Coverage for ODS Reader (#1545)
* Improve Coverage for ODS Reader Reader/ODS/Properties is now 100% covered. Reader/ODS is covered except for 1 statement. As the original author put it, "table-header-rows TODO: figure this out ... I'm not sure that PhpExcel has an API for this". I'm still thinking about it, but, so far, I agree with the author. There are minimal code changes. - Several places test !zip->open() to see whether the test failed. However, zip->open() returns true or a string, so the test never detects failure. Change to zip->open() !== true. No previous tests. - Suppress warning messages from simplexml_load_string (there had been no tests for invalid xml). - One document property was misnamed, and one non-existent property was tested for. I added a number of tests, creating an ODS directory, and moving OdsTest to that directory. * Scrutinizer Recommendation Unused variable in one test. * Update CHANGELOG Co-authored-by: Adrien Crivelli <adrien.crivelli@gmail.com>
This commit is contained in:
parent
763b208a68
commit
735103c120
|
@ -14,7 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Nothing.
|
- Improve Coverage for ODS Reader [#1545](https://github.com/phpoffice/phpspreadsheet/pull/1544)
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ use DOMNode;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||||
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
|
||||||
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException;
|
||||||
use PhpOffice\PhpSpreadsheet\Reader\Ods\PageSettings;
|
use PhpOffice\PhpSpreadsheet\Reader\Ods\PageSettings;
|
||||||
use PhpOffice\PhpSpreadsheet\Reader\Ods\Properties as DocumentProperties;
|
use PhpOffice\PhpSpreadsheet\Reader\Ods\Properties as DocumentProperties;
|
||||||
use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner;
|
use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner;
|
||||||
|
@ -76,11 +77,9 @@ class Ods extends BaseReader
|
||||||
}
|
}
|
||||||
|
|
||||||
$zip->close();
|
$zip->close();
|
||||||
|
|
||||||
return $mimeType === 'application/vnd.oasis.opendocument.spreadsheet';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return $mimeType === 'application/vnd.oasis.opendocument.spreadsheet';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,8 +94,8 @@ class Ods extends BaseReader
|
||||||
File::assertFile($pFilename);
|
File::assertFile($pFilename);
|
||||||
|
|
||||||
$zip = new ZipArchive();
|
$zip = new ZipArchive();
|
||||||
if (!$zip->open($pFilename)) {
|
if ($zip->open($pFilename) !== true) {
|
||||||
throw new Exception('Could not open ' . $pFilename . ' for reading! Error opening file.');
|
throw new ReaderException('Could not open ' . $pFilename . ' for reading! Error opening file.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$worksheetNames = [];
|
$worksheetNames = [];
|
||||||
|
@ -149,8 +148,8 @@ class Ods extends BaseReader
|
||||||
$worksheetInfo = [];
|
$worksheetInfo = [];
|
||||||
|
|
||||||
$zip = new ZipArchive();
|
$zip = new ZipArchive();
|
||||||
if (!$zip->open($pFilename)) {
|
if ($zip->open($pFilename) !== true) {
|
||||||
throw new Exception('Could not open ' . $pFilename . ' for reading! Error opening file.');
|
throw new ReaderException('Could not open ' . $pFilename . ' for reading! Error opening file.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$xml = new XMLReader();
|
$xml = new XMLReader();
|
||||||
|
@ -198,18 +197,18 @@ class Ods extends BaseReader
|
||||||
// Step into the row
|
// Step into the row
|
||||||
$xml->read();
|
$xml->read();
|
||||||
do {
|
do {
|
||||||
|
$doread = true;
|
||||||
if ($xml->name == 'table:table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
|
if ($xml->name == 'table:table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||||
if (!$xml->isEmptyElement) {
|
if (!$xml->isEmptyElement) {
|
||||||
++$currCells;
|
++$currCells;
|
||||||
$xml->next();
|
$xml->next();
|
||||||
} else {
|
$doread = false;
|
||||||
$xml->read();
|
|
||||||
}
|
}
|
||||||
} elseif ($xml->name == 'table:covered-table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
|
} elseif ($xml->name == 'table:covered-table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||||
$mergeSize = $xml->getAttribute('table:number-columns-repeated');
|
$mergeSize = $xml->getAttribute('table:number-columns-repeated');
|
||||||
$currCells += (int) $mergeSize;
|
$currCells += (int) $mergeSize;
|
||||||
$xml->read();
|
}
|
||||||
} else {
|
if ($doread) {
|
||||||
$xml->read();
|
$xml->read();
|
||||||
}
|
}
|
||||||
} while ($xml->name != 'table:table-row');
|
} while ($xml->name != 'table:table-row');
|
||||||
|
@ -258,13 +257,13 @@ class Ods extends BaseReader
|
||||||
$GMT = new DateTimeZone('UTC');
|
$GMT = new DateTimeZone('UTC');
|
||||||
|
|
||||||
$zip = new ZipArchive();
|
$zip = new ZipArchive();
|
||||||
if (!$zip->open($pFilename)) {
|
if ($zip->open($pFilename) !== true) {
|
||||||
throw new Exception("Could not open {$pFilename} for reading! Error opening file.");
|
throw new Exception("Could not open {$pFilename} for reading! Error opening file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Meta
|
// Meta
|
||||||
|
|
||||||
$xml = simplexml_load_string(
|
$xml = @simplexml_load_string(
|
||||||
$this->securityScanner->scan($zip->getFromName('meta.xml')),
|
$this->securityScanner->scan($zip->getFromName('meta.xml')),
|
||||||
'SimpleXMLElement',
|
'SimpleXMLElement',
|
||||||
Settings::getLibXmlLoaderOptions()
|
Settings::getLibXmlLoaderOptions()
|
||||||
|
@ -465,9 +464,10 @@ class Ods extends BaseReader
|
||||||
$type = DataType::TYPE_NUMERIC;
|
$type = DataType::TYPE_NUMERIC;
|
||||||
$dataValue = (float) $cellData->getAttributeNS($officeNs, 'value');
|
$dataValue = (float) $cellData->getAttributeNS($officeNs, 'value');
|
||||||
|
|
||||||
if (floor($dataValue) == $dataValue) {
|
// percentage should always be float
|
||||||
$dataValue = (int) $dataValue;
|
//if (floor($dataValue) == $dataValue) {
|
||||||
}
|
// $dataValue = (int) $dataValue;
|
||||||
|
//}
|
||||||
$formatting = NumberFormat::FORMAT_PERCENTAGE_00;
|
$formatting = NumberFormat::FORMAT_PERCENTAGE_00;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -488,8 +488,6 @@ class Ods extends BaseReader
|
||||||
if (floor($dataValue) == $dataValue) {
|
if (floor($dataValue) == $dataValue) {
|
||||||
if ($dataValue == (int) $dataValue) {
|
if ($dataValue == (int) $dataValue) {
|
||||||
$dataValue = (int) $dataValue;
|
$dataValue = (int) $dataValue;
|
||||||
} else {
|
|
||||||
$dataValue = (float) $dataValue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,15 +54,11 @@ class Properties
|
||||||
$docProps->setLastModifiedBy($propertyValue);
|
$docProps->setLastModifiedBy($propertyValue);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'creation-date':
|
case 'date':
|
||||||
$creationDate = strtotime($propertyValue);
|
$creationDate = strtotime($propertyValue);
|
||||||
$docProps->setCreated($creationDate);
|
$docProps->setCreated($creationDate);
|
||||||
$docProps->setModified($creationDate);
|
$docProps->setModified($creationDate);
|
||||||
|
|
||||||
break;
|
|
||||||
case 'keyword':
|
|
||||||
$docProps->setKeywords($propertyValue);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'description':
|
case 'description':
|
||||||
$docProps->setDescription($propertyValue);
|
$docProps->setDescription($propertyValue);
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Reader\Ods;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Reader\Ods;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @TODO The class doesn't read the bold/italic/underline properties (rich text)
|
||||||
|
*/
|
||||||
|
class OdsInfoTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testReadFileProperties(): void
|
||||||
|
{
|
||||||
|
$filename = 'tests/data/Reader/Ods/data.ods';
|
||||||
|
|
||||||
|
// Load into this instance
|
||||||
|
$reader = new Ods();
|
||||||
|
|
||||||
|
// Test "listWorksheetNames" method
|
||||||
|
|
||||||
|
self::assertEquals([
|
||||||
|
'Sheet1',
|
||||||
|
'Second Sheet',
|
||||||
|
], $reader->listWorksheetNames($filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNoMimeType(): void
|
||||||
|
{
|
||||||
|
$filename = 'tests/data/Reader/Ods/nomimetype.ods';
|
||||||
|
|
||||||
|
// Load into this instance
|
||||||
|
$reader = new Ods();
|
||||||
|
|
||||||
|
self::assertTrue($reader->canRead($filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReadBadFileProperties(): void
|
||||||
|
{
|
||||||
|
$this->expectException(ReaderException::class);
|
||||||
|
|
||||||
|
// Load into this instance
|
||||||
|
$reader = new Ods();
|
||||||
|
|
||||||
|
// Test "listWorksheetNames" method
|
||||||
|
|
||||||
|
self::assertEquals([
|
||||||
|
'Sheet1',
|
||||||
|
'Second Sheet',
|
||||||
|
], $reader->listWorksheetNames(__FILE__));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReadFileInfo(): void
|
||||||
|
{
|
||||||
|
$filename = 'tests/data/Reader/Ods/data.ods';
|
||||||
|
|
||||||
|
// Load into this instance
|
||||||
|
$reader = new Ods();
|
||||||
|
|
||||||
|
// Test "listWorksheetNames" method
|
||||||
|
|
||||||
|
$wsinfo = $reader->listWorkSheetInfo($filename);
|
||||||
|
self::assertEquals([
|
||||||
|
[
|
||||||
|
'worksheetName' => 'Sheet1',
|
||||||
|
'lastColumnLetter' => 'C',
|
||||||
|
'lastColumnIndex' => 2,
|
||||||
|
'totalRows' => 12,
|
||||||
|
'totalColumns' => 3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'worksheetName' => 'Second Sheet',
|
||||||
|
'lastColumnLetter' => 'A',
|
||||||
|
'lastColumnIndex' => 0,
|
||||||
|
'totalRows' => 2,
|
||||||
|
'totalColumns' => 1,
|
||||||
|
],
|
||||||
|
], $wsinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReadBadFileInfo(): void
|
||||||
|
{
|
||||||
|
$this->expectException(ReaderException::class);
|
||||||
|
$filename = __FILE__;
|
||||||
|
|
||||||
|
// Load into this instance
|
||||||
|
$reader = new Ods();
|
||||||
|
|
||||||
|
// Test "listWorksheetNames" method
|
||||||
|
|
||||||
|
$wsinfo = $reader->listWorkSheetInfo($filename);
|
||||||
|
self::assertEquals([
|
||||||
|
[
|
||||||
|
'worksheetName' => 'Sheet1',
|
||||||
|
'lastColumnLetter' => 'C',
|
||||||
|
'lastColumnIndex' => 2,
|
||||||
|
'totalRows' => 11,
|
||||||
|
'totalColumns' => 3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'worksheetName' => 'Second Sheet',
|
||||||
|
'lastColumnLetter' => 'A',
|
||||||
|
'lastColumnIndex' => 0,
|
||||||
|
'totalRows' => 2,
|
||||||
|
'totalColumns' => 1,
|
||||||
|
],
|
||||||
|
], $wsinfo);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheetTests\Reader;
|
namespace PhpOffice\PhpSpreadsheetTests\Reader\Ods;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||||||
use PhpOffice\PhpSpreadsheet\Document\Properties;
|
use PhpOffice\PhpSpreadsheet\Document\Properties;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException;
|
||||||
use PhpOffice\PhpSpreadsheet\Reader\Ods;
|
use PhpOffice\PhpSpreadsheet\Reader\Ods;
|
||||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||||
use PhpOffice\PhpSpreadsheet\Style\Font;
|
use PhpOffice\PhpSpreadsheet\Style\Font;
|
||||||
|
@ -50,30 +51,66 @@ class OdsTest extends TestCase
|
||||||
|
|
||||||
// Load into this instance
|
// Load into this instance
|
||||||
$reader = new Ods();
|
$reader = new Ods();
|
||||||
$this->spreadsheetData = $reader->loadIntoExisting($filename, new Spreadsheet());
|
$this->spreadsheetData = $reader->load($filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->spreadsheetData;
|
return $this->spreadsheetData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testReadFileProperties(): void
|
public function testLoadWorksheets(): void
|
||||||
|
{
|
||||||
|
$spreadsheet = $this->loadDataFile();
|
||||||
|
|
||||||
|
self::assertInstanceOf('PhpOffice\PhpSpreadsheet\Spreadsheet', $spreadsheet);
|
||||||
|
|
||||||
|
self::assertEquals(2, $spreadsheet->getSheetCount());
|
||||||
|
|
||||||
|
$firstSheet = $spreadsheet->getSheet(0);
|
||||||
|
self::assertInstanceOf('PhpOffice\PhpSpreadsheet\Worksheet\Worksheet', $firstSheet);
|
||||||
|
|
||||||
|
$secondSheet = $spreadsheet->getSheet(1);
|
||||||
|
self::assertInstanceOf('PhpOffice\PhpSpreadsheet\Worksheet\Worksheet', $secondSheet);
|
||||||
|
self::assertEquals('Sheet1', $spreadsheet->getSheet(0)->getTitle());
|
||||||
|
self::assertEquals('Second Sheet', $spreadsheet->getSheet(1)->getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLoadOneWorksheet(): void
|
||||||
{
|
{
|
||||||
$filename = 'tests/data/Reader/Ods/data.ods';
|
$filename = 'tests/data/Reader/Ods/data.ods';
|
||||||
|
|
||||||
// Load into this instance
|
// Load into this instance
|
||||||
$reader = new Ods();
|
$reader = new Ods();
|
||||||
|
$reader->setLoadSheetsOnly(['Sheet1']);
|
||||||
|
$spreadsheet = $reader->load($filename);
|
||||||
|
|
||||||
// Test "listWorksheetNames" method
|
self::assertEquals(1, $spreadsheet->getSheetCount());
|
||||||
|
|
||||||
self::assertEquals([
|
self::assertEquals('Sheet1', $spreadsheet->getSheet(0)->getTitle());
|
||||||
'Sheet1',
|
|
||||||
'Second Sheet',
|
|
||||||
], $reader->listWorksheetNames($filename));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadWorksheets(): void
|
public function testLoadBadFile(): void
|
||||||
{
|
{
|
||||||
$spreadsheet = $this->loadDataFile();
|
$this->expectException(ReaderException::class);
|
||||||
|
$reader = new Ods();
|
||||||
|
$spreadsheet = $reader->load(__FILE__);
|
||||||
|
|
||||||
|
self::assertInstanceOf('PhpOffice\PhpSpreadsheet\Spreadsheet', $spreadsheet);
|
||||||
|
|
||||||
|
self::assertEquals(2, $spreadsheet->getSheetCount());
|
||||||
|
|
||||||
|
$firstSheet = $spreadsheet->getSheet(0);
|
||||||
|
self::assertInstanceOf('PhpOffice\PhpSpreadsheet\Worksheet\Worksheet', $firstSheet);
|
||||||
|
|
||||||
|
$secondSheet = $spreadsheet->getSheet(1);
|
||||||
|
self::assertInstanceOf('PhpOffice\PhpSpreadsheet\Worksheet\Worksheet', $secondSheet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLoadCorruptFile(): void
|
||||||
|
{
|
||||||
|
$this->expectException(ReaderException::class);
|
||||||
|
$filename = 'tests/data/Reader/Ods/corruptMeta.ods';
|
||||||
|
$reader = new Ods();
|
||||||
|
$spreadsheet = $reader->load($filename);
|
||||||
|
|
||||||
self::assertInstanceOf('PhpOffice\PhpSpreadsheet\Spreadsheet', $spreadsheet);
|
self::assertInstanceOf('PhpOffice\PhpSpreadsheet\Spreadsheet', $spreadsheet);
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue