From 0a7b36fd7a024cf466fad62e5cdb25f627b13b44 Mon Sep 17 00:00:00 2001 From: Owen Leibman Date: Sat, 5 Dec 2020 22:25:42 -0800 Subject: [PATCH] TextData Coverage and Minor Bug Fixes This had been intended to get 100% coverage for TextData functions, and it does that. However, some minor bugs requiring source changes arose during testing. - the Excel CHAR function restricts its argument to 1-255. PhpSpreadsheet CHARACTER had been allowing 0+. Also, there is no need to test if iconv exists, since it is part of Composer requirements. - The DOLLAR function had been returning NUM for invalid arguments. Excel returns VALUE. Also, negative amounts were not being handled correctly. - The FIXEDFORMAT function had been returning NUM for invalid arguments. Excel FIXED returns VALUE. --- src/PhpSpreadsheet/Calculation/TextData.php | 15 +++++----- tests/data/Calculation/TextData/CHAR.php | 28 ++++++++++++++---- tests/data/Calculation/TextData/DOLLAR.php | 18 ++++++++++-- tests/data/Calculation/TextData/FIXED.php | 32 +++++++++++++++++++-- tests/data/Calculation/TextData/SEARCH.php | 5 ++++ 5 files changed, 81 insertions(+), 17 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/TextData.php b/src/PhpSpreadsheet/Calculation/TextData.php index da958836ce..f89744029e 100644 --- a/src/PhpSpreadsheet/Calculation/TextData.php +++ b/src/PhpSpreadsheet/Calculation/TextData.php @@ -27,15 +27,15 @@ public static function CHARACTER($character) { $character = Functions::flattenSingleValue($character); - if ((!is_numeric($character)) || ($character < 0)) { + if (!is_numeric($character)) { return Functions::VALUE(); } - - if (function_exists('iconv')) { - return iconv('UCS-4LE', 'UTF-8', pack('V', $character)); + $character = (int) $character; + if ($character < 1 || $character > 255) { + return Functions::VALUE(); } - return mb_convert_encoding('&#' . (int) $character . ';', 'UTF-8', 'HTML-ENTITIES'); + return iconv('UCS-4LE', 'UTF-8', pack('V', $character)); } /** @@ -160,7 +160,7 @@ public static function DOLLAR($value = 0, $decimals = 2) // Validate parameters if (!is_numeric($value) || !is_numeric($decimals)) { - return Functions::NAN(); + return Functions::VALUE(); } $decimals = floor($decimals); @@ -174,6 +174,7 @@ public static function DOLLAR($value = 0, $decimals = 2) } $value = MathTrig::MROUND($value, $round); } + $mask = "$mask;($mask)"; return NumberFormat::toFormattedString($value, $mask); } @@ -265,7 +266,7 @@ public static function FIXEDFORMAT($value, $decimals = 2, $no_commas = false) // Validate parameters if (!is_numeric($value) || !is_numeric($decimals)) { - return Functions::NAN(); + return Functions::VALUE(); } $decimals = (int) floor($decimals); diff --git a/tests/data/Calculation/TextData/CHAR.php b/tests/data/Calculation/TextData/CHAR.php index 1751699c3d..276d701518 100644 --- a/tests/data/Calculation/TextData/CHAR.php +++ b/tests/data/Calculation/TextData/CHAR.php @@ -9,6 +9,10 @@ '#VALUE!', -5, ], + [ + '#VALUE!', + 0, + ], [ 'A', 65, @@ -22,27 +26,39 @@ 126, ], [ - '⽇', + 'Á', + 193, + ], + [ + 'ÿ', + 255, + ], + [ + '#VALUE!', + 256, + ], + [ + '#VALUE!', // '⽇', 12103, ], [ - 'œ', + '#VALUE!', // 'œ', 0x153, ], [ - 'ƒ', + '#VALUE!', // 'ƒ', 0x192, ], [ - '℅', + '#VALUE!', // '℅', 0x2105, ], [ - '∑', + '#VALUE!', // '∑', 0x2211, ], [ - '†', + '#VALUE!', // '†', 0x2020, ], ]; diff --git a/tests/data/Calculation/TextData/DOLLAR.php b/tests/data/Calculation/TextData/DOLLAR.php index 95555e7c4c..67f394bb72 100644 --- a/tests/data/Calculation/TextData/DOLLAR.php +++ b/tests/data/Calculation/TextData/DOLLAR.php @@ -6,11 +6,20 @@ 123.456, 2, ], + [ + '$123.46', + 123.456, + ], [ '$123.32', 123.321, 2, ], + [ + '($123.32)', + -123.321, + 2, + ], [ '$1,235,000', 1234567, @@ -22,12 +31,17 @@ -5, ], [ - '#NUM!', + '($1,200,000)', + -1234567, + -5, + ], + [ + '#VALUE!', 'ABC', 2, ], [ - '#NUM!', + '#VALUE!', 123.456, 'ABC', ], diff --git a/tests/data/Calculation/TextData/FIXED.php b/tests/data/Calculation/TextData/FIXED.php index b8bb36ca4b..2083eccebe 100644 --- a/tests/data/Calculation/TextData/FIXED.php +++ b/tests/data/Calculation/TextData/FIXED.php @@ -20,13 +20,41 @@ true, ], [ - '#NUM!', + '-123456.79', + -123456.789, + 2, + true, + ], + [ + '123500', + 123456.789, + -2, + true, + ], + [ + '123,500', + 123456.789, + -2, + ], + [ + '-123500', + -123456.789, + -2, + true, + ], + [ + '-123,500', + -123456.789, + -2, + ], + [ + '#VALUE!', 'ABC', 2, null, ], [ - '#NUM!', + '#VALUE!', 123.456, 'ABC', null, diff --git a/tests/data/Calculation/TextData/SEARCH.php b/tests/data/Calculation/TextData/SEARCH.php index 75aa7cea7d..28cd98f81e 100644 --- a/tests/data/Calculation/TextData/SEARCH.php +++ b/tests/data/Calculation/TextData/SEARCH.php @@ -54,6 +54,11 @@ 'Mark Baker', 2, ], + [ + 1, + '', + 'Mark Baker', + ], [ '#VALUE!', 'BITE',