Commit Graph

448 Commits

Author SHA1 Message Date
oleibman 1e8ff9f852
DateTimeExcel - Change Names of funcWhatever to evaluate (#2015)
* DateTimeExcel - Change Names of funcWhatever to evaluate

Per discussions while MathTrig was being broken up, this would help standardize the code. This PR applies that standardization to the DateTimeExcel family of functions.

The deprecation messages in DateTime.php are changed to match the style used in PR #2005.

All Phpstan grandfathered errors (about 25) in DateTimeExcel are fixed and removed from baseline. A small number (about 5) of phpstan annotations in the source members in that directory are also fixed and eliminated.
2021-04-24 18:56:58 +02:00
oleibman a01a401228
MathTrig - Fix Phpstan Accomodations (#2020)
* MathTrig - Fix Phpstan Accomodations

This should be the last of my mass changes to MathTrig. All he Phpstan violations found in baseline which  are part of MathTrig are now fixed and removed from baseline. There were about 20 of these.
2021-04-24 18:12:17 +02:00
oleibman b05dc31850
MathTrig - Change Names of funcWhatever to evaluate (#2008)
* MathTrig - Change Names of funcWhatever to evaluate

Per discussions while MathTrig was being broken up, this would help standardize the code. That idea was adopted partway through the breakup. This PR applies that standardization to the earlier efforts. A similar effort is required for DateTime; that will come later. This PR replaces #2006.

The only 2 remaining funcWhatevers in MathTrig are both in SUM, which required two different methods depending on whether or not string parameters were to be ignored. It seems appropriate to leave those method names non-standardized in order to require a decision about which is to be used if they are invoked internally.

3 Phpstan grandfathered errors were eliminated as part of this change, and its baseline has changed accordingly.

Co-authored-by: Mark Baker <mark@lange.demon.co.uk>
2021-04-20 22:43:29 +02:00
oleibman c79a9a8e21
Improved Support for INDIRECT, ROW, and COLUMN Functions (#2004)
* Improved Support for INDIRECT, ROW, and COLUMN Functions

This should address issues #1913 and #1993. INDIRECT had heretofore not supported an optional parameter intended to support addresses in R1C1 format which was introduced with Excel 2010. It also had not supported the use of defined names as an argument. This PR is a replacement for #1995, which is currently in draft status and which I will close in a day or two.

The ROW and COLUMN functions also should support defined names. I have added that, and test cases, with the latest push. ROWS and COLUMNS already supported it correctly, but there had been no test cases. Because ROW and COLUMN can return arrays, and PhpSpreadsheet does not support dynamic arrays, I left the existing direct-call tests unchanged to demonstrate those capabilities.

The unit tests for INDIRECT had used mocking, and were sorely lacking (tested only error conditions). They have been replaced with normal, and hopefully adequate, tests. This includes testing globally defined names, as well as locally defined names, both in and out of scope.

The test case in 1913 was too complicated for me to add as a unit test. The main impediments to it are now removed, and its complex situation will, I hope, be corrected with this fix.

INDIRECT can also support a reference of the form Sheetname!localName when localName on its own would be out of scope. That functionality is added. It is also added, in theory, for ROW and COLUMN, however such a construction is rejected by the Calculation engine before passing control to ROW or COLUMN. It might be possible to change the engine to allow this, and I may want to look into that later, but it seems much too risky, and not nearly useful enough, to attempt to address that as part of this change.

Several unusual test cases (leading equals sign, not-quite-as-expected name definition in file, complex indirection involving concatenation and a dropdown list) were suggested by @MarkBaker and are included in this request.
2021-04-20 22:16:21 +02:00
oleibman aeccdb35e2
XLSX Reader and Empty Fill Tag (#2011)
Openpyxl can generate the xml tag `<patternFill/>`, possibly even as a default style. Excel has no problem with this, treating it as "fill none", but PhpSpreadsheet has a glitch because it treats it as "fill solid white". So, when PhpSpreadsheet loads and saves such a file, the result at first appears as if gridlines are disabled; in fact, the gridlines are merely invisible behind the cells with their solid white fill. This PR makes PhpSpreadsheet behave the same as Excel in this circumstance.

Co-authored-by: Mark Baker <mark@lange.demon.co.uk>
2021-04-20 17:20:59 +02:00
Mark Baker 6282035c96
Extract Property and Style readers from the XML Reader into separate classes (#2009)
* Extract Property and Style readers from the XML Reader into separate classes
2021-04-20 15:27:44 +02:00
Tiago Fernandes 11f8a02194
Merge branch 'master' into issue-907-absolute-path-in-Target 2021-04-19 14:32:20 +01:00
Tiago Fernandes 559c0761df Remove unnecessary changes. Added test 2021-04-19 11:25:48 +01:00
Mark Baker f49a951bea
Tag deprecations for MathTrig, and eliminate calls to the deprecated methods (#2005)
* Tag deprecations for MathTrig, and eliminate calls to the deprecated methods
2021-04-18 12:19:53 +02:00
Adrien Crivelli d85eaacfa3
BREAKING `Worksheet::getCell()` cannot return null anymore
`Worksheet::getCell()` used to optionnaly return null if passed a
second argument. This second argument was removed entirely and the
method always returns a Cell (possibly creating it if needed).

This make the API more predictable and easier to do static analysis
with tools such as PHPStan.

If you relied on that second parameter, you should instead use the
`Worksheet::cellExists()` before calling `getCell()`.
2021-04-13 11:09:29 +09:00
Adrien Crivelli 49f87de165
Reduce PHPStan error in tests 2021-04-12 11:10:23 +09:00
Adrien Crivelli f9532231d2
PHPStan Level 3 2021-04-11 16:33:53 +09:00
Akira Taniguchi da28089c3c
Merge branch 'master' into master 2021-04-06 23:56:37 +09:00
Mark Baker bc18fb7e77
more extraction of Excel Financial functions (#1989)
* More Financial function extracts, this time looking at the Periodic Cashflow functions
* Initial extract of Constant Periodic Interest and Payment functions
2021-04-06 12:45:37 +02:00
Akira Taniguchi 551bbdf30f
Update CsvOutputEncodingTest.php 2021-04-06 18:53:21 +09:00
Vivek 93d858a064
Merge branch 'master' into fix_excel_overwrite 2021-04-06 08:19:44 +05:30
Akira Taniguchi e48ffdbe77
Update CsvOutputEncodingTest.php 2021-04-06 04:44:24 +09:00
Akira Taniguchi 991616d1d9
Update CsvOutputEncodingTest.php 2021-04-06 04:39:26 +09:00
Akira Taniguchi 86f3bdd598
Update CsvOutputEncodingTest.php 2021-04-06 04:27:14 +09:00
Akira Taniguchi bfd4a659a4
Update CsvOutputEncodingTest.php 2021-04-06 04:11:46 +09:00
Akira Taniguchi 2adc44262c
Update CsvOutputEncodingTest.php 2021-04-06 03:48:08 +09:00
Akira Taniguchi 7681a1093f
Update CsvOutputEncodingTest.php 2021-04-06 03:46:10 +09:00
Akira Taniguchi 2df8e1a93f
Update CsvOutputEncodingTest.php 2021-04-06 03:07:10 +09:00
Akira Taniguchi f6bfbd0655
Create CsvOutputEncodingTest.php 2021-04-06 02:56:54 +09:00
Akira Taniguchi 2a16ce1432
Delete CsvOutputEncoding.php 2021-04-06 02:47:46 +09:00
Akira Taniguchi eef90b62df
Create CsvOutputEncoding.php 2021-04-06 02:05:08 +09:00
Vivek Kumar dd9cb259d0 Unlink temporary file 2021-04-05 22:14:50 +05:30
oleibman 95b8c4d59b
Continue MathTrig Breakup - Completion! (#1985)
* Continue MathTrig Breakup - Completion!

Continuing the process of breaking MathTrip.php up into smaller classes. This round takes care of everything that was left:
- ABS
- DEGREES
- EXP
- RADIANS
- SQRT
- SQRTPI
- SUMSQ, SUMX2MY2, SUMX2PY2, SUMXMY2

The only notable logic change was that the 3 SUMX* functions had accepted arrays of unlike length; in that condition, they now return N/A, as Excel does. There had been no tests for this condition.

All the functions in MathTrig.php are now deprecated. Except for COMBIN, the test suite executes them only from MathTrig MovedFunctionsTest. COMBIN is still directly called by some Statistics Binomial functions which have not yet had the opportunity to be re-coded for the new location.


Co-authored-by: Mark Baker <mark@lange.demon.co.uk>
2021-04-05 16:39:03 +02:00
Vivek Kumar 5e96f4292b Merge remote-tracking branch 'master' into fix_excel_overwrite 2021-04-05 12:42:43 +05:30
Vivek Kumar 59de56bb62 Move original file to temporary file 2021-04-05 12:26:44 +05:30
Adrien Crivelli d02352845c
PHPStan Level 2 2021-04-04 22:06:00 +09:00
Mark Baker dd74dd7fcf
Let's start with some appeasements to phpstan, just to reduce the baseline (#1983)
* Let's start with some appeasements to phpstan, just to reduce the baseline
* Appeasements to phpstan, taking the number of reported errors down to just 61
2021-04-03 17:10:40 +02:00
Adrien Crivelli a189d933f2
Introduce PHPStan
To improve the feedback loop on code quality with a process
that can be run locally by the developers, instead of only
on Scrutinizer.
2021-04-03 16:13:21 +09:00
Mark Baker a2bb825bc5
Extract Normal and Standard Normal Distributions from the Statistical Class (#1981)
* Extract Normal and Standard Normal Distributions from the Statistical Class
* Extract ZTest from the Statistical Class, and move it to the Standard Normal Distribution class
Additional unit tests for NORMINV()
* Extract LogNormal distribution functions from Statistical
2021-04-02 20:17:03 +02:00
oleibman a4982fd9fe
Continue MathTrig Breakup - Penultimate? (#1973)
* Continue MathTrig Breakup - Penultimate?

Continuing the process of breaking MathTrip.php up into smaller classes. This round takes care of about half of what is left, so perhaps one round after this one will finish the job:
- ARABIC
- COMBIN; also implemented COMBINA
- FACTDOUBLE
- GCD (which accepts and ignores empty cells as arguments, but returns VALUE if all the arguments are that way; LCM does the same)
- LOG_BASE, LOG10, LN
- implemented MUNIT
- MOD
- POWER
- RAND, RANDBETWEEN (RANDARRAY is too complicated to implement with this ticket)

As you can see from the description, there are some functions which were combined in a single class. When not combined, I adopted PowerKiki's suggestion of using "execute" as the function name.

Co-authored-by: Mark Baker <mark@lange.demon.co.uk>
2021-04-02 14:35:34 +02:00
Mark Baker 17af13281b
Extract a few more Distribution functions from Statistical (#1975)
* Extract a few more Distribution functions from Statistical; this time EXPONDIST() and HYPGEOMDIST()

* Extract the F Distribution (although only F.DIST() is implemented so far

* Updae docblocks

* PHPCS
2021-03-31 21:45:06 +02:00
Mark Baker 029f345987
Extract Binomial Distribution functions from Statistical (#1974)
* Extract Binomial Distribution functions from Statistical
Replace the old MS algorithm for CRITBINOM() (which has now been replaced with te BINOM.INV() function) with a brute force approach - I'll look to refine it later. The MS algorithm is no longer documented, and the implementation produced erroneous results anyway

* Exract the NEGBINOMDIST() function as well; still need to add a cumulative flag to support the additional argument for the newer NEGBINOM.DIST() function
* Rationalise validation of probability arguments
2021-03-30 22:49:10 +02:00
Mark Baker e68978f1c7
Chi squared inverse left tailed (#1964)
* Implementation of the CHISQ.INV() method for ChiSquared distribution left-tail
2021-03-28 19:12:45 +02:00
Mark Baker e2ff14fe89
Implemented the CHISQ.DIST() Statistical function. (#1961)
* Implementation of the CHISQ.DIST() statistical function for left tail distribution
2021-03-28 16:13:00 +02:00
Mark Baker 67fec4e3fc
Implementation of the CHITEST() statistical function (#1960)
* Implementation of the CHITEST() statistical function

* A couple of additional edge case tests (rows = 1, columns = 1)
2021-03-27 22:04:05 +01:00
Mark Baker a34dd71cce
Difference in variance calculations between Excel/Gnumeric and Open/LibreOffice (#1959)
* Difference in variance calculations between Excel/Gnumeric and Open/LibreOffice
* Simplify STDEV() function logic by remembering that STDEV() is simply the square root of VAR(), so we can simply use the VAR() calculaion rather than duplicating the basic logic... and also allow for the differences between Excel/Gnumeric and Open/LibreOffice
2021-03-27 18:31:24 +01:00
Mark Baker ec2531411d
Start implementing Newton-Raphson for the inverse of Statistical Distributions (#1958)
* Start implementing Newton-Raphson for the inverse of Statistical Distributions, starting with the two-tailed Student-T
* Additional unit tests and validations
* Use the new Newton Raphson class for calculating the Inverse of ChiSquared
* Extract Weibull distribution, and provide unit tests
2021-03-27 13:29:58 +01:00
Mark Baker c699d144e2
Extract ACCRINT() and ACCRINTM() Financial functions into their own class (#1956)
* Extract ACCRINT() and ACCRINTM() Financial functions into their own class
Implement additional validations, with additional unit tests
Add support for the new calculation method argument for ACCRINT()
* Additional tests for Amortization functions
2021-03-26 22:49:16 +01:00
oleibman 9239b3deca
Continue MathTrig Breakup - Problem Children (#1954)
Continuing the process of breaking MathTrip.php up into smaller classes. This round takes care of all functions which might be an impediment to installing due to either uncovered code or "complexity":
- BASE
- FACT
- LCM
- MDETERM, MINVERSE, MMULT
- MULTINOMIAL
- PRODUCT
- QUOTIENT
- SERIESSUM
- SUM
- SUMPRODUCT

MathTrig and the members in directory MathTrig are now 100% covered. Many tests have been added, and some edge-case bugs are corrected. Some cases where PhpSpreadsheet had rejected numeric values stored as strings have been changed to accept them whenever Excel does; there had been no tests for that condition.

Boolean arguments are now accepted as arguments wherever Excel accpets them. Taking a cue from what has been done in Engineering, the parameter validation now happens in a routine which issues Exceptions for invalid values; this simplifies the code in the functions themselves. Thank you for doing that; I did not foresee how useful that was when I first looked at it.

Consistent with earlier changes of this nature, the versions in the MathTrig class remain, with a doc block indicating deprecation, and a stub call to the new routines.

All tests except for MINVERSE and MMULT are now handled in the context of a spreadsheet rather than a direct call to the calculation function which implements it. PhpSpreadsheet would need to handle dynamic arrays in order to test MINVERSE and MMULT in a spreadsheet context. Implementing that looks like it might be *very* challenging. It is not something I plan to look at, at least not in the near future.

One parsing problem turned up in the test conversion. It is in one of the SUMIF tests. It takes me to an area in Calculation where the comment says "I don't even want to know what you did to get here". It did not show up in the previous incarnation because, by using a direct call, the previous test managed to bypass the parsing. I have confirmed that this problem shows up in earlier releases of PhpSpreadsheet, so the changes in this PR did not cause it - they merely exposed it. I have left the test intact, but marked it "incomplete" for documentation purposes. I have not been able to get a handle on what's going wrong yet. I will probably open an issue on it if I can't resolve it soon. However, the test in question isn't a "real world" issue, and the error wasn't caused by this change, so I see no reason to delay this pending a resolution of the problem.

SUM had an idiosyncratic moment of its own. It had been ignoring non-numeric values, but Excel returns VALUE in that situation. So I changed it and wrote some new tests, which worked, but ... SUMIF uses several levels of indirection to get to SUM, and SUMIF *does* ignore non-numeric values, so a SUMIF test broke. SUM is a really simple function; the most practical approach seemed to be to clone it, with the string-accepting version being used by the Legacy version (which is called by SUMIF), and the non-string-accepting version being used in the Calculation Function table. That seems far easier and more practical than, for instance, adding a boolean parameter to the variable parameter list. As a follow-up, I will change SUMIF to explicitly call the appropriate new version, but I did not want to add that to this already large change.

SUM again - although it was fully covered beforehand, there was not a specific test member for it. There is now.

FACT had been coded to fail Gnumeric requests where the numeric argument has a decimal portion. However, Gnumeric does accept such an argument, and, unlike Excel and ODS, does not truncate it, but returns the result of a Gamma function call instead. This has been corrected.

When LCM included arguments which contained both 0 and a negative number, it returned 0 or NUM, whichever it found first. It is changed to always return NUM in that circumstance, as Excel does.

QUOTIENT had been documented as taking a variadic list of arguments. In fact, it takes exactly 2 - numerator and denominator - and the docblock and signature is fixed, even in the deprecated version.

The SERIESSUM docbock and signature are more accurate, even in the deprecated version. It is changed to ignore nulls, as Excel does, rather than return VALUE, and is one of the routines which previously rejected numbers in string form.

SUBTOTAL tests had used mocking for some reason. These are replaced with normal tests. And SUBTOTAL had a big surprise in store. That part of it which deals with hidden cells cares only whether the row is hidden, and doesn't care about the column's visibility.

I struggled with whether it should be SubTotal or Subtotal. I think the latter is correct, so that's how I proceeded. I don't think there are likely to be any other capitalization controversies.
2021-03-26 17:35:30 +09:00
Mark Baker 07ad800755
New Bessel Algorithm, providing a higher degree of accuracy and precision (#1946)
* New Bessel Algorithm, providing a higher degree of precision (12 decimal places) and still matching/exceeding MS Excel's precision across the range of values
2021-03-24 13:29:54 +01:00
Mark Baker 1a7b9a446a
First phase of refactoring the Excel Text functions (#1945)
* Refactoring the Excel Text functions
* More unit tests for utf-8 handling, for edge cases, and for argument validations
2021-03-23 13:34:28 +01:00
oleibman 9beacd21be
Complete Breakup Of Calculation/DateTime Functions (#1937)
* Complete Breakup Of Calculation/DateTime Functions

In conjunction with parallel breakups happening in other areas of Calculation, this change breaks up all the DateTime functions into their own classes. All methods remaining in DateTime itself have a doc block deprecation notice, and consist only of stub code to call the replacement methods. Coverage of DateTime itself and all the replacement methods is 100%.

There is only one substantive change to the code (see next paragraph). Among the non-substantive changes, it now adopts the same parsing technique (throwing and catching exceptions) already in use in Engineering and MathTrig. Boolean parameters are allowed in lieu of numbers when Excel allows them. Most of the code changes involve refactoring due to the need to avoid Scrutinizer "complexity" failures in what it will consider to be new methods.

Issue #1936 was opened just as I was staging this. It is now fixed. One existing WORKDAY test was wrong (noted in a comment in the test data file), and a bunch of new tests are added.

I found it confusing to use DateTime as a node of the the class name since most of the methods invoke native DateTime methods. So, everything is moved to directory DateTimeExcel, and that is what is used in the class names.

There are several follow-up activities that I am planning to undertake if this PR is merged.

- ODS supports dates well before 1900. There are exactly 2 assertions for this functionality. More are needed (and some functions might have to change to accept this).
- WEEKDAY has some poorly documented extra options for "style" which are not yet implemented.
- Most tests have been changed to use a formula as entered on a spreadsheet rather than a direct call to the method which implements the formula. There are 3 exceptions at this time. WORKDAY and NETWORKDAYS, which include arrays as part of their parameters, are more complicated than most. YEARFRAC was just too large to deal with now.
- There are direct calls to the now-deprecated methods in both source code and tests, mostly in Financial code, but possibly in others as well. These need to be changed.
- Some constants, none "officially" documented, remain in the original class. These should be either deleted or marked deprecated. I wasn't sure if deprecation was even possible (or desirable), and did not want that to be something which would cause Scrutinizer to fail the change.

* Deprecate Now-unused Constants, Fix Yearfrac bug, Change 3 Tests

Add new DateTime/Constants class, initially populated with constants used in Weeknum.

MS has another inconsistency with how it handles null cells in Yearfrac. Change PhpSpreadsheet to behave compatibly with this bug.

I have modified YearFrac, WorkDay, and NetworkDays tests to be more to my liking. Many tests added to YearFrac because of the bug above. Only minor modifications to the existing tests for the others.
2021-03-21 09:12:05 +01:00
Mark Baker d346318c2b
Start work on breaking down some of the Financial Excel functions (#1941)
* Start work on breaking down some of the Financial Excel functions
* Unhappy path unit tests for Treasury Bill functions
* Codebase for Treasury Bills includes logic for a different days between settlement and maturity calculation for OpenOffice; but Open/Libre Office now uses the Excel days calculation, so this discrepancy between packages is no longer required
* We've already converted the Settlement and Maturity dates to Excel timestamps, so there's no need to try doing it again when calculating the days between Settlement and Maturity
* Add Unit Tests for the Days per Year helper function
* Extract Interest Rate functions - EFFECT() and NOMINAL() - with additional validation, and unhappy path unit tests
* First pass at extracting the Coupon Excel functions
* Simplify the validation methods
* Extended unit tests to cover all combinations of frequency and basis, including leap years
Fix for COUPDAYSNC() when basis is US 360 and settlement date is the last day of the month
* Ensure that all Financial function code uses the new Helpers class for Days Per Year
2021-03-20 18:40:53 +01:00
Mark Baker 4cd6c7806e
Initial unit tests for Document Properties (#1932)
* Initial unit tests for Document Properties
* Typehinting in the document properties class
2021-03-17 18:36:13 +01:00
Mark Baker 09022256f4
Resolve Deprecated setMethods() call when Mocking for tests (#1925)
Resolve Deprecated `setMethods()` calls when Mocking for tests, using `onlyMethods()` and `addMethods()` instead
2021-03-15 14:50:05 +01:00