FormulaParserTest.php 5.1 KB

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