diff --git a/CHANGELOG.md b/CHANGELOG.md index b993bc3540..ab7eff4146 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org). ### Fixed - Xls Writer Parser Mishandling True/False Argument. [Issue #4331](https://github.com/PHPOffice/PhpSpreadsheet/issues/4331) [PR #4333](https://github.com/PHPOffice/PhpSpreadsheet/pull/4333) +- Minor changes to dynamic array calculations exposed by using explicit array return types in some tests. [PR #4328](https://github.com/PHPOffice/PhpSpreadsheet/pull/4328) ## 2025-01-26 - 3.9.0 diff --git a/samples/LookupRef/COLUMN.php b/samples/LookupRef/COLUMN.php index 5b257d606c..c9ccf6971f 100644 --- a/samples/LookupRef/COLUMN.php +++ b/samples/LookupRef/COLUMN.php @@ -1,5 +1,6 @@ setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_VALUE +); $worksheet = $spreadsheet->getActiveSheet(); $worksheet->getCell('A1')->setValue('=COLUMN(C13)'); diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index b256aad3b3..484386a2c7 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -4887,17 +4887,18 @@ private function processTokenStack(mixed $tokens, ?string $cellID = null, ?Cell } $result = $operand1; } else { - // In theory, we should truncate here. - // But I can't figure out a formula - // using the concatenation operator - // with literals that fits in 32K, - // so I don't think we can overflow here. if (Information\ErrorValue::isError($operand1)) { $result = $operand1; } elseif (Information\ErrorValue::isError($operand2)) { $result = $operand2; } else { - $result = self::FORMULA_STRING_QUOTE . str_replace('""', self::FORMULA_STRING_QUOTE, self::unwrapResult($operand1) . self::unwrapResult($operand2)) . self::FORMULA_STRING_QUOTE; + $result = str_replace('""', self::FORMULA_STRING_QUOTE, self::unwrapResult($operand1) . self::unwrapResult($operand2)); + $result = Shared\StringHelper::substring( + $result, + 0, + DataType::MAX_STRING_LENGTH + ); + $result = self::FORMULA_STRING_QUOTE . $result . self::FORMULA_STRING_QUOTE; } } $this->debugLog->writeDebugLog('Evaluation Result is %s', $this->showTypeDetails($result)); @@ -5046,6 +5047,9 @@ private function processTokenStack(mixed $tokens, ?string $cellID = null, ?Cell while (is_array($cellValue)) { $cellValue = array_shift($cellValue); } + if (is_string($cellValue)) { + $cellValue = preg_replace('/"/', '""', $cellValue); + } $this->debugLog->writeDebugLog('Scalar Result for cell %s is %s', $cellRef, $this->showTypeDetails($cellValue)); } $this->processingAnchorArray = false; diff --git a/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Single.php b/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Single.php index 6f60a2af18..ba3da6bb88 100644 --- a/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Single.php +++ b/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Single.php @@ -77,13 +77,13 @@ public static function periods(mixed $rate, mixed $presentValue, mixed $futureVa * * Calculates the interest rate required for an investment to grow to a specified future value . * - * @param array|float $periods The number of periods over which the investment is made - * @param array|float $presentValue Present Value - * @param array|float $futureValue Future Value + * @param mixed $periods The number of periods over which the investment is made, expect array|float + * @param mixed $presentValue Present Value, expect array|float + * @param mixed $futureValue Future Value, expect array|float * * @return float|string Result, or a string containing an error */ - public static function interestRate(array|float $periods = 0.0, array|float $presentValue = 0.0, array|float $futureValue = 0.0): string|float + public static function interestRate(mixed $periods = 0.0, mixed $presentValue = 0.0, mixed $futureValue = 0.0): string|float { $periods = Functions::flattenSingleValue($periods); $presentValue = Functions::flattenSingleValue($presentValue); diff --git a/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php b/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php index 15f9e8957b..94bfcef0e6 100644 --- a/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php +++ b/src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php @@ -23,14 +23,14 @@ class NonPeriodic * Excel Function: * =XIRR(values,dates,guess) * - * @param float[] $values A series of cash flow payments + * @param mixed $values A series of cash flow payments, expecting float[] * The series of values must contain at least one positive value & one negative value * @param mixed[] $dates A series of payment dates * The first payment date indicates the beginning of the schedule of payments * All other dates must be later than this date, but they may occur in any order * @param mixed $guess An optional guess at the expected answer */ - public static function rate(array $values, array $dates, mixed $guess = self::DEFAULT_GUESS): float|string + public static function rate(mixed $values, mixed $dates, mixed $guess = self::DEFAULT_GUESS): float|string { $rslt = self::xirrPart1($values, $dates); if ($rslt !== '') { @@ -106,18 +106,18 @@ public static function rate(array $values, array $dates, mixed $guess = self::DE * Excel Function: * =XNPV(rate,values,dates) * - * @param array|float $rate the discount rate to apply to the cash flows - * @param float[] $values A series of cash flows that corresponds to a schedule of payments in dates. + * @param mixed $rate the discount rate to apply to the cash flows, expect array|float + * @param mixed $values A series of cash flows that corresponds to a schedule of payments in dates, expecting floag[]. * The first payment is optional and corresponds to a cost or payment that occurs * at the beginning of the investment. * If the first value is a cost or payment, it must be a negative value. * All succeeding payments are discounted based on a 365-day year. * The series of values must contain at least one positive value and one negative value. - * @param mixed[] $dates A schedule of payment dates that corresponds to the cash flow payments. + * @param mixed $dates A schedule of payment dates that corresponds to the cash flow payments, expecting mixed[]. * The first payment date indicates the beginning of the schedule of payments. * All other dates must be later than this date, but they may occur in any order. */ - public static function presentValue(array|float $rate, array $values, array $dates): float|string + public static function presentValue(mixed $rate, mixed $values, mixed $dates): float|string { return self::xnpvOrdered($rate, $values, $dates, true); } diff --git a/src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php b/src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php index 228b464485..b8e84a669e 100644 --- a/src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php +++ b/src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php @@ -82,6 +82,15 @@ public static function index(mixed $matrix, mixed $rowNum = 0, mixed $columnNum $rowNum = $rowNum ?? 0; $columnNum = $columnNum ?? 0; + if (is_scalar($matrix)) { + if ($rowNum === 0 || $rowNum === 1) { + if ($columnNum === 0 || $columnNum === 1) { + if ($columnNum === 1 || $rowNum === 1) { + return $matrix; + } + } + } + } try { $rowNum = LookupRefValidations::validatePositiveInt($rowNum); diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index 89321abeda..ef1d442899 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -408,9 +408,6 @@ public function getCalculatedValue(bool $resetLog = true): mixed $oldAttributesT = $oldAttributes['t'] ?? ''; $coordinate = $this->getCoordinate(); $oldAttributesRef = $oldAttributes['ref'] ?? $coordinate; - if (!str_contains($oldAttributesRef, ':')) { - $oldAttributesRef .= ":$oldAttributesRef"; - } $originalValue = $this->value; $originalDataType = $this->dataType; $this->formulaAttributes = []; @@ -434,6 +431,14 @@ public function getCalculatedValue(bool $resetLog = true): mixed $result = array_shift($result); } } + if ( + !is_array($result) + && $calculation->getInstanceArrayReturnType() === Calculation::RETURN_ARRAY_AS_ARRAY + && $oldAttributesT === 'array' + && ($oldAttributesRef === $coordinate || $oldAttributesRef === "$coordinate:$coordinate") + ) { + $result = [$result]; + } // if return_as_array for formula like '=sheet!cell' if (is_array($result) && count($result) === 1) { $resultKey = array_keys($result)[0]; @@ -560,6 +565,8 @@ public function getCalculatedValue(bool $resetLog = true): mixed SharedDate::setExcelCalendar($currentCalendar); if ($result === Functions::NOT_YET_IMPLEMENTED) { + $this->formulaAttributes = $oldAttributes; + return $this->calculatedValue; // Fallback if calculation engine does not support the formula. } diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index 504bd38fb7..c97a2db277 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -1513,6 +1513,9 @@ private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell if (isset($attributes['ref'])) { $ref = $this->parseRef($coordinate, $attributes['ref']); + if ($ref === "$coordinate:$coordinate") { + $ref = $coordinate; + } } else { $ref = $coordinate; } diff --git a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php index 976e8d54bc..27b72dc8d1 100644 --- a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php @@ -62,6 +62,10 @@ public static function providerArrayFormulae(): array public function testArrayFormulaUsingCells(): void { $spreadsheet = new Spreadsheet(); + $calculation = Calculation::getInstance($spreadsheet); + $calculation->setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_VALUE + ); $sheet = $spreadsheet->getActiveSheet(); $sheet->getCell('A4')->setValue(-3); $sheet->getCell('B4')->setValue(4); diff --git a/tests/PhpSpreadsheetTests/Calculation/CalculationLoggingTest.php b/tests/PhpSpreadsheetTests/Calculation/CalculationLoggingTest.php index 5d7a076919..8e90644c7b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/CalculationLoggingTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/CalculationLoggingTest.php @@ -42,6 +42,10 @@ public function testFormulaWithLogging(): void public function testFormulaWithMultipleCellLogging(): void { $spreadsheet = new Spreadsheet(); + $calculation = Calculation::getInstance($spreadsheet); + $calculation->setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_VALUE + ); $sheet = $spreadsheet->getActiveSheet(); $sheet->fromArray( diff --git a/tests/PhpSpreadsheetTests/Calculation/FormulaAsStringTest.php b/tests/PhpSpreadsheetTests/Calculation/FormulaAsStringTest.php index ab6c40e67b..d81f093421 100644 --- a/tests/PhpSpreadsheetTests/Calculation/FormulaAsStringTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/FormulaAsStringTest.php @@ -4,15 +4,21 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Spreadsheet; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; class FormulaAsStringTest extends TestCase { - #[\PHPUnit\Framework\Attributes\DataProvider('providerFunctionsAsString')] + #[DataProvider('providerFunctionsAsString')] public function testFunctionsAsString(mixed $expectedResult, string $formula): void { $spreadsheet = new Spreadsheet(); + $calculation = Calculation::getInstance($spreadsheet); + $calculation->setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_VALUE + ); $workSheet = $spreadsheet->getActiveSheet(); $workSheet->setCellValue('A1', 10); $workSheet->setCellValue('A2', 20); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsFormulaTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsFormulaTest.php index 9f691d1562..8fc08c7988 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsFormulaTest.php @@ -15,6 +15,10 @@ class IsFormulaTest extends TestCase public function testIsFormula(): void { $spreadsheet = new Spreadsheet(); + $calculation = Calculation::getInstance($spreadsheet); + $calculation->setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_VALUE + ); $sheet1 = $spreadsheet->getActiveSheet(); $sheet1->setTitle('SheetOne'); // no space in sheet title $sheet2 = $spreadsheet->createSheet(); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/AllSetupTeardown.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/AllSetupTeardown.php index 5db3c9b918..fc8dcad3a6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/AllSetupTeardown.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/AllSetupTeardown.php @@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Logical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcException; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Cell\DataType; @@ -100,4 +101,13 @@ protected function runTestCase(string $functionName, mixed $expectedResult, mixe $this->setCell('B1', $formula); self::assertSame($expectedResult, $sheet->getCell('B1')->getCalculatedValue()); } + + protected function setArrayAsValue(): void + { + $spreadsheet = $this->getSpreadsheet(); + $calculation = Calculation::getInstance($spreadsheet); + $calculation->setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_VALUE + ); + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/AndTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/AndTest.php index e1eb46aa14..c41a527897 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/AndTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/AndTest.php @@ -4,11 +4,14 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Logical; +use PHPUnit\Framework\Attributes\DataProvider; + class AndTest extends AllSetupTeardown { - #[\PHPUnit\Framework\Attributes\DataProvider('providerAND')] + #[DataProvider('providerAND')] public function testAND(mixed $expectedResult, mixed ...$args): void { + $this->setArrayAsValue(); $this->runTestCase('AND', $expectedResult, ...$args); } @@ -17,7 +20,7 @@ public static function providerAND(): array return require 'tests/data/Calculation/Logical/AND.php'; } - #[\PHPUnit\Framework\Attributes\DataProvider('providerANDLiteral')] + #[DataProvider('providerANDLiteral')] public function testANDLiteral(bool|string $expectedResult, float|int|string $formula): void { $sheet = $this->getSheet(); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/XorTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/XorTest.php index 990068dde1..cc09074c2e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/XorTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/XorTest.php @@ -9,6 +9,7 @@ class XorTest extends AllSetupTeardown #[\PHPUnit\Framework\Attributes\DataProvider('providerXOR')] public function testXOR(mixed $expectedResult, mixed ...$args): void { + $this->setArrayAsValue(); $this->runTestCase('XOR', $expectedResult, ...$args); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/AllSetupTeardown.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/AllSetupTeardown.php index 0f177c81f4..882ee67337 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/AllSetupTeardown.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/AllSetupTeardown.php @@ -18,7 +18,7 @@ class AllSetupTeardown extends TestCase protected string $arrayReturnType; - private ?Spreadsheet $spreadsheet = null; + protected ?Spreadsheet $spreadsheet = null; private ?Worksheet $sheet = null; @@ -86,4 +86,13 @@ protected function getSheet(): Worksheet return $this->sheet; } + + protected function setArrayAsValue(): void + { + $spreadsheet = $this->getSpreadsheet(); + $calculation = Calculation::getInstance($spreadsheet); + $calculation->setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_VALUE + ); + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnOnSpreadsheetTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnOnSpreadsheetTest.php index 3382a1e38d..a57b91eb3f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnOnSpreadsheetTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnOnSpreadsheetTest.php @@ -5,13 +5,15 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef; use PhpOffice\PhpSpreadsheet\NamedRange; +use PHPUnit\Framework\Attributes\DataProvider; class ColumnOnSpreadsheetTest extends AllSetupTeardown { - #[\PHPUnit\Framework\Attributes\DataProvider('providerCOLUMNonSpreadsheet')] + #[DataProvider('providerCOLUMNonSpreadsheet')] public function testColumnOnSpreadsheet(mixed $expectedResult, string $cellReference = 'omitted'): void { $this->mightHaveException($expectedResult); + $this->setArrayAsValue(); $sheet = $this->getSheet(); $this->getSpreadsheet()->addNamedRange(new NamedRange('namedrangex', $sheet, '$E$2:$E$6')); $this->getSpreadsheet()->addNamedRange(new NamedRange('namedrangey', $sheet, '$F$2:$H$2')); @@ -37,6 +39,7 @@ public static function providerCOLUMNonSpreadsheet(): array public function testCOLUMNLocalDefinedName(): void { + $this->setArrayAsValue(); $sheet = $this->getSheet(); $sheet1 = $this->getSpreadsheet()->createSheet(); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/HLookupTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/HLookupTest.php index 679cbe28b1..a8f1c2acdb 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/HLookupTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/HLookupTest.php @@ -7,16 +7,15 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\NamedRange; -use PhpOffice\PhpSpreadsheet\Spreadsheet; -use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\DataProvider; -class HLookupTest extends TestCase +class HLookupTest extends AllSetupTeardown { - #[\PHPUnit\Framework\Attributes\DataProvider('providerHLOOKUP')] + #[DataProvider('providerHLOOKUP')] public function testHLOOKUP(mixed $expectedResult, mixed $lookup, array $values, mixed $rowIndex, ?bool $rangeLookup = null): void { - $spreadsheet = new Spreadsheet(); - $sheet = $spreadsheet->getActiveSheet(); + $this->setArrayAsValue(); + $sheet = $this->getSheet(); $maxRow = 0; $maxCol = 0; $maxColLetter = 'A'; @@ -52,8 +51,6 @@ public function testHLOOKUP(mixed $expectedResult, mixed $lookup, array $values, } $sheet->getCell('ZZ1')->setValue("=HLOOKUP(ZZ8, A1:$maxColLetter$maxRow, $indexarg$boolArg)"); self::assertEquals($expectedResult, $sheet->getCell('ZZ1')->getCalculatedValue()); - - $spreadsheet->disconnectWorksheets(); } private static function parseRangeLookup(?bool $rangeLookup): string @@ -70,7 +67,7 @@ public static function providerHLOOKUP(): array return require 'tests/data/Calculation/LookupRef/HLOOKUP.php'; } - #[\PHPUnit\Framework\Attributes\DataProvider('providerHLookupNamedRange')] + #[DataProvider('providerHLookupNamedRange')] public function testHLookupNamedRange(string $expectedResult, string $cellAddress): void { $lookupData = [ @@ -85,12 +82,11 @@ public function testHLookupNamedRange(string $expectedResult, string $cellAddres ['Cleanliness', 3, '=HLOOKUP(C8,Lookup_Table,2,FALSE)'], ]; - $spreadsheet = new Spreadsheet(); - $worksheet = $spreadsheet->getActiveSheet(); + $worksheet = $this->getSheet(); $worksheet->fromArray($lookupData, null, 'F4'); $worksheet->fromArray($formData, null, 'B4'); - $spreadsheet->addNamedRange(new NamedRange('Lookup_Table', $worksheet, '=$G$4:$J$5')); + $this->getSpreadsheet()->addNamedRange(new NamedRange('Lookup_Table', $worksheet, '=$G$4:$J$5')); $result = $worksheet->getCell($cellAddress)->getCalculatedValue(); self::assertEquals($expectedResult, $result); @@ -106,7 +102,7 @@ public static function providerHLookupNamedRange(): array ]; } - #[\PHPUnit\Framework\Attributes\DataProvider('providerHLookupArray')] + #[DataProvider('providerHLookupArray')] public function testHLookupArray(array $expectedResult, string $values, string $database, string $index): void { $calculation = Calculation::getInstance(); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndexOnSpreadsheetTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndexOnSpreadsheetTest.php index 08cf905c5c..45993d8938 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndexOnSpreadsheetTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndexOnSpreadsheetTest.php @@ -4,12 +4,15 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef; +use PHPUnit\Framework\Attributes\DataProvider; + class IndexOnSpreadsheetTest extends AllSetupTeardown { - #[\PHPUnit\Framework\Attributes\DataProvider('providerINDEXonSpreadsheet')] + #[DataProvider('providerINDEXonSpreadsheet')] public function testIndexOnSpreadsheet(mixed $expectedResult, array $matrix, null|int|string $rowNum = null, null|int|string $colNum = null): void { $this->mightHaveException($expectedResult); + $this->setArrayAsValue(); $sheet = $this->getSheet(); $sheet->fromArray($matrix); $maxRow = $sheet->getHighestRow(); @@ -33,9 +36,10 @@ public static function providerINDEXonSpreadsheet(): array return require 'tests/data/Calculation/LookupRef/INDEXonSpreadsheet.php'; } - #[\PHPUnit\Framework\Attributes\DataProvider('providerIndexLiteralArrays')] + #[DataProvider('providerIndexLiteralArrays')] public function testLiteralArrays(mixed $expectedResult, string $indexArgs): void { + $this->setArrayAsValue(); $sheet = $this->getSheet(); $sheet->getCell('A10')->setValue(10); $sheet->getCell('B10')->setValue(11); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndirectTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndirectTest.php index 2ffa013818..176d96a50d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndirectTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndirectTest.php @@ -7,10 +7,11 @@ use PhpOffice\PhpSpreadsheet\NamedFormula; use PhpOffice\PhpSpreadsheet\NamedRange; use PhpOffice\PhpSpreadsheet\Reader\Xlsx as ReaderXlsx; +use PHPUnit\Framework\Attributes\DataProvider; class IndirectTest extends AllSetupTeardown { - #[\PHPUnit\Framework\Attributes\DataProvider('providerINDIRECT')] + #[DataProvider('providerINDIRECT')] public function testINDIRECT(mixed $expectedResult, mixed $cellReference = 'omitted', mixed $a1 = 'omitted'): void { $this->mightHaveException($expectedResult); @@ -106,13 +107,13 @@ public function testIndirectFile2(): void { $reader = new ReaderXlsx(); $file = 'tests/data/Calculation/LookupRef/IndirectFormulaSelection.xlsx'; - $spreadsheet = $reader->load($file); - $sheet = $spreadsheet->getActiveSheet(); + $this->spreadsheet = $reader->load($file); + $sheet = $this->spreadsheet->getActiveSheet(); $result = $sheet->getCell('A5')->getCalculatedValue(); self::assertSame(100, $result); $value = $sheet->getCell('A5')->getValue(); self::assertSame('=CURRENCY_SELECTOR', $value); - $formula = $spreadsheet->getNamedFormula('CURRENCY_SELECTOR'); + $formula = $this->spreadsheet->getNamedFormula('CURRENCY_SELECTOR'); if ($formula === null) { self::fail('Expected named formula was not defined'); } else { @@ -130,9 +131,10 @@ public function testDeprecatedCall(): void self::assertSame('This is it', $result); } - #[\PHPUnit\Framework\Attributes\DataProvider('providerRelative')] + #[DataProvider('providerRelative')] public function testR1C1Relative(string|int|null $expectedResult, string $address): void { + $this->setArrayAsValue(); $sheet = $this->getSheet(); $sheet->fromArray([ ['a1', 'b1', 'c1'], diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowOnSpreadsheetTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowOnSpreadsheetTest.php index ca22fdcc86..28edd256b3 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowOnSpreadsheetTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowOnSpreadsheetTest.php @@ -5,13 +5,15 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef; use PhpOffice\PhpSpreadsheet\NamedRange; +use PHPUnit\Framework\Attributes\DataProvider; class RowOnSpreadsheetTest extends AllSetupTeardown { - #[\PHPUnit\Framework\Attributes\DataProvider('providerROWonSpreadsheet')] + #[DataProvider('providerROWonSpreadsheet')] public function testRowOnSpreadsheet(mixed $expectedResult, string $cellReference = 'omitted'): void { $this->mightHaveException($expectedResult); + $this->setArrayAsValue(); $sheet = $this->getSheet(); $sheet->setTitle('ThisSheet'); $this->getSpreadsheet()->addNamedRange(new NamedRange('namedrangex', $sheet, '$E$2:$E$6')); @@ -41,6 +43,7 @@ public static function providerROWOnSpreadsheet(): array public function testINDIRECTLocalDefinedName(): void { $sheet = $this->getSheet(); + $this->setArrayAsValue(); $sheet1 = $this->getSpreadsheet()->createSheet(); $sheet1->setTitle('OtherSheet'); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/VLookupTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/VLookupTest.php index 169f203a0c..612bdb3d1d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/VLookupTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/VLookupTest.php @@ -6,16 +6,15 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Cell\DataType; -use PhpOffice\PhpSpreadsheet\Spreadsheet; -use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Attributes\DataProvider; -class VLookupTest extends TestCase +class VLookupTest extends AllSetupTeardown { - #[\PHPUnit\Framework\Attributes\DataProvider('providerVLOOKUP')] + #[DataProvider('providerVLOOKUP')] public function testVLOOKUP(mixed $expectedResult, mixed $value, mixed $table, mixed $index, ?bool $lookup = null): void { - $spreadsheet = new Spreadsheet(); - $sheet = $spreadsheet->getActiveSheet(); + $this->setArrayAsValue(); + $sheet = $this->getSheet(); if (is_array($table)) { $sheet->fromArray($table); $dimension = $sheet->calculateWorksheetDimension(); @@ -40,7 +39,6 @@ public function testVLOOKUP(mixed $expectedResult, mixed $value, mixed $table, m $sheet->getCell('Z99')->setValue("=VLOOKUP(Z98,$dimension,$indexarg$lastarg)"); $result = $sheet->getCell('Z99')->getCalculatedValue(); self::assertEquals($expectedResult, $result); - $spreadsheet->disconnectWorksheets(); } public static function providerVLOOKUP(): array @@ -48,7 +46,7 @@ public static function providerVLOOKUP(): array return require 'tests/data/Calculation/LookupRef/VLOOKUP.php'; } - #[\PHPUnit\Framework\Attributes\DataProvider('providerVLookupArray')] + #[DataProvider('providerVLookupArray')] public function testVLookupArray(array $expectedResult, string $values, string $database, string $index): void { $calculation = Calculation::getInstance(); @@ -78,8 +76,7 @@ public static function providerVLookupArray(): array public function testIssue1402(): void { - $spreadsheet = new Spreadsheet(); - $worksheet = $spreadsheet->getActiveSheet(); + $worksheet = $this->getSheet(); $worksheet->setCellValueExplicit('A1', 1, DataType::TYPE_STRING); $worksheet->setCellValue('B1', 'Text Nr 1'); @@ -93,6 +90,5 @@ public function testIssue1402(): void $worksheet->setCellValue('A5', 2); $worksheet->setCellValue('B5', '=VLOOKUP(A5,$A$1:$B$3,2,0)'); self::assertSame('Numeric result', $worksheet->getCell('B5')->getCalculatedValue()); - $spreadsheet->disconnectWorksheets(); } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AllSetupTeardown.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AllSetupTeardown.php index ca55bfa653..7ef732b1c1 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AllSetupTeardown.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AllSetupTeardown.php @@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcException; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Cell\DataType; @@ -15,7 +16,7 @@ class AllSetupTeardown extends TestCase { private string $compatibilityMode; - private ?Spreadsheet $spreadsheet = null; + protected ?Spreadsheet $spreadsheet = null; private ?Worksheet $sheet = null; @@ -81,4 +82,13 @@ protected function getSheet(): Worksheet return $this->sheet; } + + protected function setArrayAsValue(): void + { + $spreadsheet = $this->getSpreadsheet(); + $calculation = Calculation::getInstance($spreadsheet); + $calculation->setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_VALUE + ); + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MMultTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MMultTest.php index 8925151f78..3e2edf3f8a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MMultTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MMultTest.php @@ -5,10 +5,11 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; use PhpOffice\PhpSpreadsheet\Calculation\MathTrig; +use PHPUnit\Framework\Attributes\DataProvider; class MMultTest extends AllSetupTeardown { - #[\PHPUnit\Framework\Attributes\DataProvider('providerMMULT')] + #[DataProvider('providerMMULT')] public function testMMULT(mixed $expectedResult, mixed ...$args): void { $result = MathTrig\MatrixFunctions::multiply(...$args); @@ -23,6 +24,7 @@ public static function providerMMULT(): array public function testOnSpreadsheet(): void { // very limited ability to test this in the absence of dynamic arrays + $this->setArrayAsValue(); $sheet = $this->getSheet(); $sheet->getCell('A1')->setValue('=MMULT({1,2,3}, {1,2,3})'); // incompatible dimensions self::assertSame('#VALUE!', $sheet->getCell('A1')->getCalculatedValue()); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumIfTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumIfTest.php index 9199ada28e..3ee886f708 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumIfTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumIfTest.php @@ -4,15 +4,18 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PHPUnit\Framework\Attributes\DataProvider; + class SumIfTest extends AllSetupTeardown { - #[\PHPUnit\Framework\Attributes\DataProvider('providerSUMIF')] + #[DataProvider('providerSUMIF')] public function testSUMIF2(mixed $expectedResult, array $array1, mixed $condition, ?array $array2 = null): void { $this->mightHaveException($expectedResult); if ($expectedResult === 'incomplete') { self::markTestIncomplete('Raises formula error - researching solution'); } + $this->setArrayAsValue(); $sheet = $this->getSheet(); $sheet->fromArray($array1, null, 'A1', true); $maxARow = count($array1); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumProduct2Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumProduct2Test.php index 0d40b5dd92..3d1c8c252b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumProduct2Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumProduct2Test.php @@ -12,8 +12,9 @@ public function testSUMPRODUCT(): void { $file = 'tests/data/Reader/XLSX/issue.3909b.xlsx'; $reader = new XlsxReader(); - $spreadsheet = $reader->load($file); - $sheet = $spreadsheet->getActiveSheet(); + $this->spreadsheet = $reader->load($file); + $this->setArrayAsValue(); + $sheet = $this->getSheet(); self::assertSame('=SUMPRODUCT(((calNames=I3)*(calTiers=$K$2))*calHours)', $sheet->getCell('K3')->getValue()); self::assertSame(40, $sheet->getCell('K3')->getCalculatedValue()); self::assertSame(4, $sheet->getCell('L3')->getCalculatedValue()); @@ -29,6 +30,5 @@ public function testSUMPRODUCT(): void self::assertSame(0, $sheet->getCell('N5')->getCalculatedValue()); self::assertSame('=SUMPRODUCT(calHours*((calNames=I3)*(calTiers=$K$2)))', $sheet->getCell('I14')->getValue()); self::assertSame(40, $sheet->getCell('I14')->getCalculatedValue()); - $spreadsheet->disconnectWorksheets(); } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumTest.php index dfa27f35fc..69bf7d9ae8 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumTest.php @@ -5,12 +5,14 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; use PhpOffice\PhpSpreadsheet\Spreadsheet; +use PHPUnit\Framework\Attributes\DataProvider; class SumTest extends AllSetupTeardown { - #[\PHPUnit\Framework\Attributes\DataProvider('providerSUM')] + #[DataProvider('providerSUM')] public function testSUM(mixed $expectedResult, mixed ...$args): void { + $this->setArrayAsValue(); $sheet = $this->getSheet(); $row = 0; foreach ($args as $arg) { @@ -27,7 +29,7 @@ public static function providerSUM(): array return require 'tests/data/Calculation/MathTrig/SUM.php'; } - #[\PHPUnit\Framework\Attributes\DataProvider('providerSUMLiterals')] + #[DataProvider('providerSUMLiterals')] public function testSUMLiterals(mixed $expectedResult, string $args): void { $sheet = $this->getSheet(); @@ -41,10 +43,11 @@ public static function providerSUMLiterals(): array return require 'tests/data/Calculation/MathTrig/SUMLITERALS.php'; } - #[\PHPUnit\Framework\Attributes\DataProvider('providerSUMWITHINDEXMATCH')] + #[DataProvider('providerSUMWITHINDEXMATCH')] public function testSumWithIndexMatch(mixed $expectedResult, string $formula): void { - $spreadsheet = new Spreadsheet(); + $spreadsheet = $this->getSpreadsheet(); + $this->setArrayAsValue(); $sheet1 = $spreadsheet->getActiveSheet(); $sheet1->setTitle('Formula'); $sheet1->fromArray( @@ -62,7 +65,6 @@ public function testSumWithIndexMatch(mixed $expectedResult, string $formula): v ] ); self::assertSame($expectedResult, $sheet1->getCell('B2')->getCalculatedValue()); - $spreadsheet->disconnectWorksheets(); } public static function providerSUMWITHINDEXMATCH(): array diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AllSetupTeardown.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AllSetupTeardown.php index 8aaf6e73f6..e8f444a398 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AllSetupTeardown.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AllSetupTeardown.php @@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcException; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Cell\DataType; @@ -20,9 +21,12 @@ class AllSetupTeardown extends TestCase private ?Worksheet $sheet = null; + protected string $returnArrayAs; + protected function setUp(): void { $this->compatibilityMode = Functions::getCompatibilityMode(); + $this->returnArrayAs = ''; } protected function tearDown(): void @@ -108,6 +112,12 @@ protected function runTestCaseReference(string $functionName, mixed $expectedRes { $this->mightHaveException($expectedResult); $sheet = $this->getSheet(); + if ($this->returnArrayAs !== '') { + $calculation = Calculation::getInstance($this->spreadsheet); + $calculation->setInstanceArrayReturnType( + $this->returnArrayAs + ); + } $formula = "=$functionName("; $comma = ''; $row = 0; diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfTest.php index 62db48efa5..c25b636b81 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfTest.php @@ -39,7 +39,7 @@ public function testOutliers(): void } catch (CalcException $e) { self::assertStringContainsString('Must specify range of cells', $e->getMessage()); } - $sheet->getCell('A3')->setValue('=AVERAGEIF(C1,"<32")'); + $sheet->getCell('A3')->setValue('=AVERAGEIF(C1:C1,"<32")'); self::assertSame(5, $sheet->getCell('A3')->getCalculatedValue(), 'first arg is single cell'); } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountBlankTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountBlankTest.php index 4856547617..f112557597 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountBlankTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountBlankTest.php @@ -41,9 +41,9 @@ public function testOutliers(): void } catch (CalcException $e) { self::assertStringContainsString('Must specify range of cells', $e->getMessage()); } - $sheet->getCell('A3')->setValue('=COUNTBLANK(C1)'); + $sheet->getCell('A3')->setValue('=COUNTBLANK(C1:C1)'); self::assertSame(0, $sheet->getCell('A3')->getCalculatedValue(), 'arg is single non-blank cell'); - $sheet->getCell('A4')->setValue('=COUNTBLANK(D2)'); + $sheet->getCell('A4')->setValue('=COUNTBLANK(D2:D2)'); self::assertSame(1, $sheet->getCell('A4')->getCalculatedValue(), 'arg is single null cell'); $sheet->getCell('A5')->setValue('=COUNTBLANK(D3:D4)'); self::assertSame(2, $sheet->getCell('A5')->getCalculatedValue(), 'arg is two cells both null'); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SkewTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SkewTest.php index fad689b61c..7685c0724a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SkewTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SkewTest.php @@ -4,11 +4,15 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; +use PHPUnit\Framework\Attributes\DataProvider; + class SkewTest extends AllSetupTeardown { - #[\PHPUnit\Framework\Attributes\DataProvider('providerSKEW')] + #[DataProvider('providerSKEW')] public function testSKEW(mixed $expectedResult, array $args): void { + $this->returnArrayAs = Calculation::RETURN_ARRAY_AS_VALUE; $this->runTestCaseReference('SKEW', $expectedResult, ...$args); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ConcatenateRangeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ConcatenateRangeTest.php index e90d55922a..f665a15018 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ConcatenateRangeTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ConcatenateRangeTest.php @@ -18,12 +18,19 @@ public function testIssue4061(): void $sheet->getCell('C2')->setValue('2'); $sheet->getCell('C3')->setValue('3'); $sheet->getCell('B1')->setValue('=CONCATENATE(A1:A3, "-", C1:C3)'); + Calculation::getInstance($this->getSpreadsheet()) + ->setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_VALUE + ); self::assertSame('a-1', $sheet->getCell('B1')->getCalculatedValue()); $sheet->getCell('X1')->setValue('=A1:A3&"-"&C1:C3'); self::assertSame('a-1', $sheet->getCell('X1')->getCalculatedValue()); $sheet->getCell('D1')->setValue('=CONCAT(A1:A3, "-", C1:C3)'); self::assertSame('abc-123', $sheet->getCell('D1')->getCalculatedValue()); - Calculation::getInstance($this->getSpreadsheet())->setInstanceArrayReturnType(Calculation::RETURN_ARRAY_AS_ARRAY); + Calculation::getInstance($this->getSpreadsheet()) + ->setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_ARRAY + ); $sheet->getCell('E1')->setValue('=CONCATENATE(A1:A3, "-", C1:C3)'); self::assertSame([['a-1'], ['b-2'], ['c-3']], $sheet->getCell('E1')->getCalculatedValue()); $sheet->getCell('Y1')->setValue('=A1:A3&"-"&C1:C3'); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ConcatenateTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ConcatenateTest.php index 7e2cfb2953..8ace2c0bfd 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ConcatenateTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ConcatenateTest.php @@ -6,10 +6,11 @@ use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\Spreadsheet; +use PHPUnit\Framework\Attributes\DataProvider; class ConcatenateTest extends AllSetupTeardown { - #[\PHPUnit\Framework\Attributes\DataProvider('providerCONCATENATE')] + #[DataProvider('providerCONCATENATE')] public function testCONCATENATE(mixed $expectedResult, mixed ...$args): void { $this->mightHaveException($expectedResult); diff --git a/tests/PhpSpreadsheetTests/Calculation/XlfnFunctionsTest.php b/tests/PhpSpreadsheetTests/Calculation/XlfnFunctionsTest.php index 1579cc0aac..9d634b4afe 100644 --- a/tests/PhpSpreadsheetTests/Calculation/XlfnFunctionsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/XlfnFunctionsTest.php @@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Shared\File; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Style\Color; @@ -34,6 +35,10 @@ public function testXlfn(): void ['365', 'A1', '=SORT({7;1;5})', '=SORT({7;1;5})', 1], ]; $workbook = new Spreadsheet(); + $calculation = Calculation::getInstance($workbook); + $calculation->setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_VALUE + ); $sheet = $workbook->getActiveSheet(); $sheet->setTitle('2010'); $sheet = $workbook->createSheet(); @@ -112,6 +117,10 @@ public function testXlfn(): void $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx'); $rdobj = $reader->load($oufil); unlink($oufil); + $calculation = Calculation::getInstance($rdobj); + $calculation->setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_VALUE + ); foreach ($formulas as $values) { $sheet = $rdobj->setActiveSheetIndexByName($values[0]); self::assertEquals($values[3], $sheet->getCell($values[1])->getValue()); diff --git a/tests/PhpSpreadsheetTests/Functional/ArrayFunctionsSpillTest.php b/tests/PhpSpreadsheetTests/Functional/ArrayFunctionsSpillTest.php index f2309071e5..614ac11497 100644 --- a/tests/PhpSpreadsheetTests/Functional/ArrayFunctionsSpillTest.php +++ b/tests/PhpSpreadsheetTests/Functional/ArrayFunctionsSpillTest.php @@ -86,6 +86,10 @@ public function testArrayOutput(): void public function testNonArrayOutput(): void { $spreadsheet = new Spreadsheet(); + Calculation::getInstance($spreadsheet) + ->setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_VALUE + ); $sheet = $spreadsheet->getActiveSheet(); $sheet->setCellValue('B5', 'OCCUPIED'); diff --git a/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php index 9accf01ae3..ab87485408 100644 --- a/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php @@ -5,11 +5,12 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\Reader\Ods; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; class ArrayFormulaTest extends TestCase { - #[\PHPUnit\Framework\Attributes\DataProvider('arrayFormulaReaderProvider')] + #[DataProvider('arrayFormulaReaderProvider')] public function testArrayFormulaReader( string $cellAddress, string $expectedRange, @@ -25,12 +26,19 @@ public function testArrayFormulaReader( self::assertSame(DataType::TYPE_FORMULA, $cell->getDataType()); self::assertSame(['t' => 'array', 'ref' => $expectedRange], $cell->getFormulaAttributes()); self::assertSame($expectedFormula, strtoupper($cell->getValueString())); - Calculation::getInstance($spreadsheet)->setInstanceArrayReturnType(Calculation::RETURN_ARRAY_AS_ARRAY); + Calculation::getInstance($spreadsheet) + ->setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_ARRAY + ); $worksheet->calculateArrays(); $cell = $worksheet->getCell($cellAddress); self::assertSame($expectedValue, $cell->getCalculatedValue()); if (is_array($expectedValue)) { - self::assertSame($expectedValue, $worksheet->rangeToArray($expectedRange, formatData: false, reduceArrays: true)); + if ($expectedRange === "$cellAddress:$cellAddress") { + self::assertSame([$expectedValue], $worksheet->rangeToArray($expectedRange, formatData: false, reduceArrays: true)); + } else { + self::assertSame($expectedValue, $worksheet->rangeToArray($expectedRange, formatData: false, reduceArrays: true)); + } } else { self::assertSame([[$expectedValue]], $worksheet->rangeToArray($expectedRange, formatData: false, reduceArrays: true)); } @@ -56,7 +64,7 @@ public static function arrayFormulaReaderProvider(): array 'E3', 'E3:E3', '=MAX(SIN({-1,0,1,2}))', - 0.9092974268256817, + [0.9092974268256817], ], [ 'D5', diff --git a/tests/PhpSpreadsheetTests/Reader/Ods/DefinedNamesTest.php b/tests/PhpSpreadsheetTests/Reader/Ods/DefinedNamesTest.php index d5a572f77c..c3d3655e9d 100644 --- a/tests/PhpSpreadsheetTests/Reader/Ods/DefinedNamesTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Ods/DefinedNamesTest.php @@ -4,16 +4,21 @@ namespace PhpOffice\PhpSpreadsheetTests\Reader\Ods; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Reader\Ods; use PHPUnit\Framework\TestCase; class DefinedNamesTest extends TestCase { - public function testDefinedNames(): void + public function testDefinedNamesValue(): void { $filename = 'tests/data/Reader/Ods/DefinedNames.ods'; $reader = new Ods(); $spreadsheet = $reader->load($filename); + $calculation = Calculation::getInstance($spreadsheet); + $calculation->setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_VALUE + ); $worksheet = $spreadsheet->getActiveSheet(); $firstDefinedNameValue = $worksheet->getCell('First')->getValue(); @@ -25,4 +30,25 @@ public function testDefinedNames(): void self::assertSame(12, $calculatedFormulaValue); $spreadsheet->disconnectWorksheets(); } + + public function testDefinedNamesArray(): void + { + $filename = 'tests/data/Reader/Ods/DefinedNames.ods'; + $reader = new Ods(); + $spreadsheet = $reader->load($filename); + $calculation = Calculation::getInstance($spreadsheet); + $calculation->setInstanceArrayReturnType( + Calculation::RETURN_ARRAY_AS_ARRAY + ); + $worksheet = $spreadsheet->getActiveSheet(); + + $firstDefinedNameValue = $worksheet->getCell('First')->getValue(); + $secondDefinedNameValue = $worksheet->getCell('Second')->getValue(); + $calculatedFormulaValue = $worksheet->getCell('B2')->getCalculatedValue(); + + self::assertSame(3, $firstDefinedNameValue); + self::assertSame(4, $secondDefinedNameValue); + self::assertSame([12], $calculatedFormulaValue); + $spreadsheet->disconnectWorksheets(); + } }