This commit introduces Row and Cell entities, that will replace the arrays passed in previously. It also adds support for Cell styling (instead of Row styling only).
201 lines
7.2 KiB
PHP
201 lines
7.2 KiB
PHP
<?php
|
|
|
|
namespace Box\Spout\Reader\XLSX\Helper;
|
|
|
|
use Box\Spout\Common\Helper\Escaper;
|
|
use Box\Spout\Reader\XLSX\Manager\StyleManager;
|
|
|
|
/**
|
|
* Class CellValueFormatterTest
|
|
*/
|
|
class CellValueFormatterTest extends \PHPUnit_Framework_TestCase
|
|
{
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function dataProviderForTestExcelDate()
|
|
{
|
|
return [
|
|
// use 1904 dates, node value, expected date as string
|
|
|
|
// 1900 calendar
|
|
[false, 3687.4207639, '1910-02-03 10:05:54'],
|
|
[false, 2.5000000, '1900-01-01 12:00:00'],
|
|
[false, 2958465.9999884, '9999-12-31 23:59:59'],
|
|
[false, 2958465.9999885, null],
|
|
[false, -2337.999989, '1893-08-05 00:00:01'],
|
|
[false, -693593, '0001-01-01 00:00:00'],
|
|
[false, -693593.0000001, null],
|
|
[false, 0, '1899-12-30 00:00:00'],
|
|
[false, 0.25, '1899-12-30 06:00:00'],
|
|
[false, 0.5, '1899-12-30 12:00:00'],
|
|
[false, 0.75, '1899-12-30 18:00:00'],
|
|
[false, 0.99999, '1899-12-30 23:59:59'],
|
|
[false, 1, '1899-12-31 00:00:00'],
|
|
[false, '3687.4207639', '1910-02-03 10:05:54'],
|
|
|
|
// 1904 calendar
|
|
[true, 2225.4207639, '1910-02-03 10:05:54'],
|
|
[true, 2.5000000, '1904-01-03 12:00:00'],
|
|
[true, 2957003.9999884, '9999-12-31 23:59:59'],
|
|
[true, 2957003.9999885, null],
|
|
[true, -3799.999989, '1893-08-05 00:00:01'],
|
|
[true, -695055, '0001-01-01 00:00:00'],
|
|
[true, -695055.0000001, null],
|
|
[true, 0, '1904-01-01 00:00:00'],
|
|
[true, 0.25, '1904-01-01 06:00:00'],
|
|
[true, 0.5, '1904-01-01 12:00:00'],
|
|
[true, 0.75, '1904-01-01 18:00:00'],
|
|
[true, 0.99999, '1904-01-01 23:59:59'],
|
|
[true, 1, '1904-01-02 00:00:00'],
|
|
[true, '2225.4207639', '1910-02-03 10:05:54'],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider dataProviderForTestExcelDate
|
|
*
|
|
* @param bool $shouldUse1904Dates
|
|
* @param int|float|string $nodeValue
|
|
* @param string|null $expectedDateAsString
|
|
* @return void
|
|
*/
|
|
public function testExcelDate($shouldUse1904Dates, $nodeValue, $expectedDateAsString)
|
|
{
|
|
$nodeListMock = $this->createMock(\DOMNodeList::class);
|
|
|
|
$nodeListMock
|
|
->expects($this->atLeastOnce())
|
|
->method('item')
|
|
->with(0)
|
|
->will($this->returnValue((object) ['nodeValue' => $nodeValue]));
|
|
|
|
$nodeMock = $this->createMock(\DOMElement::class);
|
|
|
|
$nodeMock
|
|
->expects($this->atLeastOnce())
|
|
->method('getAttribute')
|
|
->will($this->returnValueMap([
|
|
[CellValueFormatter::XML_ATTRIBUTE_TYPE, CellValueFormatter::CELL_TYPE_NUMERIC],
|
|
[CellValueFormatter::XML_ATTRIBUTE_STYLE_ID, 123],
|
|
]));
|
|
|
|
$nodeMock
|
|
->expects($this->atLeastOnce())
|
|
->method('getElementsByTagName')
|
|
->with(CellValueFormatter::XML_NODE_VALUE)
|
|
->will($this->returnValue($nodeListMock));
|
|
|
|
/** @var StyleManager|\PHPUnit_Framework_MockObject_MockObject $styleManagerMock */
|
|
$styleManagerMock = $this->createMock(StyleManager::class);
|
|
|
|
$styleManagerMock
|
|
->expects($this->once())
|
|
->method('shouldFormatNumericValueAsDate')
|
|
->with(123)
|
|
->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'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function dataProviderForTestFormatNumericCellValueWithNumbers()
|
|
{
|
|
// Some test values exceed PHP_INT_MAX on 32-bit PHP. They are
|
|
// therefore converted to as doubles automatically by PHP.
|
|
$expectedBigNumberType = (PHP_INT_SIZE < 8 ? 'double' : 'integer');
|
|
|
|
return [
|
|
[42, 42, 'integer'],
|
|
[42.5, 42.5, 'double'],
|
|
[-42, -42, 'integer'],
|
|
[-42.5, -42.5, 'double'],
|
|
['42', 42, 'integer'],
|
|
['42.5', 42.5, 'double'],
|
|
[865640023012945, 865640023012945, $expectedBigNumberType],
|
|
['865640023012945', 865640023012945, $expectedBigNumberType],
|
|
[865640023012945.5, 865640023012945.5, 'double'],
|
|
['865640023012945.5', 865640023012945.5, 'double'],
|
|
[PHP_INT_MAX, PHP_INT_MAX, 'integer'],
|
|
[~PHP_INT_MAX + 1, ~PHP_INT_MAX + 1, 'integer'], // ~PHP_INT_MAX === PHP_INT_MIN, PHP_INT_MIN being PHP7+
|
|
[PHP_INT_MAX + 1, PHP_INT_MAX + 1, 'double'],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider dataProviderForTestFormatNumericCellValueWithNumbers
|
|
*
|
|
* @param int|float|string $value
|
|
* @param int|float $expectedFormattedValue
|
|
* @param string $expectedType
|
|
* @return void
|
|
*/
|
|
public function testFormatNumericCellValueWithNumbers($value, $expectedFormattedValue, $expectedType)
|
|
{
|
|
/** @var StyleManager|\PHPUnit_Framework_MockObject_MockObject $styleManagerMock */
|
|
$styleManagerMock = $this->createMock(StyleManager::class);
|
|
$styleManagerMock
|
|
->expects($this->once())
|
|
->method('shouldFormatNumericValueAsDate')
|
|
->will($this->returnValue(false));
|
|
|
|
$formatter = new CellValueFormatter(null, $styleManagerMock, false, false, new Escaper\XLSX());
|
|
$formattedValue = \ReflectionHelper::callMethodOnObject($formatter, 'formatNumericCellValue', $value, 0);
|
|
|
|
$this->assertEquals($expectedFormattedValue, $formattedValue);
|
|
$this->assertEquals($expectedType, gettype($formattedValue));
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function dataProviderForTestFormatStringCellValue()
|
|
{
|
|
return [
|
|
['A', 'A'],
|
|
[' A ', ' A '],
|
|
["\n\tA\n\t", "\n\tA\n\t"],
|
|
[' ', ' '],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider dataProviderForTestFormatStringCellValue
|
|
*
|
|
* @param string $value
|
|
* @param string $expectedFormattedValue
|
|
* @return void
|
|
*/
|
|
public function testFormatInlineStringCellValue($value, $expectedFormattedValue)
|
|
{
|
|
$nodeListMock = $this->createMock(\DOMNodeList::class);
|
|
$nodeListMock
|
|
->expects($this->atLeastOnce())
|
|
->method('item')
|
|
->with(0)
|
|
->will($this->returnValue((object) ['nodeValue' => $value]));
|
|
|
|
$nodeMock = $this->createMock(\DOMElement::class);
|
|
$nodeMock
|
|
->expects($this->atLeastOnce())
|
|
->method('getElementsByTagName')
|
|
->with(CellValueFormatter::XML_NODE_INLINE_STRING_VALUE)
|
|
->will($this->returnValue($nodeListMock));
|
|
|
|
$formatter = new CellValueFormatter(null, null, false, false, new Escaper\XLSX());
|
|
$formattedValue = \ReflectionHelper::callMethodOnObject($formatter, 'formatInlineStringCellValue', $nodeMock);
|
|
|
|
$this->assertEquals($expectedFormattedValue, $formattedValue);
|
|
}
|
|
}
|