Range operator tests (#1498)

* Fix intersection operator when working with named ranges
This commit is contained in:
Mark Baker 2020-05-29 21:53:28 +02:00 committed by GitHub
parent b3b0b49b7c
commit 8b2bba9bdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 5 deletions

View File

@ -3456,10 +3456,8 @@ class Calculation
if ((isset(self::$comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$comparisonOperators[$formula[$index + 1]]))) {
$opCharacter .= $formula[++$index];
}
// Find out if we're currently at the beginning of a number, variable, cell reference, function, parenthesis or operand
$isOperandOrFunction = preg_match($regexpMatchString, substr($formula, $index), $match);
if ($opCharacter == '-' && !$expectingOperator) { // Is it a negation instead of a minus?
// Put a negation on the stack
$stack->push('Unary Operator', '~', null, $currentCondition, $currentOnlyIf, $currentOnlyIfNot);
@ -3776,8 +3774,12 @@ class Calculation
}
// If we're expecting an operator, but only have a space between the previous and next operands (and both are
// Cell References) then we have an INTERSECTION operator
if (($expectingOperator) && (preg_match('/^' . self::CALCULATION_REGEXP_CELLREF . '.*/Ui', substr($formula, $index), $match)) &&
($output[count($output) - 1]['type'] == 'Cell Reference')) {
if (($expectingOperator) &&
((preg_match('/^' . self::CALCULATION_REGEXP_CELLREF . '.*/Ui', substr($formula, $index), $match)) &&
($output[count($output) - 1]['type'] == 'Cell Reference') ||
(preg_match('/^' . self::CALCULATION_REGEXP_NAMEDRANGE . '.*/Ui', substr($formula, $index), $match)) &&
($output[count($output) - 1]['type'] == 'Named Range' || $output[count($output) - 1]['type'] == 'Value')
)) {
while ($stack->count() > 0 &&
($o2 = $stack->last()) &&
isset(self::$operators[$o2['value']]) &&

View File

@ -3,6 +3,7 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Engine;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\NamedRange;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
@ -28,7 +29,7 @@ class RangeTest extends TestCase
/**
* @dataProvider providerRangeEvaluation
*
* @param mixed $formula
* @param string $formula
* @param int $expectedResult
*/
public function testRangeEvaluation($formula, $expectedResult): void
@ -51,4 +52,54 @@ class RangeTest extends TestCase
['=SUM(A1:B2 B2:C3)', 5],
];
}
/**
* @dataProvider providerNamedRangeEvaluation
*
* @param string $group1
* @param string $group2
* @param string $formula
* @param int $expectedResult
*/
public function testNamedRangeEvaluation($group1, $group2, $formula, $expectedResult): void
{
$workSheet = $this->spreadSheet->getActiveSheet();
$this->spreadSheet->addNamedRange(new NamedRange('GROUP1', $workSheet, $group1));
$this->spreadSheet->addNamedRange(new NamedRange('GROUP2', $workSheet, $group2));
$workSheet->setCellValue('E1', $formula);
$actualRresult = $workSheet->getCell('E1')->getCalculatedValue();
self::assertSame($expectedResult, $actualRresult);
}
public function providerNamedRangeEvaluation()
{
return[
[
'A1:B3',
'A1:C2',
'=SUM(GROUP1,GROUP2)',
48,
],
[
'A1:B3',
'A1:C2',
'=SUM(GROUP1 GROUP2)',
12,
],
[
'A1:B2',
'B2:C3',
'=SUM(GROUP1,GROUP2)',
40,
],
[
'A1:B2',
'B2:C3',
'=SUM(GROUP1 GROUP2)',
5,
],
];
}
}