| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- <?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(array $ranges, string $formula, int $expectedResult): void
- {
- $workSheet = $this->spreadSheet->getActiveSheet();
- foreach ($ranges as $id => $range) {
- $this->spreadSheet->addNamedRange(new NamedRange('GROUP' . ++$id, $workSheet, $range));
- }
- $workSheet->setCellValue('H1', $formula);
- $sumRresult = $workSheet->getCell('H1')->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],
- [['$A$5', '$C$10:$C$20', '$F$1'], '=SUM(GROUP1:GROUP2:GROUP3)', 7260],
- [['$A$5:$A$7', '$C$20', '$F$1'], '=SUM(GROUP1:GROUP2:GROUP3)', 7260],
- [['$A$5:$A$7', '$C$10:$C$20', '$F$1'], '=SUM(GROUP1:GROUP2:GROUP3)', 7260],
- [['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,
- ],
- ];
- }
- }
|