Skip to content
This repository was archived by the owner on May 26, 2022. It is now read-only.

Commit 2093724

Browse files
committed
Merge pull request #167 from box/fix_int_float_value_formatters
Fix CellValueFormatter for numeric values
2 parents c48c07d + 4a5da2a commit 2093724

File tree

3 files changed

+67
-20
lines changed

3 files changed

+67
-20
lines changed

src/Spout/Reader/ODS/Helper/CellValueFormatter.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ public function __construct()
4747

4848
/**
4949
* Returns the (unescaped) correctly marshalled, cell value associated to the given XML node.
50-
* @TODO Add other types !!
5150
* @see http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os-part1.html#refTable13
5251
*
5352
* @param \DOMNode $node
@@ -119,7 +118,8 @@ protected function formatStringCellValue($node)
119118
protected function formatFloatCellValue($node)
120119
{
121120
$nodeValue = $node->getAttribute(self::XML_ATTRIBUTE_VALUE);
122-
$cellValue = is_int($nodeValue) ? intval($nodeValue) : floatval($nodeValue);
121+
$nodeIntValue = intval($nodeValue);
122+
$cellValue = ($nodeIntValue == $nodeValue) ? $nodeIntValue : floatval($nodeValue);
123123
return $cellValue;
124124
}
125125

src/Spout/Reader/XLSX/Helper/CellValueFormatter.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ protected function formatNumericCellValue($nodeValue, $cellStyleId)
169169
if ($shouldFormatAsDate) {
170170
return $this->formatExcelTimestampValue(floatval($nodeValue));
171171
} else {
172-
return is_int($nodeValue) ? intval($nodeValue) : floatval($nodeValue);
172+
$nodeIntValue = intval($nodeValue);
173+
return ($nodeIntValue == $nodeValue) ? $nodeIntValue : floatval($nodeValue);
173174
}
174175
}
175176

tests/Spout/Reader/XLSX/Helper/CellValueFormatterTest.php

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,26 @@ class CellValueFormatterTest extends \PHPUnit_Framework_TestCase
1212
/**
1313
* @return array
1414
*/
15-
public function dataProviderForExcelDateTest()
15+
public function dataProviderForTestExcelDate()
1616
{
1717
return [
18-
[ CellValueFormatter::CELL_TYPE_NUMERIC, 42429, '2016-02-29 00:00:00' ],
19-
[ CellValueFormatter::CELL_TYPE_NUMERIC, '146098', '2299-12-31 00:00:00' ],
20-
[ CellValueFormatter::CELL_TYPE_NUMERIC, -700, null ],
21-
[ CellValueFormatter::CELL_TYPE_NUMERIC, 0, null ],
22-
[ CellValueFormatter::CELL_TYPE_NUMERIC, 0.5, null ],
23-
[ CellValueFormatter::CELL_TYPE_NUMERIC, 1, '1900-01-01 00:00:00' ],
24-
[ CellValueFormatter::CELL_TYPE_NUMERIC, 59.999988425926, '1900-02-28 23:59:59' ],
25-
[ CellValueFormatter::CELL_TYPE_NUMERIC, 60.458333333333, '1900-02-28 11:00:00' ],
18+
[CellValueFormatter::CELL_TYPE_NUMERIC, 42429, '2016-02-29 00:00:00'],
19+
[CellValueFormatter::CELL_TYPE_NUMERIC, '146098', '2299-12-31 00:00:00'],
20+
[CellValueFormatter::CELL_TYPE_NUMERIC, -700, null],
21+
[CellValueFormatter::CELL_TYPE_NUMERIC, 0, null],
22+
[CellValueFormatter::CELL_TYPE_NUMERIC, 0.5, null],
23+
[CellValueFormatter::CELL_TYPE_NUMERIC, 1, '1900-01-01 00:00:00'],
24+
[CellValueFormatter::CELL_TYPE_NUMERIC, 59.999988425926, '1900-02-28 23:59:59'],
25+
[CellValueFormatter::CELL_TYPE_NUMERIC, 60.458333333333, '1900-02-28 11:00:00'],
2626
];
2727
}
2828

2929
/**
30-
* @dataProvider dataProviderForExcelDateTest
30+
* @dataProvider dataProviderForTestExcelDate
3131
*
32+
* @param string $cellType
33+
* @param int|float|string $nodeValue
34+
* @param string|null $expectedDateAsString
3235
* @return void
3336
*/
3437
public function testExcelDate($cellType, $nodeValue, $expectedDateAsString)
@@ -39,16 +42,16 @@ public function testExcelDate($cellType, $nodeValue, $expectedDateAsString)
3942
->expects($this->atLeastOnce())
4043
->method('item')
4144
->with(0)
42-
->will($this->returnValue((object)[ 'nodeValue' => $nodeValue ]));
45+
->will($this->returnValue((object)['nodeValue' => $nodeValue]));
4346

