PhpSpreadsheet/tests/PhpSpreadsheetTests/Calculation/Engine/RangeTest.php

177 lines
7.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Engine;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\NamedRange;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class RangeTest extends TestCase
{
/** @var string */
private $incompleteMessage = 'Must be revisited';
/**
* @var Spreadsheet
*/
private $spreadSheet;
protected function setUp(): void
{
$this->spreadSheet = new Spreadsheet();
$this->spreadSheet->getActiveSheet()
->fromArray(array_chunk(range(1, 240), 6), null, 'A1', true);
}
/**
* @dataProvider providerRangeEvaluation
*
* @param mixed $expectedResult
*/
public function testRangeEvaluation(string $formula, $expectedResult): void
{
$workSheet = $this->spreadSheet->getActiveSheet();
$workSheet->setCellValue('H1', $formula);
$actualRresult = $workSheet->getCell('H1')->getCalculatedValue();
self::assertSame($expectedResult, $actualRresult);
}
public function providerRangeEvaluation(): array
{
return[
'Sum with Simple Range' => ['=SUM(A1:C3)', 72],
'Count with Simple Range' => ['=COUNT(A1:C3)', 9],
'Sum with UNION #1' => ['=SUM(A1:B3,A1:C2)', 75],
'Count with UNION #1' => ['=COUNT(A1:B3,A1:C2)', 12],
'Sum with INTERSECTION #1' => ['=SUM(A1:B3 A1:C2)', 18],
'Count with INTERSECTION #1' => ['=COUNT(A1:B3 A1:C2)', 4],
'Sum with UNION #2' => ['=SUM(A1:A3,C1:C3)', 48],
'Count with UNION #2' => ['=COUNT(A1:A3,C1:C3)', 6],
'Sum with INTERSECTION #2 - No Intersect' => ['=SUM(A1:A3 C1:C3)', Functions::null()],
'Count with INTERSECTION #2 - No Intersect' => ['=COUNT(A1:A3 C1:C3)', 0],
'Sum with UNION #3' => ['=SUM(A1:B2,B2:C3)', 64],
'Count with UNION #3' => ['=COUNT(A1:B2,B2:C3)', 8],
'Sum with INTERSECTION #3 - Single Cell' => ['=SUM(A1:B2 B2:C3)', 8],
'Count with INTERSECTION #3 - Single Cell' => ['=COUNT(A1:B2 B2:C3)', 1],
'Sum with Triple UNION' => ['=SUM(A1:C1,A3:C3,B1:C3)', 99],
'Count with Triple UNION' => ['=COUNT(A1:C1,A3:C3,B1:C3)', 12],
'Sum with UNION and INTERSECTION' => ['=SUM(A1:C1,A3:C3 B1:C3)', 35],
'Count with UNION and INTERSECTION' => ['=COUNT(A1:C1,A3:C3 B1:C3)', 5],
'Sum with UNION with Worksheet Reference' => ['=SUM(Worksheet!A1:B3,Worksheet!A1:C2)', 75],
'Sum with UNION with full Worksheet Reference' => ['=SUM(Worksheet!A1:Worksheet!B3,Worksheet!A1:Worksheet!C2)', 75],
'Sum with Chained UNION #1' => ['=SUM(A3:B1:C2)', 72],
'Count with Chained UNION #1' => ['=COUNT(A3:B1:C2)', 9],
'Sum with Chained UNION #2' => ['=SUM(A5:C10:C20:F1)', 7260],
'Count with Chained UNION#2' => ['=COUNT(A5:C10:C20:F1)', 120],
];
}
public function test3dRangeEvaluation(): void
{
$workSheet = $this->spreadSheet->getActiveSheet();
$workSheet->setCellValue('E1', '=SUM(Worksheet!A1:Worksheet2!B3)');
$this->expectExceptionMessage('3D Range references are not yet supported');
$workSheet->getCell('E1')->getCalculatedValue();
}
/**
* @dataProvider providerNamedRangeEvaluation
*/
public function testNamedRangeEvaluation(string $group1, string $group2, string $formula, int $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);
$sumRresult = $workSheet->getCell('E1')->getCalculatedValue();
self::assertSame($expectedResult, $sumRresult);
}
public function providerNamedRangeEvaluation(): array
{
return[
['$A$1:$B$3', '$A$1:$C$2', '=SUM(GROUP1,GROUP2)', 75],
['$A$1:$B$3', '$A$1:$C$2', '=COUNT(GROUP1,GROUP2)', 12],
['$A$1:$B$3', '$A$1:$C$2', '=SUM(GROUP1 GROUP2)', 18],
['$A$1:$B$3', '$A$1:$C$2', '=COUNT(GROUP1 GROUP2)', 4],
['$A$1:$B$2', '$B$2:$C$3', '=SUM(GROUP1,GROUP2)', 64],
['$A$1:$B$2', '$B$2:$C$3', '=COUNT(GROUP1,GROUP2)', 8],
['$A$1:$B$2', '$B$2:$C$3', '=SUM(GROUP1 GROUP2)', 8],
['$A$1:$B$2', '$B$2:$C$3', '=COUNT(GROUP1 GROUP2)', 1],
['Worksheet!$A$1:$B$2', 'Worksheet!$B$2:$C$3', '=SUM(GROUP1,GROUP2)', 64],
['Worksheet!$A$1:Worksheet!$B$2', 'Worksheet!$B$2:Worksheet!$C$3', '=SUM(GROUP1,GROUP2)', 64],
];
}
/**
* @dataProvider providerUTF8NamedRangeEvaluation
*
* @param string[] $names
* @param string[] $ranges
*/
public function testUTF8NamedRangeEvaluation(array $names, array $ranges, string $formula, int $expectedResult): void
{
$workSheet = $this->spreadSheet->getActiveSheet();
foreach ($names as $index => $name) {
$range = $ranges[$index];
$this->spreadSheet->addNamedRange(new NamedRange($name, $workSheet, $range));
}
$workSheet->setCellValue('E1', $formula);
$sumRresult = $workSheet->getCell('E1')->getCalculatedValue();
self::assertSame($expectedResult, $sumRresult);
}
public function providerUTF8NamedRangeEvaluation(): array
{
return[
[['Γειά', 'σου', 'Κόσμε'], ['$A$1', '$B$1:$B$2', '$C$1:$C$3'], '=SUM(Γειά,σου,Κόσμε)', 38],
[['Γειά', 'σου', 'Κόσμε'], ['$A$1', '$B$1:$B$2', '$C$1:$C$3'], '=COUNT(Γειά,σου,Κόσμε)', 6],
[['Здравствуй', 'мир'], ['$A$1:$A$3', '$C$1:$C$3'], '=SUM(Здравствуй,мир)', 48],
];
}
/**
* @dataProvider providerCompositeNamedRangeEvaluation
*/
public function testCompositeNamedRangeEvaluation(string $composite, int $expectedSum, int $expectedCount): void
{
if ($this->incompleteMessage !== '') {
self::markTestIncomplete($this->incompleteMessage);
}
$workSheet = $this->spreadSheet->getActiveSheet();
$this->spreadSheet->addNamedRange(new NamedRange('COMPOSITE', $workSheet, $composite));
$workSheet->setCellValue('E1', '=SUM(COMPOSITE)');
$workSheet->setCellValue('E2', '=COUNT(COMPOSITE)');
$actualSum = $workSheet->getCell('E1')->getCalculatedValue();
self::assertSame($expectedSum, $actualSum);
$actualCount = $workSheet->getCell('E2')->getCalculatedValue();
self::assertSame($expectedCount, $actualCount);
}
public function providerCompositeNamedRangeEvaluation(): array
{
return[
// Calculation engine doesn't yet handle union ranges with overlap
'Union with overlap' => [
'A1:C1,A3:C3,B1:C3',
63,
12,
],
'Union and Intersection' => [
'A1:C1,A3:C3 B1:C3',
23,
5,
],
];
}
}