Skip to content

Commit eb76c3c

Browse files
authored
Code Coverage >90% (#2973)
No source code changes, just additional tests. FormulaParser appears unused, replaced by newer code in Calculation. However, it's a public interface, so probably shouldn't be deleted without first deprecating it. I have no strong feelings about whether that should happen. However, as long as it's part of the package, we may as well have some formal unit tests for it.
1 parent b661d31 commit eb76c3c

File tree

3 files changed

+152
-6
lines changed

3 files changed

+152
-6
lines changed

phpstan-baseline.neon

-5
Original file line numberDiff line numberDiff line change
@@ -515,11 +515,6 @@ parameters:
515515
count: 1
516516
path: src/PhpSpreadsheet/Calculation/FormulaParser.php
517517

518-
-
519-
message: "#^Strict comparison using \\=\\=\\= between string and null will always evaluate to false\\.$#"
520-
count: 1
521-
path: src/PhpSpreadsheet/Calculation/FormulaParser.php
522-
523518
-
524519
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Functions\\:\\:ifCondition\\(\\) has no return type specified\\.$#"
525520
count: 1

src/PhpSpreadsheet/Calculation/FormulaParser.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class FormulaParser
6161
/**
6262
* Create a new FormulaParser.
6363
*
64-
* @param string $formula Formula to parse
64+
* @param ?string $formula Formula to parse
6565
*/
6666
public function __construct($formula = '')
6767
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
<?php
2+
3+
namespace PhpOffice\PhpSpreadsheetTests\Calculation;
4+
5+
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcException;
6+
use PhpOffice\PhpSpreadsheet\Calculation\FormulaParser;
7+
use PHPUnit\Framework\TestCase;
8+
9+
class FormulaParserTest extends TestCase
10+
{
11+
public function testNullFormula(): void
12+
{
13+
$this->expectException(CalcException::class);
14+
$this->expectExceptionMessage('Invalid parameter passed: formula');
15+
$result = new FormulaParser(null);
16+
}
17+
18+
public function testInvalidTokenId(): void
19+
{
20+
$this->expectException(CalcException::class);
21+
$this->expectExceptionMessage('Token with id 1 does not exist.');
22+
$result = new FormulaParser('=2');
23+
$result->getToken(1);
24+
}
25+
26+
public function testNoFormula(): void
27+
{
28+
$result = new FormulaParser('');
29+
self::assertSame(0, $result->getTokenCount());
30+
}
31+
32+
/**
33+
* @dataProvider providerFormulaParser
34+
*/
35+
public function testFormulaParser(string $formula, array $expectedResult): void
36+
{
37+
$formula = "=$formula";
38+
$result = new FormulaParser($formula);
39+
self::assertSame($formula, $result->getFormula());
40+
self::assertSame(count($expectedResult), $result->getTokenCount());
41+
$tokens = $result->getTokens();
42+
$token0 = $result->getToken(0);
43+
self::assertSame($tokens[0], $token0);
44+
$idx = -1;
45+
foreach ($expectedResult as $resultArray) {
46+
++$idx;
47+
self::assertSame($resultArray[0], $tokens[$idx]->getValue());
48+
self::assertSame($resultArray[1], $tokens[$idx]->getTokenType());
49+
self::assertSame($resultArray[2], $tokens[$idx]->getTokenSubType());
50+
}
51+
}
52+
53+
public function providerFormulaParser(): array
54+
{
55+
return [
56+
['5%*(2+(-3))+A3',
57+
[
58+
['5', 'Operand', 'Number'],
59+
['%', 'OperatorPostfix', 'Nothing'],
60+
['*', 'OperatorInfix', 'Math'],
61+
['', 'Subexpression', 'Start'],
62+
['2', 'Operand', 'Number'],
63+
['+', 'OperatorInfix', 'Math'],
64+
['', 'Subexpression', 'Start'],
65+
['-', 'OperatorPrefix', 'Nothing'],
66+
['3', 'Operand', 'Number'],
67+
['', 'Subexpression', 'Stop'],
68+
['', 'Subexpression', 'Stop'],
69+
['+', 'OperatorInfix', 'Math'],
70+
['A3', 'Operand', 'Range'],
71+
],
72+
],
73+
['"hello" & "goodbye"',
74+
[
75+
['hello', 'Operand', 'Text'],
76+
['&', 'OperatorInfix', 'Concatenation'],
77+
['goodbye', 'Operand', 'Text'],
78+
],
79+
],
80+
['+1.23E5',
81+
[
82+
['1.23E5', 'Operand', 'Number'],
83+
],
84+
],
85+
['#DIV/0!',
86+
[
87+
['#DIV/0!', 'Operand', 'Error'],
88+
],
89+
],
90+
['"HE""LLO"',
91+
[
92+
['HE"LLO', 'Operand', 'Text'],
93+
],
94+
],
95+
['MINVERSE({3,1;4,2})',
96+
[
97+
['MINVERSE', 'Function', 'Start'],
98+
['ARRAY', 'Function', 'Start'],
99+
['ARRAYROW', 'Function', 'Start'],
100+
['3', 'Operand', 'Number'],
101+
[',', 'OperatorInfix', 'Union'],
102+
['1', 'Operand', 'Number'],
103+
['', 'Function', 'Stop'],
104+
[',', 'Argument', 'Nothing'],
105+
['ARRAYROW', 'Function', 'Start'],
106+
['4', 'Operand', 'Number'],
107+
[',', 'OperatorInfix', 'Union'],
108+
['2', 'Operand', 'Number'],
109+
['', 'Function', 'Stop'],
110+
['', 'Function', 'Stop'],
111+
['', 'Function', 'Stop'],
112+
],
113+
],
114+
['[1,1]*5',
115+
[
116+
['[1,1]', 'Operand', 'Range'],
117+
['*', 'OperatorInfix', 'Math'],
118+
['5', 'Operand', 'Number'],
119+
],
120+
],
121+
['IF(A1>=0,2,3)',
122+
[
123+
['IF', 'Function', 'Start'],
124+
['A1', 'Operand', 'Range'],
125+
['>=', 'OperatorInfix', 'Logical'],
126+
['0', 'Operand', 'Number'],
127+
[',', 'OperatorInfix', 'Union'],
128+
['2', 'Operand', 'Number'],
129+
[',', 'OperatorInfix', 'Union'],
130+
['3', 'Operand', 'Number'],
131+
['', 'Function', 'Stop'],
132+
],
133+
],
134+
["'Worksheet'!A1:A3",
135+
[
136+
['Worksheet!A1:A3', 'Operand', 'Range'],
137+
],
138+
],
139+
["'Worksh''eet'!A1:A3",
140+
[
141+
['Worksh\'eet!A1:A3', 'Operand', 'Range'],
142+
],
143+
],
144+
['true',
145+
[
146+
['true', 'Operand', 'Logical'],
147+
],
148+
],
149+
];
150+
}
151+
}

0 commit comments

Comments
 (0)