diff --git a/CHANGELOG.md b/CHANGELOG.md index 153b1acf..1aed31e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org). ### Added -- ... +- Implementation of IFNA() logical function ### Fixed diff --git a/src/PhpSpreadsheet/Calculation/MathTrig.php b/src/PhpSpreadsheet/Calculation/MathTrig.php index 4e384ea3..30071c2d 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig.php @@ -220,10 +220,9 @@ class MathTrig return Functions::NAN(); } $factLoop = floor($factVal); - if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC) { - if ($factVal > $factLoop) { - return Functions::NAN(); - } + if ((Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC) && + ($factVal > $factLoop)) { + return Functions::NAN(); } $factorial = 1; diff --git a/src/PhpSpreadsheet/Calculation/TextData.php b/src/PhpSpreadsheet/Calculation/TextData.php index e30b2ff7..050c1a9b 100644 --- a/src/PhpSpreadsheet/Calculation/TextData.php +++ b/src/PhpSpreadsheet/Calculation/TextData.php @@ -52,7 +52,7 @@ class TextData return ($stringValue) ? Calculation::getTRUE() : Calculation::getFALSE(); } - if (self::$invalidChars == null) { + if (self::$invalidChars === null) { self::$invalidChars = range(chr(0), chr(31)); } @@ -84,6 +84,15 @@ class TextData return null; } + private static function convertBooleanValue($value) + { + if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) { + return (int) $value; + } + + return ($value) ? Calculation::getTRUE() : Calculation::getFALSE(); + } + /** * ASCIICODE. * @@ -98,11 +107,7 @@ class TextData } $characters = Functions::flattenSingleValue($characters); if (is_bool($characters)) { - if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) { - $characters = (int) $characters; - } else { - $characters = ($characters) ? Calculation::getTRUE() : Calculation::getFALSE(); - } + $characters = self::convertBooleanValue($characters); } $character = $characters; @@ -126,11 +131,7 @@ class TextData $aArgs = Functions::flattenArray($args); foreach ($aArgs as $arg) { if (is_bool($arg)) { - if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) { - $arg = (int) $arg; - } else { - $arg = ($arg) ? Calculation::getTRUE() : Calculation::getFALSE(); - } + $arg = self::convertBooleanValue($arg); } $returnValue .= $arg; } @@ -197,7 +198,7 @@ class TextData } if (($offset > 0) && (StringHelper::countCharacters($haystack) > $offset)) { - if (StringHelper::countCharacters($needle) == 0) { + if (StringHelper::countCharacters($needle) === 0) { return $offset; } @@ -232,7 +233,7 @@ class TextData } if (($offset > 0) && (StringHelper::countCharacters($haystack) > $offset)) { - if (StringHelper::countCharacters($needle) == 0) { + if (StringHelper::countCharacters($needle) === 0) { return $offset; } @@ -659,11 +660,7 @@ class TextData if ($ignoreEmpty && trim($arg) == '') { unset($aArgs[$key]); } elseif (is_bool($arg)) { - if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) { - $arg = (int) $arg; - } else { - $arg = ($arg) ? Calculation::getTRUE() : Calculation::getFALSE(); - } + $arg = self::convertBooleanValue($arg); } } diff --git a/tests/PhpSpreadsheetTests/Calculation/FinancialTest.php b/tests/PhpSpreadsheetTests/Calculation/FinancialTest.php index 2d8d770a..d98d91c5 100644 --- a/tests/PhpSpreadsheetTests/Calculation/FinancialTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/FinancialTest.php @@ -13,38 +13,6 @@ class FinancialTest extends TestCase Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); } - /** - * @dataProvider providerACCRINT - * - * @param mixed $expectedResult - */ - public function testACCRINT($expectedResult, ...$args) - { - $result = Financial::ACCRINT(...$args); - self::assertEquals($expectedResult, $result, '', 1E-8); - } - - public function providerACCRINT() - { - return require 'data/Calculation/Financial/ACCRINT.php'; - } - - /** - * @dataProvider providerACCRINTM - * - * @param mixed $expectedResult - */ - public function testACCRINTM($expectedResult, ...$args) - { - $result = Financial::ACCRINTM(...$args); - self::assertEquals($expectedResult, $result, '', 1E-8); - } - - public function providerACCRINTM() - { - return require 'data/Calculation/Financial/ACCRINTM.php'; - } - /** * @dataProvider providerAMORDEGRC * diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AccrintMTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AccrintMTest.php new file mode 100644 index 00000000..a89d74f1 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AccrintMTest.php @@ -0,0 +1,31 @@ +assertEquals($expectedResult, $result, '', 1E-8); + } + + public function providerACCRINT() + { + return require 'data/Calculation/Financial/ACCRINT.php'; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ChooseTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ChooseTest.php new file mode 100644 index 00000000..c1e043e0 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ChooseTest.php @@ -0,0 +1,31 @@ +assertEquals($expectedResult, $result); + } + + public function providerCHOOSE() + { + return require 'data/Calculation/LookupRef/CHOOSE.php'; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnsTest.php new file mode 100644 index 00000000..06872eec --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnsTest.php @@ -0,0 +1,31 @@ +assertEquals($expectedResult, $result); + } + + public function providerCOLUMNS() + { + return require 'data/Calculation/LookupRef/COLUMNS.php'; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/HLookupTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/HLookupTest.php new file mode 100644 index 00000000..cb1f08fa --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/HLookupTest.php @@ -0,0 +1,31 @@ +assertEquals($expectedResult, $result); + } + + public function providerHLOOKUP() + { + return require 'data/Calculation/LookupRef/HLOOKUP.php'; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndexTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndexTest.php new file mode 100644 index 00000000..0da7de1b --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndexTest.php @@ -0,0 +1,31 @@ +assertEquals($expectedResult, $result); + } + + public function providerINDEX() + { + return require 'data/Calculation/LookupRef/INDEX.php'; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/LookupTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/LookupTest.php new file mode 100644 index 00000000..0c5e610e --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/LookupTest.php @@ -0,0 +1,31 @@ +assertEquals($expectedResult, $result); + } + + public function providerLOOKUP() + { + return require 'data/Calculation/LookupRef/LOOKUP.php'; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php new file mode 100644 index 00000000..42c7b3bb --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php @@ -0,0 +1,31 @@ +assertEquals($expectedResult, $result); + } + + public function providerMATCH() + { + return require 'data/Calculation/LookupRef/MATCH.php'; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php new file mode 100644 index 00000000..46dd9851 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php @@ -0,0 +1,31 @@ +assertEquals($expectedResult, $result); + } + + public function providerROWS() + { + return require 'data/Calculation/LookupRef/ROWS.php'; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/VLookupTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/VLookupTest.php new file mode 100644 index 00000000..ea9afa20 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/VLookupTest.php @@ -0,0 +1,31 @@ +assertEquals($expectedResult, $result); + } + + public function providerVLOOKUP() + { + return require 'data/Calculation/LookupRef/VLOOKUP.php'; + } +} diff --git a/tests/PhpSpreadsheetTests/Calculation/LookupRefTest.php b/tests/PhpSpreadsheetTests/Calculation/LookupRefTest.php index f7f035e7..9d7da8dd 100644 --- a/tests/PhpSpreadsheetTests/Calculation/LookupRefTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/LookupRefTest.php @@ -19,118 +19,6 @@ class LookupRefTest extends TestCase Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); } - /** - * @dataProvider providerHLOOKUP - * - * @param mixed $expectedResult - */ - public function testHLOOKUP($expectedResult, ...$args) - { - $result = LookupRef::HLOOKUP(...$args); - self::assertEquals($expectedResult, $result); - } - - public function providerHLOOKUP() - { - return require 'data/Calculation/LookupRef/HLOOKUP.php'; - } - - /** - * @dataProvider providerVLOOKUP - * - * @param mixed $expectedResult - */ - public function testVLOOKUP($expectedResult, ...$args) - { - $result = LookupRef::VLOOKUP(...$args); - self::assertEquals($expectedResult, $result); - } - - public function providerVLOOKUP() - { - return require 'data/Calculation/LookupRef/VLOOKUP.php'; - } - - /** - * @dataProvider providerLOOKUP - * - * @param mixed $expectedResult - */ - public function testLOOKUP($expectedResult, ...$args) - { - $result = LookupRef::LOOKUP(...$args); - self::assertEquals($expectedResult, $result); - } - - public function providerLOOKUP() - { - return require 'data/Calculation/LookupRef/LOOKUP.php'; - } - - /** - * @dataProvider providerMATCH - * - * @param mixed $expectedResult - */ - public function testMATCH($expectedResult, ...$args) - { - $result = LookupRef::MATCH(...$args); - self::assertEquals($expectedResult, $result); - } - - public function providerMATCH() - { - return require 'data/Calculation/LookupRef/MATCH.php'; - } - - /** - * @dataProvider providerINDEX - * - * @param mixed $expectedResult - */ - public function testINDEX($expectedResult, ...$args) - { - $result = LookupRef::INDEX(...$args); - self::assertEquals($expectedResult, $result); - } - - public function providerINDEX() - { - return require 'data/Calculation/LookupRef/INDEX.php'; - } - - /** - * @dataProvider providerCOLUMNS - * - * @param mixed $expectedResult - */ - public function testCOLUMNS($expectedResult, ...$args) - { - $result = LookupRef::COLUMNS(...$args); - self::assertEquals($expectedResult, $result); - } - - public function providerCOLUMNS() - { - return require 'data/Calculation/LookupRef/COLUMNS.php'; - } - - /** - * @dataProvider providerROWS - * - * @param mixed $expectedResult - */ - public function testROWS($expectedResult, ...$args) - { - $result = LookupRef::ROWS(...$args); - self::assertEquals($expectedResult, $result); - } - - public function providerROWS() - { - return require 'data/Calculation/LookupRef/ROWS.php'; - } - /** * @dataProvider providerFormulaText * diff --git a/tests/data/Calculation/DateTime/DATE.php b/tests/data/Calculation/DateTime/DATE.php index 83beefb8..a7b3e7cc 100644 --- a/tests/data/Calculation/DateTime/DATE.php +++ b/tests/data/Calculation/DateTime/DATE.php @@ -1,52 +1,43 @@ [ + 6890, // '11th November 1918' 18, 11, 11, ], - // Excel 1900 Calendar Base Date - [ + 'Excel 1900 Calendar Base Date' => [ 1, 1900, 1, 1, ], - // Day before Excel mythical 1900 leap day - [ + 'Day before Excel mythical 1900 leap day' => [ 59, 1900, 2, 28, ], - // Excel mythical 1900 leap day - [ + 'Excel mythical 1900 leap day' => [ 60, 1900, 2, 29, ], - [ - // Day after Excel mythical 1900 leap day + 'Day after Excel mythical 1900 leap day' => [ 61, 1900, 3, 1, ], - // Day after Excel actual 1904 leap day - [ + 'Day after Excel actual 1904 leap day' => [ 713, 1901, 12, 13, ], - // PHP 32-bit Earliest Date (unix timestamp) - [ + 'signed 32-bit Unix Timestamp Earliest Date' => [ 714, 1901, 12, 14, ], - [ + 'Day before Excel 1904 Calendar Base Date' => [ 1461, 1903, 12, 31, ], - // Excel 1904 Calendar Base Date - [ + 'Excel 1904 Calendar Base Date' => [ 1462, 1904, 1, 1, ], - [ + 'Day after Excel 1904 Calendar Base Date' => [ 1463, 1904, 1, 2, ], @@ -54,8 +45,7 @@ return [ 22269, 1960, 12, 19, ], - // PHP (unix timestamp) Base Date - [ + 'Unix Timestamp Base Date' => [ 25569, 1970, 1, 1, ], @@ -67,13 +57,11 @@ return [ 39611, 2008, 6, 12, ], - // PHP (unix timestamp) 32-bit Latest Date - [ + '32-bit signed Unix Timestamp Latest Date' => [ 50424, 2038, 1, 19, ], - // Day after PHP (unix timestamp) 32-bit Latest Date - [ + 'Day after 32-bit signed Unix Timestamp Latest Date' => [ 50425, 2038, 1, 20, ], @@ -245,13 +233,11 @@ return [ '#NUM!', -20, 6, 15, ], - // Excel Maximum Date - [ + 'Excel Maximum Date' => [ 2958465, 9999, 12, 31, ], - // Exceeded Excel Maximum Date - [ + 'Exceeded Excel Maximum Date' => [ '#NUM!', 10000, 1, 1, ], @@ -329,5 +315,5 @@ return [ [ '#VALUE!', 2010, 3, 'GHI', - ], + ] ]; diff --git a/tests/data/Calculation/LookupRef/CHOOSE.php b/tests/data/Calculation/LookupRef/CHOOSE.php new file mode 100644 index 00000000..020ef498 --- /dev/null +++ b/tests/data/Calculation/LookupRef/CHOOSE.php @@ -0,0 +1,28 @@ +