4447
$nodeMock = $this->getMockBuilder('DOMElement')->disableOriginalConstructor()->getMock();
4548

4649
$nodeMock
4750
->expects($this->atLeastOnce())
4851
->method('getAttribute')
4952
->will($this->returnValueMap([
50-
[ CellValueFormatter::XML_ATTRIBUTE_TYPE, $cellType ],
51-
[ CellValueFormatter::XML_ATTRIBUTE_STYLE_ID, 123 ],
53+
[CellValueFormatter::XML_ATTRIBUTE_TYPE, $cellType],
54+
[CellValueFormatter::XML_ATTRIBUTE_STYLE_ID, 123],
5255
]));
5356

5457
$nodeMock
@@ -57,17 +60,16 @@ public function testExcelDate($cellType, $nodeValue, $expectedDateAsString)
5760
->with(CellValueFormatter::XML_NODE_VALUE)
5861
->will($this->returnValue($nodeListMock));
5962

60-
$styleHelperMock = $this->getMockBuilder(__NAMESPACE__ . '\StyleHelper')->disableOriginalConstructor()->getMock();
63+
$styleHelperMock = $this->getMockBuilder('Box\Spout\Reader\XLSX\Helper\StyleHelper')->disableOriginalConstructor()->getMock();
6164

6265
$styleHelperMock
6366
->expects($this->once())
6467
->method('shouldFormatNumericValueAsDate')
6568
->with(123)
6669
->will($this->returnValue(true));
6770

68-
$instance = new CellValueFormatter(null, $styleHelperMock);
69-
70-
$result = $instance->extractAndFormatNodeValue($nodeMock);
71+
$formatter = new CellValueFormatter(null, $styleHelperMock);
72+
$result = $formatter->extractAndFormatNodeValue($nodeMock);
7173

7274
if ($expectedDateAsString === null) {
7375
$this->assertNull($result);
@@ -77,4 +79,48 @@ public function testExcelDate($cellType, $nodeValue, $expectedDateAsString)
7779
}
7880
}
7981

82+
/**
83+
* @return array
84+
*/
85+
public function dataProviderForTestFormatNumericCellValueWithNumbers()
86+
{
87+
return [
88+
[42, 42, 'integer'],
89+
[42.5, 42.5, 'double'],
90+
[-42, -42, 'integer'],
91+
[-42.5, -42.5, 'double'],
92+
['42', 42, 'integer'],
93+
['42.5', 42.5, 'double'],
94+
[865640023012945, 865640023012945, 'integer'],
95+
['865640023012945', 865640023012945, 'integer'],
96+
[865640023012945.5, 865640023012945.5, 'double'],
97+
['865640023012945.5', 865640023012945.5, 'double'],
98+
[PHP_INT_MAX, PHP_INT_MAX, 'integer'],
99+
[~PHP_INT_MAX + 1, ~PHP_INT_MAX + 1, 'integer'], // ~PHP_INT_MAX === PHP_INT_MIN, PHP_INT_MIN being PHP7+
100+
[PHP_INT_MAX + 1, PHP_INT_MAX + 1, 'double'],
101+
];
102+
}
103+
104+
/**
105+
* @dataProvider dataProviderForTestFormatNumericCellValueWithNumbers
106+
*
107+
* @param int|float|string $value
108+
* @param int|float $expectedFormattedValue
109+
* @param string $expectedType
110+
* @return void
111+
*/
112+
public function testFormatNumericCellValueWithNumbers($value, $expectedFormattedValue, $expectedType)
113+
{
114+
$styleHelperMock = $this->getMockBuilder('Box\Spout\Reader\XLSX\Helper\StyleHelper')->disableOriginalConstructor()->getMock();
115+
$styleHelperMock
116+
->expects($this->once())
117+
->method('shouldFormatNumericValueAsDate')
118+
->will($this->returnValue(false));
119+
120+
$formatter = new CellValueFormatter(null, $styleHelperMock);
121+
$formattedValue = \ReflectionHelper::callMethodOnObject($formatter, 'formatNumericCellValue', $value, 0);
122+
123+
$this->assertEquals($expectedFormattedValue, $formattedValue);
124+
$this->assertEquals($expectedType, gettype($formattedValue));
125+
}
80126
}

0 commit comments

Comments
 (0)