Cleanup 3 LookupRef Tests (#3097)
Scrutinizer had previously suggested annotations for 3 LookupRef tests, but it no longer accepts its own annotation for those cases. This PR cleans them up. ColumnsTest and RowsTest are extremely straightforward. IndexTest is a bit more complicated, but only because, unlike the other two, it had no test which executed in the context of a spreadsheet. And, when I added those, I discovered a couple of bugs. INDEX always requires at least 2 parameters (row# is always required), but its entry in the function table specified 1-4 parameters, now changed to 2-4. And, omitting col# is not handled the same way as specifying 0 for col#, though the code had treated them identically. (The same would have been true for row# but, because it is now required, ...)
This commit is contained in:
parent
35b42cc180
commit
d27b6a672a
|
|
@ -1450,7 +1450,7 @@ class Calculation
|
||||||
'INDEX' => [
|
'INDEX' => [
|
||||||
'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
|
'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
|
||||||
'functionCall' => [LookupRef\Matrix::class, 'index'],
|
'functionCall' => [LookupRef\Matrix::class, 'index'],
|
||||||
'argumentCount' => '1-4',
|
'argumentCount' => '2-4',
|
||||||
],
|
],
|
||||||
'INDIRECT' => [
|
'INDIRECT' => [
|
||||||
'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
|
'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
|
||||||
|
|
|
||||||
|
|
@ -76,13 +76,14 @@ class Matrix
|
||||||
* If an array of values is passed as the $rowNum and/or $columnNum arguments, then the returned result
|
* If an array of values is passed as the $rowNum and/or $columnNum arguments, then the returned result
|
||||||
* will also be an array with the same dimensions
|
* will also be an array with the same dimensions
|
||||||
*/
|
*/
|
||||||
public static function index($matrix, $rowNum = 0, $columnNum = 0)
|
public static function index($matrix, $rowNum = 0, $columnNum = null)
|
||||||
{
|
{
|
||||||
if (is_array($rowNum) || is_array($columnNum)) {
|
if (is_array($rowNum) || is_array($columnNum)) {
|
||||||
return self::evaluateArrayArgumentsSubsetFrom([self::class, __FUNCTION__], 1, $matrix, $rowNum, $columnNum);
|
return self::evaluateArrayArgumentsSubsetFrom([self::class, __FUNCTION__], 1, $matrix, $rowNum, $columnNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
$rowNum = $rowNum ?? 0;
|
$rowNum = $rowNum ?? 0;
|
||||||
|
$originalColumnNum = $columnNum;
|
||||||
$columnNum = $columnNum ?? 0;
|
$columnNum = $columnNum ?? 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -102,6 +103,9 @@ class Matrix
|
||||||
if ($columnNum > count($columnKeys)) {
|
if ($columnNum > count($columnKeys)) {
|
||||||
return ExcelError::REF();
|
return ExcelError::REF();
|
||||||
}
|
}
|
||||||
|
if ($originalColumnNum === null && 1 < count($columnKeys)) {
|
||||||
|
return ExcelError::REF();
|
||||||
|
}
|
||||||
|
|
||||||
if ($columnNum === 0) {
|
if ($columnNum === 0) {
|
||||||
return self::extractRowValue($matrix, $rowKeys, $rowNum);
|
return self::extractRowValue($matrix, $rowKeys, $rowNum);
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,11 @@ class ColumnsTest extends TestCase
|
||||||
* @dataProvider providerCOLUMNS
|
* @dataProvider providerCOLUMNS
|
||||||
*
|
*
|
||||||
* @param mixed $expectedResult
|
* @param mixed $expectedResult
|
||||||
|
* @param null|array|string $arg
|
||||||
*/
|
*/
|
||||||
public function testCOLUMNS($expectedResult, ...$args): void
|
public function testCOLUMNS($expectedResult, $arg): void
|
||||||
{
|
{
|
||||||
$result = LookupRef::COLUMNS(/** @scrutinizer ignore-type */ ...$args);
|
$result = LookupRef::COLUMNS($arg);
|
||||||
self::assertEquals($expectedResult, $result);
|
self::assertEquals($expectedResult, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef;
|
||||||
|
|
||||||
|
class IndexOnSpreadsheetTest extends AllSetupTeardown
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider providerINDEXonSpreadsheet
|
||||||
|
*
|
||||||
|
* @param mixed $expectedResult
|
||||||
|
* @param null|int|string $rowNum
|
||||||
|
* @param null|int|string $colNum
|
||||||
|
*/
|
||||||
|
public function testIndexOnSpreadsheet($expectedResult, array $matrix, $rowNum = null, $colNum = null): void
|
||||||
|
{
|
||||||
|
$this->mightHaveException($expectedResult);
|
||||||
|
$sheet = $this->getSheet();
|
||||||
|
$sheet->fromArray($matrix);
|
||||||
|
$maxRow = $sheet->getHighestRow();
|
||||||
|
$maxColumn = $sheet->getHighestColumn();
|
||||||
|
$formulaArray = "A1:$maxColumn$maxRow";
|
||||||
|
if ($rowNum === null) {
|
||||||
|
$formula = "=INDEX($formulaArray)";
|
||||||
|
} elseif ($colNum === null) {
|
||||||
|
$formula = "=INDEX($formulaArray, $rowNum)";
|
||||||
|
} else {
|
||||||
|
$formula = "=INDEX($formulaArray, $rowNum, $colNum)";
|
||||||
|
}
|
||||||
|
$sheet->getCell('ZZ98')->setValue('x');
|
||||||
|
$sheet->getCell('ZZ99')->setValue($formula);
|
||||||
|
$result = $sheet->getCell('ZZ99')->getCalculatedValue();
|
||||||
|
self::assertEquals($expectedResult, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerINDEXonSpreadsheet(): array
|
||||||
|
{
|
||||||
|
return require 'tests/data/Calculation/LookupRef/INDEXonSpreadsheet.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef;
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
|
use PhpOffice\PhpSpreadsheet\Calculation\LookupRef\Matrix;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class IndexTest extends TestCase
|
class IndexTest extends TestCase
|
||||||
|
|
@ -12,10 +12,19 @@ class IndexTest extends TestCase
|
||||||
* @dataProvider providerINDEX
|
* @dataProvider providerINDEX
|
||||||
*
|
*
|
||||||
* @param mixed $expectedResult
|
* @param mixed $expectedResult
|
||||||
|
* @param mixed $matrix
|
||||||
|
* @param mixed $rowNum
|
||||||
|
* @param mixed $colNum
|
||||||
*/
|
*/
|
||||||
public function testINDEX($expectedResult, ...$args): void
|
public function testINDEX($expectedResult, $matrix, $rowNum = null, $colNum = null): void
|
||||||
{
|
{
|
||||||
$result = LookupRef::INDEX(/** @scrutinizer ignore-type */ ...$args);
|
if ($rowNum === null) {
|
||||||
|
$result = Matrix::index($matrix);
|
||||||
|
} elseif ($colNum === null) {
|
||||||
|
$result = Matrix::index($matrix, $rowNum);
|
||||||
|
} else {
|
||||||
|
$result = Matrix::index($matrix, $rowNum, $colNum);
|
||||||
|
}
|
||||||
self::assertEquals($expectedResult, $result);
|
self::assertEquals($expectedResult, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,11 @@ class RowsTest extends TestCase
|
||||||
* @dataProvider providerROWS
|
* @dataProvider providerROWS
|
||||||
*
|
*
|
||||||
* @param mixed $expectedResult
|
* @param mixed $expectedResult
|
||||||
|
* @param null|array|string $arg
|
||||||
*/
|
*/
|
||||||
public function testROWS($expectedResult, ...$args): void
|
public function testROWS($expectedResult, $arg): void
|
||||||
{
|
{
|
||||||
$result = LookupRef::ROWS(/** @scrutinizer ignore-type */ ...$args);
|
$result = LookupRef::ROWS($arg);
|
||||||
self::assertEquals($expectedResult, $result);
|
self::assertEquals($expectedResult, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,234 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'Single Cell' => [
|
||||||
|
1, // Expected
|
||||||
|
[
|
||||||
|
[1],
|
||||||
|
],
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
'Row Number omitted' => [
|
||||||
|
'exception', // Expected
|
||||||
|
[
|
||||||
|
[1],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'Negative Row' => [
|
||||||
|
'#VALUE!', // Expected
|
||||||
|
[
|
||||||
|
[1],
|
||||||
|
[2],
|
||||||
|
],
|
||||||
|
-1,
|
||||||
|
],
|
||||||
|
'Row > matrix rows' => [
|
||||||
|
'#REF!', // Expected
|
||||||
|
[
|
||||||
|
[1],
|
||||||
|
[2],
|
||||||
|
],
|
||||||
|
10,
|
||||||
|
],
|
||||||
|
'Row is not a number' => [
|
||||||
|
'#NAME?', // Expected
|
||||||
|
[
|
||||||
|
[1],
|
||||||
|
[2],
|
||||||
|
],
|
||||||
|
'NaN',
|
||||||
|
],
|
||||||
|
'Row is reference to non-number' => [
|
||||||
|
'#VALUE!', // Expected
|
||||||
|
[
|
||||||
|
[1],
|
||||||
|
[2],
|
||||||
|
],
|
||||||
|
'ZZ98',
|
||||||
|
],
|
||||||
|
'Row is quoted non-numeric result' => [
|
||||||
|
'#VALUE!', // Expected
|
||||||
|
[
|
||||||
|
[1],
|
||||||
|
[2],
|
||||||
|
],
|
||||||
|
'"string"',
|
||||||
|
],
|
||||||
|
'Row is Error' => [
|
||||||
|
'#N/A', // Expected
|
||||||
|
[
|
||||||
|
[1],
|
||||||
|
[2],
|
||||||
|
],
|
||||||
|
'#N/A',
|
||||||
|
],
|
||||||
|
'Return row 2 only one column' => [
|
||||||
|
'xyz', // Expected
|
||||||
|
[
|
||||||
|
['abc'],
|
||||||
|
['xyz'],
|
||||||
|
],
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
'Return row 1 col 2' => [
|
||||||
|
'def', // Expected
|
||||||
|
[
|
||||||
|
['abc', 'def'],
|
||||||
|
['xyz', 'tuv'],
|
||||||
|
],
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
'Column number omitted from 2-column matrix' => [
|
||||||
|
'#REF!', // Expected
|
||||||
|
[
|
||||||
|
['abc', 'def'],
|
||||||
|
['xyz', 'tuv'],
|
||||||
|
],
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
'Column number omitted from 1-column matrix' => [
|
||||||
|
'xyz', // Expected
|
||||||
|
[
|
||||||
|
['abc'],
|
||||||
|
['xyz'],
|
||||||
|
],
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
'Return row 2 from larger matrix (Phpspreadsheet flattens expected [2,4] to single value)' => [
|
||||||
|
2, // Expected
|
||||||
|
// Input
|
||||||
|
[
|
||||||
|
[1, 3],
|
||||||
|
[2, 4],
|
||||||
|
],
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
'Negative Column' => [
|
||||||
|
'#VALUE!', // Expected
|
||||||
|
[
|
||||||
|
[1, 3],
|
||||||
|
[2, 4],
|
||||||
|
],
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
],
|
||||||
|
'Column > matrix columns' => [
|
||||||
|
'#REF!', // Expected
|
||||||
|
[
|
||||||
|
[1, 3],
|
||||||
|
[2, 4],
|
||||||
|
],
|
||||||
|
2,
|
||||||
|
10,
|
||||||
|
],
|
||||||
|
'Column is not a number' => [
|
||||||
|
'#NAME?', // Expected
|
||||||
|
[
|
||||||
|
[1],
|
||||||
|
[2],
|
||||||
|
],
|
||||||
|
1,
|
||||||
|
'NaN',
|
||||||
|
],
|
||||||
|
'Column is reference to non-number' => [
|
||||||
|
'#VALUE!', // Expected
|
||||||
|
[
|
||||||
|
[1],
|
||||||
|
[2],
|
||||||
|
],
|
||||||
|
1,
|
||||||
|
'ZZ98',
|
||||||
|
],
|
||||||
|
'Column is quoted non-number' => [
|
||||||
|
'#VALUE!', // Expected
|
||||||
|
[
|
||||||
|
[1],
|
||||||
|
[2],
|
||||||
|
],
|
||||||
|
1,
|
||||||
|
'"string"',
|
||||||
|
],
|
||||||
|
'Column is Error' => [
|
||||||
|
'#N/A', // Expected
|
||||||
|
[
|
||||||
|
[1],
|
||||||
|
[2],
|
||||||
|
],
|
||||||
|
1,
|
||||||
|
'#N/A',
|
||||||
|
],
|
||||||
|
'Row 2 Column 2' => [
|
||||||
|
4, // Expected
|
||||||
|
[
|
||||||
|
[1, 3],
|
||||||
|
[2, 4],
|
||||||
|
],
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
'Row 2 Column 2 Alphabetic' => [
|
||||||
|
'Pears',
|
||||||
|
[
|
||||||
|
['Apples', 'Lemons'],
|
||||||
|
['Bananas', 'Pears'],
|
||||||
|
],
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
'Row 2 Column 1 Alphabetic' => [
|
||||||
|
'Bananas',
|
||||||
|
[
|
||||||
|
['Apples', 'Lemons'],
|
||||||
|
['Bananas', 'Pears'],
|
||||||
|
],
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
'Row 2 Column 0 (PhpSpreadsheet flattens result)' => [
|
||||||
|
'Bananas',
|
||||||
|
[
|
||||||
|
['Apples', 'Lemons'],
|
||||||
|
['Bananas', 'Pears'],
|
||||||
|
],
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
'Row 5 column 2' => [
|
||||||
|
3,
|
||||||
|
[
|
||||||
|
[4, 6],
|
||||||
|
[5, 3],
|
||||||
|
[6, 9],
|
||||||
|
[7, 5],
|
||||||
|
[8, 3],
|
||||||
|
],
|
||||||
|
5,
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
'Row 5 column 0 (flattened)' => [
|
||||||
|
8,
|
||||||
|
[
|
||||||
|
[4, 6],
|
||||||
|
[5, 3],
|
||||||
|
[6, 9],
|
||||||
|
[7, 5],
|
||||||
|
[8, 3],
|
||||||
|
],
|
||||||
|
5,
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
'Row 0 column 2 (flattened)' => [
|
||||||
|
6,
|
||||||
|
[
|
||||||
|
[4, 6],
|
||||||
|
[5, 3],
|
||||||
|
[6, 9],
|
||||||
|
[7, 5],
|
||||||
|
[8, 3],
|
||||||
|
],
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
];
|
||||||
Loading…
Reference in New Issue