From 35b65bef8c92fa440a54548563b8c4776ae18371 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sun, 20 Feb 2022 16:46:25 +0100 Subject: [PATCH] First steps toward array-enabling the information functions (#2608) * First steps toward array-enabling the information functions Also includes moving unit tests out from Functions and into a separate, dedicated Information folder * Resolve issue with IF(), branch pruning and calculation cache (ensure that we don't convert the if condition to a bool before we've tested to see if it evaluates to an error) More refactoring --- .../Calculation/Calculation.php | 30 ++- src/PhpSpreadsheet/Calculation/Functions.php | 26 +-- .../Calculation/Information/ErrorValue.php | 71 +++++++ .../Calculation/Information/Value.php | 132 ++++++------ .../Calculation/Logical/Conditional.php | 12 +- .../LookupRef/LookupRefValidations.php | 4 +- .../Calculation/MathTrig/Sum.php | 5 +- .../Calculation/Statistical.php | 2 +- .../Distributions/StandardNormal.php | 12 +- src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php | 3 +- .../Functions/Information/IsBlankTest.php | 54 +++++ .../Functions/Information/IsErrTest.php | 54 +++++ .../Functions/Information/IsErrorTest.php | 54 +++++ .../Functions/Information/IsEvenTest.php | 56 +++++ .../Functions/Information/IsLogicalTest.php | 54 +++++ .../Functions/Information/IsNaTest.php | 54 +++++ .../Functions/Information/IsNonTextTest.php | 54 +++++ .../Functions/Information/IsNumberTest.php | 54 +++++ .../Functions/Information/IsOddTest.php | 56 +++++ .../Functions/Information/IsTextTest.php | 54 +++++ .../Functions/Information/NTest.php | 32 +++ .../Functions/Information/TypeTest.php | 31 +++ .../Functions/Statistical/ZTestTest.php | 26 +++ .../Calculation/FunctionsTest.php | 192 ------------------ .../{Functions => Information}/IS_BLANK.php | 3 - .../{Functions => Information}/IS_ERR.php | 3 - .../{Functions => Information}/IS_ERROR.php | 3 - .../{Functions => Information}/IS_EVEN.php | 3 - .../{Functions => Information}/IS_LOGICAL.php | 3 - .../{Functions => Information}/IS_NA.php | 3 - .../{Functions => Information}/IS_NONTEXT.php | 3 - .../{Functions => Information}/IS_NUMBER.php | 3 - .../{Functions => Information}/IS_ODD.php | 3 - .../{Functions => Information}/IS_TEXT.php | 3 - .../{Functions => Information}/N.php | 3 - .../{Functions => Information}/TYPE.php | 3 - 36 files changed, 817 insertions(+), 341 deletions(-) create mode 100644 src/PhpSpreadsheet/Calculation/Information/ErrorValue.php create mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsBlankTest.php create mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsErrTest.php create mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsErrorTest.php create mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsEvenTest.php create mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsLogicalTest.php create mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNaTest.php create mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNonTextTest.php create mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNumberTest.php create mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsOddTest.php create mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsTextTest.php create mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/Information/NTest.php create mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/Information/TypeTest.php rename tests/data/Calculation/{Functions => Information}/IS_BLANK.php (96%) rename tests/data/Calculation/{Functions => Information}/IS_ERR.php (95%) rename tests/data/Calculation/{Functions => Information}/IS_ERROR.php (95%) rename tests/data/Calculation/{Functions => Information}/IS_EVEN.php (96%) rename tests/data/Calculation/{Functions => Information}/IS_LOGICAL.php (95%) rename tests/data/Calculation/{Functions => Information}/IS_NA.php (95%) rename tests/data/Calculation/{Functions => Information}/IS_NONTEXT.php (95%) rename tests/data/Calculation/{Functions => Information}/IS_NUMBER.php (95%) rename tests/data/Calculation/{Functions => Information}/IS_ODD.php (96%) rename tests/data/Calculation/{Functions => Information}/IS_TEXT.php (95%) rename tests/data/Calculation/{Functions => Information}/N.php (98%) rename tests/data/Calculation/{Functions => Information}/TYPE.php (97%) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 81a0353b..8ba77d3b 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Engine\CyclicReferenceStack; use PhpOffice\PhpSpreadsheet\Calculation\Engine\Logger; +use PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue; use PhpOffice\PhpSpreadsheet\Calculation\Information\Value; use PhpOffice\PhpSpreadsheet\Calculation\Token\Stack; use PhpOffice\PhpSpreadsheet\Cell\Cell; @@ -1463,12 +1464,12 @@ class Calculation ], 'ISERR' => [ 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Information\Value::class, 'isErr'], + 'functionCall' => [Information\ErrorValue::class, 'isErr'], 'argumentCount' => '1', ], 'ISERROR' => [ 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Information\Value::class, 'isError'], + 'functionCall' => [Information\ErrorValue::class, 'isError'], 'argumentCount' => '1', ], 'ISEVEN' => [ @@ -1490,7 +1491,7 @@ class Calculation ], 'ISNA' => [ 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Information\Value::class, 'isNa'], + 'functionCall' => [Information\ErrorValue::class, 'isNa'], 'argumentCount' => '1', ], 'ISNONTEXT' => [ @@ -1765,7 +1766,7 @@ class Calculation ], 'NA' => [ 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Functions::class, 'NA'], + 'functionCall' => [Information\ExcelError::class, 'NA'], 'argumentCount' => '0', ], 'NEGBINOMDIST' => [ @@ -3894,8 +3895,8 @@ class Calculation $regexpMatchString = '/^(' . self::CALCULATION_REGEXP_FUNCTION . '|' . self::CALCULATION_REGEXP_CELLREF . - '|' . self::CALCULATION_REGEXP_COLUMN_RANGE . - '|' . self::CALCULATION_REGEXP_ROW_RANGE . + '|' . self::CALCULATION_REGEXP_COLUMN_RANGE . + '|' . self::CALCULATION_REGEXP_ROW_RANGE . '|' . self::CALCULATION_REGEXP_NUMBER . '|' . self::CALCULATION_REGEXP_STRING . '|' . self::CALCULATION_REGEXP_OPENBRACE . @@ -4009,10 +4010,11 @@ class Calculation --$parenthesisDepthMap[$pendingStoreKey]; } - if (is_array($d) && preg_match('/^' . self::CALCULATION_REGEXP_FUNCTION . '$/miu', $d['value'], $matches)) { // Did this parenthesis just close a function? + if (is_array($d) && preg_match('/^' . self::CALCULATION_REGEXP_FUNCTION . '$/miu', $d['value'], $matches)) { + // Did this parenthesis just close a function? if (!empty($pendingStoreKey) && $parenthesisDepthMap[$pendingStoreKey] == -1) { // we are closing an IF( - if ($d['value'] != 'IF(') { + if ($d['value'] !== 'IF(') { return $this->raiseFormulaError('Parser bug we should be in an "IF("'); } if ($expectingConditionMap[$pendingStoreKey]) { @@ -4427,11 +4429,7 @@ class Calculation if ( isset($storeValue) - && ( - !$storeValueAsBool - || Value::isError($storeValue) - || ($storeValue === 'Pruned branch') - ) + && (!$storeValueAsBool || ErrorValue::isError($storeValue) || ($storeValue === 'Pruned branch')) ) { // If branching value is not true, we don't need to compute if (!isset($fakedForBranchPruning['onlyIf-' . $onlyIfStoreKey])) { @@ -4462,11 +4460,7 @@ class Calculation } if ( isset($storeValue) - && ( - $storeValueAsBool - || Value::isError($storeValue) - || ($storeValue === 'Pruned branch') - ) + && ($storeValueAsBool || ErrorValue::isError($storeValue) || ($storeValue === 'Pruned branch')) ) { // If branching value is true, we don't need to compute if (!isset($fakedForBranchPruning['onlyIfNot-' . $onlyIfNotStoreKey])) { diff --git a/src/PhpSpreadsheet/Calculation/Functions.php b/src/PhpSpreadsheet/Calculation/Functions.php index c3b7c257..8911a5d4 100644 --- a/src/PhpSpreadsheet/Calculation/Functions.php +++ b/src/PhpSpreadsheet/Calculation/Functions.php @@ -346,7 +346,7 @@ class Functions * @see Information\Value::isBlank() * Use the isBlank() method in the Information\Value class instead * - * @return bool + * @return array|bool */ public static function isBlank($value = null) { @@ -363,11 +363,11 @@ class Functions * @see Information\Value::isErr() * Use the isErr() method in the Information\Value class instead * - * @return bool + * @return array|bool */ public static function isErr($value = '') { - return Information\Value::isErr($value); + return Information\ErrorValue::isErr($value); } /** @@ -380,11 +380,11 @@ class Functions * @see Information\Value::isError() * Use the isError() method in the Information\Value class instead * - * @return bool + * @return array|bool */ public static function isError($value = '') { - return Information\Value::isError($value); + return Information\ErrorValue::isError($value); } /** @@ -397,11 +397,11 @@ class Functions * @see Information\Value::isNa() * Use the isNa() method in the Information\Value class instead * - * @return bool + * @return array|bool */ public static function isNa($value = '') { - return Information\Value::isNa($value); + return Information\ErrorValue::isNa($value); } /** @@ -414,7 +414,7 @@ class Functions * @see Information\Value::isEven() * Use the isEven() method in the Information\Value class instead * - * @return bool|string + * @return array|bool|string */ public static function isEven($value = null) { @@ -431,7 +431,7 @@ class Functions * @see Information\Value::isOdd() * Use the isOdd() method in the Information\Value class instead * - * @return bool|string + * @return array|bool|string */ public static function isOdd($value = null) { @@ -448,7 +448,7 @@ class Functions * @see Information\Value::isNumber() * Use the isNumber() method in the Information\Value class instead * - * @return bool + * @return array|bool */ public static function isNumber($value = null) { @@ -465,7 +465,7 @@ class Functions * @see Information\Value::isLogical() * Use the isLogical() method in the Information\Value class instead * - * @return bool + * @return array|bool */ public static function isLogical($value = null) { @@ -482,7 +482,7 @@ class Functions * @see Information\Value::isText() * Use the isText() method in the Information\Value class instead * - * @return bool + * @return array|bool */ public static function isText($value = null) { @@ -499,7 +499,7 @@ class Functions * @see Information\Value::isNonText() * Use the isNonText() method in the Information\Value class instead * - * @return bool + * @return array|bool */ public static function isNonText($value = null) { diff --git a/src/PhpSpreadsheet/Calculation/Information/ErrorValue.php b/src/PhpSpreadsheet/Calculation/Information/ErrorValue.php new file mode 100644 index 00000000..dabe7d1c --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/Information/ErrorValue.php @@ -0,0 +1,71 @@ +getCell($cellReference)->isFormula() : ExcelError::REF(); } - /** - * IS_ERR. - * - * @param mixed $value Value to check - * - * @return bool - */ - public static function isErr($value = '') - { - $value = Functions::flattenSingleValue($value); - - return self::isError($value) && (!self::isNa(($value))); - } - - /** - * IS_ERROR. - * - * @param mixed $value Value to check - * - * @return bool - */ - public static function isError($value = '') - { - $value = Functions::flattenSingleValue($value); - - if (!is_string($value)) { - return false; - } - - return in_array($value, ExcelError::$errorCodes); - } - - /** - * IS_NA. - * - * @param mixed $value Value to check - * - * @return bool - */ - public static function isNa($value = '') - { - $value = Functions::flattenSingleValue($value); - - return $value === ExcelError::NA(); - } - /** * N. * @@ -205,12 +201,12 @@ class Value * * @return number N converts values listed in the following table * If value is or refers to N returns - * A number That number - * A date The serial number of that date + * A number That number value + * A date The Excel serialized number of that date * TRUE 1 - * FALSE 0 - * An error value The error value - * Anything else 0 + * FALSE 0 + * An error value The error value + * Anything else 0 */ public static function asNumber($value = null) { @@ -248,9 +244,9 @@ class Value * If value is or refers to N returns * A number 1 * Text 2 - * Logical Value 4 - * An error value 16 - * Array or Matrix 64 + * Logical Value 4 + * An error value 16 + * Array or Matrix 64 */ public static function type($value = null) { @@ -269,8 +265,8 @@ class Value // Empty Cell return 1; } - $value = Functions::flattenSingleValue($value); + $value = Functions::flattenSingleValue($value); if (($value === null) || (is_float($value)) || (is_int($value))) { return 1; } elseif (is_bool($value)) { diff --git a/src/PhpSpreadsheet/Calculation/Logical/Conditional.php b/src/PhpSpreadsheet/Calculation/Logical/Conditional.php index 86842d3a..6a7757ce 100644 --- a/src/PhpSpreadsheet/Calculation/Logical/Conditional.php +++ b/src/PhpSpreadsheet/Calculation/Logical/Conditional.php @@ -5,6 +5,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Logical; use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; +use PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Calculation\Information\Value; @@ -47,15 +48,16 @@ class Conditional */ public static function statementIf($condition = true, $returnIfTrue = 0, $returnIfFalse = false) { - if (Value::isError($condition)) { + $condition = ($condition === null) ? true : Functions::flattenSingleValue($condition); + + if (ErrorValue::isError($condition)) { return $condition; } - $condition = ($condition === null) ? true : (bool) Functions::flattenSingleValue($condition); $returnIfTrue = $returnIfTrue ?? 0; $returnIfFalse = $returnIfFalse ?? false; - return ($condition) ? $returnIfTrue : $returnIfFalse; + return ((bool) $condition) ? $returnIfTrue : $returnIfFalse; } /** @@ -138,7 +140,7 @@ class Conditional $errorpart = $errorpart ?? ''; - return self::statementIf(Value::isError($testValue), $errorpart, $testValue); + return self::statementIf(ErrorValue::isError($testValue), $errorpart, $testValue); } /** @@ -164,7 +166,7 @@ class Conditional $napart = $napart ?? ''; - return self::statementIf(Value::isNa($testValue), $napart, $testValue); + return self::statementIf(ErrorValue::isNa($testValue), $napart, $testValue); } /** diff --git a/src/PhpSpreadsheet/Calculation/LookupRef/LookupRefValidations.php b/src/PhpSpreadsheet/Calculation/LookupRef/LookupRefValidations.php index e1f39765..2282bf47 100644 --- a/src/PhpSpreadsheet/Calculation/LookupRef/LookupRefValidations.php +++ b/src/PhpSpreadsheet/Calculation/LookupRef/LookupRefValidations.php @@ -3,8 +3,8 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\LookupRef; use PhpOffice\PhpSpreadsheet\Calculation\Exception; +use PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; -use PhpOffice\PhpSpreadsheet\Calculation\Information\Value; class LookupRefValidations { @@ -14,7 +14,7 @@ class LookupRefValidations public static function validateInt($value): int { if (!is_numeric($value)) { - if (Value::isError($value)) { + if (ErrorValue::isError($value)) { throw new Exception($value); } diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Sum.php b/src/PhpSpreadsheet/Calculation/MathTrig/Sum.php index 82b261f1..1a797c8a 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Sum.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Sum.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig; use PhpOffice\PhpSpreadsheet\Calculation\Functions; +use PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Calculation\Information\Value; @@ -29,7 +30,7 @@ class Sum // Is it a numeric value? if (is_numeric($arg)) { $returnValue += $arg; - } elseif (Value::isError($arg)) { + } elseif (ErrorValue::isError($arg)) { return $arg; } } @@ -63,7 +64,7 @@ class Sum $returnValue += $arg; } elseif (is_bool($arg)) { $returnValue += (int) $arg; - } elseif (Value::isError($arg)) { + } elseif (ErrorValue::isError($arg)) { return $arg; // ignore non-numerics from cell, but fail as literals (except null) } elseif ($arg !== null && !Functions::isCellValue($k)) { diff --git a/src/PhpSpreadsheet/Calculation/Statistical.php b/src/PhpSpreadsheet/Calculation/Statistical.php index 73db0aa7..497c9297 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical.php +++ b/src/PhpSpreadsheet/Calculation/Statistical.php @@ -1811,7 +1811,7 @@ class Statistical * @param float $m0 Alpha Parameter * @param float $sigma Beta Parameter * - * @return float|string (string if result is an error) + * @return array|float|string (string if result is an error) */ public static function ZTEST($dataSet, $m0, $sigma = null) { diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php index 31a02e29..8239dac8 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php @@ -117,16 +117,22 @@ class StandardNormal * * @param mixed $dataSet The dataset should be an array of float values for the observations * @param mixed $m0 Alpha Parameter + * Or can be an array of values * @param mixed $sigma A null or float value for the Beta (Standard Deviation) Parameter; * if null, we use the standard deviation of the dataset + * Or can be an array of values * - * @return float|string (string if result is an error) + * @return array|float|string (string if result is an error) + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function zTest($dataSet, $m0, $sigma = null) { + if (is_array($m0) || is_array($sigma)) { + return self::evaluateArrayArgumentsSubsetFrom([self::class, __FUNCTION__], 1, $dataSet, $m0, $sigma); + } + $dataSet = Functions::flattenArrayIndexed($dataSet); - $m0 = Functions::flattenSingleValue($m0); - $sigma = Functions::flattenSingleValue($sigma); if (!is_numeric($m0) || ($sigma !== null && !is_numeric($sigma))) { return ExcelError::VALUE(); diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index 2028fa30..c5502a33 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx; +use PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue; use PhpOffice\PhpSpreadsheet\Calculation\Information\Value; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; @@ -1251,7 +1252,7 @@ class Worksheet extends WriterPart { $calculatedValue = $this->getParentWriter()->getPreCalculateFormulas() ? $cell->getCalculatedValue() : $cellValue; if (is_string($calculatedValue)) { - if (Value::isError($calculatedValue)) { + if (ErrorValue::isError($calculatedValue)) { $this->writeCellError($objWriter, 'e', $cellValue, $calculatedValue); return; diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsBlankTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsBlankTest.php new file mode 100644 index 00000000..0cf03591 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsBlankTest.php @@ -0,0 +1,54 @@ +_calculateFormulaValue($formula); + self::assertEquals($expectedResult, $result); + } + + public function providerIsBlankArray(): array + { + return [ + 'vector' => [ + [[false, true, false]], + '{12, NULL, ""}', + ], + ]; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsErrTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsErrTest.php new file mode 100644 index 00000000..1360a607 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsErrTest.php @@ -0,0 +1,54 @@ +_calculateFormulaValue($formula); + self::assertEquals($expectedResult, $result); + } + + public function providerIsErrArray(): array + { + return [ + 'vector' => [ + [[true, true, false, false, false, false]], + '{5/0, "#REF!", "#N/A", 1.2, TRUE, "PHP"}', + ], + ]; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsErrorTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsErrorTest.php new file mode 100644 index 00000000..674062ee --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsErrorTest.php @@ -0,0 +1,54 @@ +_calculateFormulaValue($formula); + self::assertEquals($expectedResult, $result); + } + + public function providerIsErrorArray(): array + { + return [ + 'vector' => [ + [[true, true, true, false, false, false]], + '{5/0, "#REF!", "#N/A", 1.2, TRUE, "PHP"}', + ], + ]; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsEvenTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsEvenTest.php new file mode 100644 index 00000000..baad4816 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsEvenTest.php @@ -0,0 +1,56 @@ +_calculateFormulaValue($formula); + self::assertEquals($expectedResult, $result); + } + + public function providerIsEvenArray(): array + { + return [ + 'vector' => [ + [[true, false, true, false, true]], + '{-2, -1, 0, 1, 2}', + ], + ]; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsLogicalTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsLogicalTest.php new file mode 100644 index 00000000..0c220aee --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsLogicalTest.php @@ -0,0 +1,54 @@ +_calculateFormulaValue($formula); + self::assertEquals($expectedResult, $result); + } + + public function providerIsLogicalArray(): array + { + return [ + 'vector' => [ + [[true, false, false, false, true, false]], + '{true, -1, null, 1, false, "FALSE"}', + ], + ]; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNaTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNaTest.php new file mode 100644 index 00000000..5fac18fa --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNaTest.php @@ -0,0 +1,54 @@ +_calculateFormulaValue($formula); + self::assertEquals($expectedResult, $result); + } + + public function providerIsNaArray(): array + { + return [ + 'vector' => [ + [[false, false, true, false, false, false]], + '{5/0, "#REF!", "#N/A", 1.2, TRUE, "PHP"}', + ], + ]; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNonTextTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNonTextTest.php new file mode 100644 index 00000000..759d7b30 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNonTextTest.php @@ -0,0 +1,54 @@ +_calculateFormulaValue($formula); + self::assertEquals($expectedResult, $result); + } + + public function providerIsNonTextArray(): array + { + return [ + 'vector' => [ + [[true, false, false, true, true]], + '{-2, "PHP", "123.456", false, 2.34}', + ], + ]; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNumberTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNumberTest.php new file mode 100644 index 00000000..649e4335 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNumberTest.php @@ -0,0 +1,54 @@ +_calculateFormulaValue($formula); + self::assertEquals($expectedResult, $result); + } + + public function providerIsNumberArray(): array + { + return [ + 'vector' => [ + [[true, false, false, false, true]], + '{-2, "PHP", "123.456", false, 2.34}', + ], + ]; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsOddTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsOddTest.php new file mode 100644 index 00000000..4f31ff38 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsOddTest.php @@ -0,0 +1,56 @@ +_calculateFormulaValue($formula); + self::assertEquals($expectedResult, $result); + } + + public function providerIsOddArray(): array + { + return [ + 'vector' => [ + [[false, true, false, true, false]], + '{-2, -1, 0, 1, 2}', + ], + ]; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsTextTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsTextTest.php new file mode 100644 index 00000000..cdbba409 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsTextTest.php @@ -0,0 +1,54 @@ +_calculateFormulaValue($formula); + self::assertEquals($expectedResult, $result); + } + + public function providerIsTextArray(): array + { + return [ + 'vector' => [ + [[false, true, true, false, false]], + '{-2, "PHP", "123.456", false, 2.34}', + ], + ]; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/NTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/NTest.php new file mode 100644 index 00000000..1ff5a03d --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/NTest.php @@ -0,0 +1,32 @@ +_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerZTestArray(): array + { + return [ + 'row vector' => [ + [ + [0.09057419685136381, 0.4516213175273426, 0.8630433891295299], + ], + '{3, 6, 7, 8, 6, 5, 4, 2, 1, 9}', + '{4, 5, 6}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php b/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php index 0f518ea5..16fe8651 100644 --- a/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php @@ -116,54 +116,6 @@ class FunctionsTest extends TestCase self::assertEquals('#VALUE!', $result); } - /** - * @dataProvider providerIsBlank - * - * @param mixed $expectedResult - */ - public function testIsBlank($expectedResult, ...$args): void - { - $result = Functions::isBlank(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); - } - - public function providerIsBlank(): array - { - return require 'tests/data/Calculation/Functions/IS_BLANK.php'; - } - - /** - * @dataProvider providerIsErr - * - * @param mixed $expectedResult - */ - public function testIsErr($expectedResult, ...$args): void - { - $result = Functions::isErr(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); - } - - public function providerIsErr(): array - { - return require 'tests/data/Calculation/Functions/IS_ERR.php'; - } - - /** - * @dataProvider providerIsError - * - * @param mixed $expectedResult - */ - public function testIsError($expectedResult, ...$args): void - { - $result = Functions::isError(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); - } - - public function providerIsError(): array - { - return require 'tests/data/Calculation/Functions/IS_ERROR.php'; - } - /** * @dataProvider providerErrorType * @@ -180,150 +132,6 @@ class FunctionsTest extends TestCase return require 'tests/data/Calculation/Functions/ERROR_TYPE.php'; } - /** - * @dataProvider providerIsLogical - * - * @param mixed $expectedResult - */ - public function testIsLogical($expectedResult, ...$args): void - { - $result = Functions::isLogical(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); - } - - public function providerIsLogical(): array - { - return require 'tests/data/Calculation/Functions/IS_LOGICAL.php'; - } - - /** - * @dataProvider providerIsNa - * - * @param mixed $expectedResult - */ - public function testIsNa($expectedResult, ...$args): void - { - $result = Functions::isNa(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); - } - - public function providerIsNa(): array - { - return require 'tests/data/Calculation/Functions/IS_NA.php'; - } - - /** - * @dataProvider providerIsNumber - * - * @param mixed $expectedResult - */ - public function testIsNumber($expectedResult, ...$args): void - { - $result = Functions::isNumber(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); - } - - public function providerIsNumber(): array - { - return require 'tests/data/Calculation/Functions/IS_NUMBER.php'; - } - - /** - * @dataProvider providerIsText - * - * @param mixed $expectedResult - */ - public function testIsText($expectedResult, ...$args): void - { - $result = Functions::isText(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); - } - - public function providerIsText(): array - { - return require 'tests/data/Calculation/Functions/IS_TEXT.php'; - } - - /** - * @dataProvider providerIsNonText - * - * @param mixed $expectedResult - */ - public function testIsNonText($expectedResult, ...$args): void - { - $result = Functions::isNonText(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); - } - - public function providerIsNonText(): array - { - return require 'tests/data/Calculation/Functions/IS_NONTEXT.php'; - } - - /** - * @dataProvider providerIsEven - * - * @param mixed $expectedResult - */ - public function testIsEven($expectedResult, ...$args): void - { - $result = Functions::isEven(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); - } - - public function providerIsEven(): array - { - return require 'tests/data/Calculation/Functions/IS_EVEN.php'; - } - - /** - * @dataProvider providerIsOdd - * - * @param mixed $expectedResult - */ - public function testIsOdd($expectedResult, ...$args): void - { - $result = Functions::isOdd(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); - } - - public function providerIsOdd(): array - { - return require 'tests/data/Calculation/Functions/IS_ODD.php'; - } - - /** - * @dataProvider providerTYPE - * - * @param mixed $expectedResult - */ - public function testTYPE($expectedResult, ...$args): void - { - $result = Functions::TYPE(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); - } - - public function providerTYPE(): array - { - return require 'tests/data/Calculation/Functions/TYPE.php'; - } - - /** - * @dataProvider providerN - * - * @param mixed $expectedResult - */ - public function testN($expectedResult, ...$args): void - { - $result = Functions::n(...$args); - self::assertEqualsWithDelta($expectedResult, $result, 1E-8); - } - - public function providerN(): array - { - return require 'tests/data/Calculation/Functions/N.php'; - } - /** * @dataProvider providerIfCondition * diff --git a/tests/data/Calculation/Functions/IS_BLANK.php b/tests/data/Calculation/Information/IS_BLANK.php similarity index 96% rename from tests/data/Calculation/Functions/IS_BLANK.php rename to tests/data/Calculation/Information/IS_BLANK.php index 83f25163..c2c9aec1 100644 --- a/tests/data/Calculation/Functions/IS_BLANK.php +++ b/tests/data/Calculation/Information/IS_BLANK.php @@ -1,9 +1,6 @@