Replace Tests With Unneeded Mocking (#2465)

Replace mock tests with real ones when possible. The original tests are all still present; they just take place in a more representative scenario.

After this, there will be 4 remaining uses of mocking. Of these, 3 are needed for scenarios which are otherwise hard to test - WebServiceTest, CellsTest, and SampleCoverageTest. For the other one, AutoFilterTest, I just can't figure out what it's trying to accomplish, so have left it alone.

This change is almost entirely restricted to tests. There is a one-line change in src. When the first argument passed to OFFSET is null or nullstring, the returned value is currently 0. However, according to the documentation for Excel, it should be `#VALUE!`. The code is changed accordingly.
This commit is contained in:
oleibman 2021-12-31 13:24:43 -08:00 committed by GitHub
parent 07271c83aa
commit 5d1ab39def
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 249 additions and 239 deletions

View File

@ -7930,26 +7930,6 @@ parameters:
count: 1
path: tests/PhpSpreadsheetTests/Calculation/Functions/Financial/XirrTest.php
-
message: "#^Parameter \\#1 \\$cellAddress of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\:\\:COLUMN\\(\\) expects array\\|string\\|null, mixed given\\.$#"
count: 1
path: tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnTest.php
-
message: "#^Parameter \\#1 \\$cellAddress of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\:\\:OFFSET\\(\\) expects string\\|null, mixed given\\.$#"
count: 1
path: tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/OffsetTest.php
-
message: "#^Parameter \\#1 \\$cellAddress of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\:\\:ROW\\(\\) expects array\\|string\\|null, mixed given\\.$#"
count: 1
path: tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowTest.php
-
message: "#^Parameter \\#1 \\$matrixData of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\:\\:TRANSPOSE\\(\\) expects array, mixed given\\.$#"
count: 1
path: tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/TransposeTest.php
-
message: "#^Part \\$number \\(mixed\\) of encapsed string cannot be cast to string\\.$#"
count: 1
@ -8220,11 +8200,6 @@ parameters:
count: 1
path: tests/PhpSpreadsheetTests/Calculation/Functions/TextData/UpperTest.php
-
message: "#^Parameter \\#1 \\$string of function substr expects string, mixed given\\.$#"
count: 1
path: tests/PhpSpreadsheetTests/Calculation/LookupRefTest.php
-
message: "#^Parameter \\#1 \\$currencyCode of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:setCurrencyCode\\(\\) expects string, mixed given\\.$#"
count: 1

View File

@ -48,7 +48,7 @@ class Offset
$width = Functions::flattenSingleValue($width);
if ($cellAddress === null || $cellAddress === '') {
return 0;
return Functions::VALUE();
}
if (!is_object($cell)) {

View File

@ -2,27 +2,19 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PHPUnit\Framework\TestCase;
class ColumnTest extends TestCase
class ColumnTest extends AllSetupTeardown
{
protected function setUp(): void
{
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
}
/**
* @dataProvider providerCOLUMN
*
* @param mixed $expectedResult
* @param null|mixed $cellReference
* @param null|array|string $cellReference
*/
public function testCOLUMN($expectedResult, $cellReference = null): void
{
$result = LookupRef::COLUMN($cellReference);
$result = LookupRef\RowColumnInformation::COLUMN($cellReference);
self::assertSame($expectedResult, $result);
}
@ -33,14 +25,15 @@ class ColumnTest extends TestCase
public function testCOLUMNwithNull(): void
{
$cell = $this->getMockBuilder(Cell::class)
->onlyMethods(['getColumn'])
->disableOriginalConstructor()
->getMock();
$cell->method('getColumn')
->willReturn('D');
$result = LookupRef::COLUMN(null, $cell);
self::assertSame(4, $result);
$sheet = $this->getSheet();
$sheet->getCell('D1')->setValue('=COLUMN()');
self::assertSame(4, $sheet->getCell('D1')->getCalculatedValue());
$sheet->getCell('D2')->setValue('=COLUMN(C13)');
self::assertSame(3, $sheet->getCell('D2')->getCalculatedValue());
// Sheetnames don't have to exist
$sheet->getCell('D3')->setValue('=COLUMN(Sheet17!E15)');
self::assertSame(5, $sheet->getCell('D3')->getCalculatedValue());
$sheet->getCell('D4')->setValue("=COLUMN('Worksheet #5'!X500)");
self::assertSame(24, $sheet->getCell('D4')->getCalculatedValue());
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef;
use PhpOffice\PhpSpreadsheet\Calculation\LookupRef\Formula;
/**
* Class FormulaTextTest.
*/
class FormulaTextTest extends AllSetupTeardown
{
/**
* @param mixed $value
* @dataProvider providerFormulaText
*/
public function testFormulaText(string $expectedResult, $value): void
{
$sheet = $this->getSheet();
$reference = 'A1';
if ($value !== null) {
$sheet->getCell($reference)->setValue($value);
}
$sheet->getCell('D1')->setValue("=FORMULATEXT($reference)");
$result = $sheet->getCell('D1')->getCalculatedValue();
self::assertSame($expectedResult, $result);
}
public function providerFormulaText(): array
{
return require 'tests/data/Calculation/LookupRef/FORMULATEXT.php';
}
public function testNoCell(): void
{
self::assertSame('#REF!', Formula::text('B5'));
}
}

View File

@ -4,40 +4,91 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\Hyperlink;
use PHPUnit\Framework\TestCase;
class HyperlinkTest extends TestCase
class HyperlinkTest extends AllSetupTeardown
{
/** @var bool */
protected $issue2464 = true;
/**
* @dataProvider providerHYPERLINK
*
* @param mixed $expectedResult
* @param null|string $linkUrl
* @param null|string $description
* @param array|string $expectedResult
*/
public function testHYPERLINK($expectedResult, $linkUrl, $description): void
public function testHYPERLINK($expectedResult, ?string $linkUrl, ?string $description): void
{
$hyperlink = new Hyperlink();
$this->mightHaveException($expectedResult);
$sheet = $this->getSheet();
$formula = '=HYPERLINK(';
if ($linkUrl !== null) {
$formula .= '"' . $linkUrl . '"';
if ($description !== null) {
$formula .= ',"' . $description . '"';
}
}
$formula .= ')';
$sheet->getCell('A1')->setValue($formula);
$result = $sheet->getCell('A1')->getCalculatedValue();
$cell = $this->getMockBuilder(Cell::class)
->onlyMethods(['getHyperlink'])
->disableOriginalConstructor()
->getMock();
$cell->method('getHyperlink')
->willReturn($hyperlink);
$result = LookupRef::HYPERLINK($linkUrl, $description, $cell);
if (!is_array($expectedResult)) {
self::assertSame($expectedResult, $result);
} else {
self::assertSame($expectedResult[1], $result);
$hyperlink = $sheet->getCell('A1')->getHyperlink();
self::assertSame($expectedResult[0], $hyperlink->getUrl());
self::assertSame($expectedResult[1], $hyperlink->getTooltip());
}
}
/**
* @dataProvider providerHYPERLINK
*
* @param array|string $expectedResult
*/
public function testHYPERLINKcellRef($expectedResult, ?string $linkUrl, ?string $description): void
{
$this->mightHaveException($expectedResult);
$sheet = $this->getSheet();
$formula = '=HYPERLINK(';
if ($linkUrl !== null) {
$sheet->getCell('A2')->setValue($linkUrl);
$formula .= 'A2';
if ($description !== null) {
$sheet->getCell('A3')->setValue($description);
$formula .= ',A3';
}
}
$formula .= ')';
$sheet->getCell('A1')->setValue($formula);
$result = $sheet->getCell('A1')->getCalculatedValue();
if (!is_array($expectedResult)) {
self::assertSame($expectedResult, $result);
} else {
self::assertSame($expectedResult[1], $result);
if (!$this->issue2464) {
$hyperlink = $sheet->getCell('A1')->getHyperlink();
self::assertSame($expectedResult[0], $hyperlink->getUrl());
self::assertSame($expectedResult[1], $hyperlink->getTooltip());
}
}
}
public function testLen(): void
{
$sheet = $this->getSheet();
$sheet->getCell('A1')->setValue('=LEN(HYPERLINK("http://www.example.com","Example"))');
$value = $sheet->getCell('A1')->getCalculatedValue();
self::assertSame(7, $value);
if ($this->issue2464) {
self::markTestIncomplete('testLen and testHYPERLINKcellRef incomplete due to issue 2464');
} else {
$hyperlink = $sheet->getCell('A1')->getHyperlink();
self::assertSame('', $hyperlink->getUrl());
self::assertSame('', $hyperlink->getTooltip());
}
}
public function providerHYPERLINK(): array
{
return require 'tests/data/Calculation/LookupRef/HYPERLINK.php';
@ -45,7 +96,7 @@ class HyperlinkTest extends TestCase
public function testHYPERLINKwithoutCell(): void
{
$result = LookupRef::HYPERLINK('https://phpspreadsheet.readthedocs.io/en/latest/', 'Read the Docs');
$result = LookupRef\Hyperlink::set('https://phpspreadsheet.readthedocs.io/en/latest/', 'Read the Docs');
self::assertSame(Functions::REF(), $result);
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
use PHPUnit\Framework\TestCase;
/**
* Sanity tests for functions which have been moved out of LookupRef
* to their own classes. A deprecated version remains in LookupRef;
* this class contains cursory tests to ensure that those work properly.
* Only 6 of the 15 functions are covered below at the moment.
*
* @covers \PhpOffice\PhpSpreadsheet\Calculation\LookupRef
*/
class MovedFunctionsTest extends TestCase
{
public function testMovedFunctions(): void
{
self::assertSame(3, LookupRef::COLUMN('C5'));
self::assertSame(Functions::REF(), LookupRef::FORMULATEXT('A1'));
self::assertSame(Functions::REF(), LookupRef::HYPERLINK('https://phpspreadsheet.readthedocs.io/en/latest/', 'Read the Docs'));
self::assertSame('#VALUE!', LookupRef::OFFSET(null));
self::assertSame(5, LookupRef::ROW('C5'));
self::assertSame([[1, 2], [3, 4]], LookupRef::TRANSPOSE([[1, 3], [2, 4]]));
}
}

View File

@ -2,26 +2,19 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
use PHPUnit\Framework\TestCase;
class OffsetTest extends TestCase
class OffsetTest extends AllSetupTeardown
{
protected function setUp(): void
{
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
}
/**
* @dataProvider providerOFFSET
*
* @param mixed $expectedResult
* @param null|mixed $cellReference
* @param null|string $cellReference
*/
public function testOFFSET($expectedResult, $cellReference = null): void
{
$result = LookupRef::OFFSET($cellReference);
$result = LookupRef\Offset::OFFSET($cellReference);
self::assertSame($expectedResult, $result);
}
@ -29,4 +22,28 @@ class OffsetTest extends TestCase
{
return require 'tests/data/Calculation/LookupRef/OFFSET.php';
}
public function testOffsetSpreadsheet(): void
{
$sheet = $this->getSheet();
$sheet->getCell('B6')->setValue(4);
$sheet->getCell('B7')->setValue(8);
$sheet->getCell('B8')->setValue(3);
$sheet->getCell('D6')->setValue(10);
$sheet->getCell('D7')->setValue(3);
$sheet->getCell('D8')->setValue(6);
$sheet->getCell('A1')->setValue('=OFFSET(D3,3,-2,1,1)');
self::assertSame(4, $sheet->getCell('A1')->getCalculatedValue());
$sheet->getCell('A2')->setValue('=SUM(OFFSET(D3:F5,3,-2, 3, 3))');
self::assertSame(34, $sheet->getCell('A2')->getCalculatedValue());
$sheet->getCell('A3')->setValue('=OFFSET(D3, -3, -3)');
self::assertSame('#REF!', $sheet->getCell('A3')->getCalculatedValue());
$sheet->getCell('C1')->setValue(5);
$sheet->getCell('A4')->setValue('=OFFSET(C1, 0, 0, 0, 0)');
self::assertSame('#REF!', $sheet->getCell('A4')->getCalculatedValue());
$sheet->getCell('A5')->setValue('=OFFSET(C1, 0, 0)');
self::assertSame(5, $sheet->getCell('A5')->getCalculatedValue());
}
}

View File

@ -2,27 +2,19 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PHPUnit\Framework\TestCase;
class RowTest extends TestCase
class RowTest extends AllSetupTeardown
{
protected function setUp(): void
{
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
}
/**
* @dataProvider providerROW
*
* @param mixed $expectedResult
* @param null|mixed $cellReference
* @param null|array|string $cellReference
*/
public function testROW($expectedResult, $cellReference = null): void
{
$result = LookupRef::ROW($cellReference);
$result = LookupRef\RowColumnInformation::ROW($cellReference);
self::assertSame($expectedResult, $result);
}
@ -33,14 +25,15 @@ class RowTest extends TestCase
public function testROWwithNull(): void
{
$cell = $this->getMockBuilder(Cell::class)
->onlyMethods(['getRow'])
->disableOriginalConstructor()
->getMock();
$cell->method('getRow')
->willReturn(3);
$result = LookupRef::ROW(null, $cell);
self::assertSame(3, $result);
$sheet = $this->getSheet();
$sheet->getCell('C4')->setValue('=ROW()');
self::assertSame(4, $sheet->getCell('C4')->getCalculatedValue());
$sheet->getCell('D2')->setValue('=ROW(C13)');
self::assertSame(13, $sheet->getCell('D2')->getCalculatedValue());
// Sheetnames don't have to exist
$sheet->getCell('D3')->setValue('=ROW(Sheet17!E15)');
self::assertSame(15, $sheet->getCell('D3')->getCalculatedValue());
$sheet->getCell('D4')->setValue("=ROW('Worksheet #5'!X500)");
self::assertSame(500, $sheet->getCell('D4')->getCalculatedValue());
}
}

View File

@ -21,7 +21,7 @@ class TransposeTest extends TestCase
*/
public function testTRANSPOSE($expectedResult, $matrix): void
{
$result = LookupRef::TRANSPOSE($matrix);
$result = LookupRef\Matrix::transpose($matrix);
self::assertEquals($expectedResult, $result);
}

View File

@ -1,86 +0,0 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Calculation;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use PHPUnit\Framework\TestCase;
/**
* Class LookupRefTest.
*/
class LookupRefTest extends TestCase
{
protected function setUp(): void
{
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
}
/**
* @dataProvider providerFormulaText
*
* @param mixed $expectedResult
* @param mixed $reference Reference to the cell we wish to test
* @param mixed $value Value of the cell we wish to test
*/
public function testFormulaText($expectedResult, $reference, $value = 'undefined'): void
{
$ourCell = null;
if ($value !== 'undefined') {
$remoteCell = $this->getMockBuilder(Cell::class)
->disableOriginalConstructor()
->getMock();
$remoteCell->method('isFormula')
->willReturn(substr($value, 0, 1) == '=');
$remoteCell->method('getValue')
->willReturn($value);
$remoteSheet = $this->getMockBuilder(Worksheet::class)
->disableOriginalConstructor()
->getMock();
$remoteSheet->method('cellExists')
->willReturn(true);
$remoteSheet->method('getCell')
->willReturn($remoteCell);
$workbook = $this->getMockBuilder(Spreadsheet::class)
->disableOriginalConstructor()
->getMock();
$workbook->method('getSheetByName')
->willReturn($remoteSheet);
$sheet = $this->getMockBuilder(Worksheet::class)
->disableOriginalConstructor()
->getMock();
$sheet->method('cellExists')
->willReturn(true);
$sheet->method('getCell')
->willReturn($remoteCell);
$sheet->method('getParent')
->willReturn($workbook);
$ourCell = $this->getMockBuilder(Cell::class)
->disableOriginalConstructor()
->getMock();
$ourCell->method('getWorksheet')
->willReturn($sheet);
}
$result = LookupRef::FORMULATEXT($reference, $ourCell);
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
public function providerFormulaText(): array
{
return require 'tests/data/Calculation/LookupRef/FORMULATEXT.php';
}
public function testFormulaTextWithoutCell(): void
{
$result = LookupRef::FORMULATEXT('A1');
self::assertEquals(Functions::REF(), $result);
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Functional;
use PhpOffice\PhpSpreadsheet\Reader\IReadFilter;
class ReadFilterFilter implements IReadFilter
{
/**
* @param string $column Column address (as a string value like "A", or "IV")
* @param int $row Row number
* @param string $worksheetName Optional worksheet name
*
* @return bool
*
* @see \PhpOffice\PhpSpreadsheet\Reader\IReadFilter::readCell()
*/
public function readCell($column, $row, $worksheetName = '')
{
// define filter range
$rowMin = 2;
$rowMax = 6;
$columnMin = 'B';
$columnMax = 'D';
$r = $row;
if ($r > $rowMax || $r < $rowMin) {
return false;
}
$col = sprintf('%04s', $column);
if (
$col > sprintf('%04s', $columnMax) ||
$col < sprintf('%04s', $columnMin)
) {
return false;
}
return true;
}
}

View File

@ -2,7 +2,6 @@
namespace PhpOffice\PhpSpreadsheetTests\Functional;
use PhpOffice\PhpSpreadsheet\Reader\IReadFilter;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
class ReadFilterTest extends AbstractFunctional
@ -69,12 +68,8 @@ class ReadFilterTest extends AbstractFunctional
$spreadsheet->getActiveSheet()->fromArray($arrayData, null, 'A1');
$reloadedSpreadsheet = $this->writeAndReload($spreadsheet, $format, function ($reader): void {
// Create a stub for the readFilter class.
$readFilterStub = $this->createMock(IReadFilter::class);
$readFilterStub->method('readCell')
->willReturnCallback([$this, 'readFilterReadCell']);
// apply filter
$reader->setReadFilter($readFilterStub);
$reader->setReadFilter(new ReadFilterFilter());
});
$sheet = $reloadedSpreadsheet->getSheet(0);
// test highest column (very specific num of columns because of some 3rd party software)
@ -88,37 +83,4 @@ class ReadFilterTest extends AbstractFunctional
$coordinateTopLeft = reset($sortedCoordinates);
self::assertSame('B2', $coordinateTopLeft);
}
/**
* @param string $column Column address (as a string value like "A", or "IV")
* @param int $row Row number
* @param string $worksheetName Optional worksheet name
*
* @return bool
*
* @see \PhpOffice\PhpSpreadsheet\Reader\IReadFilter::readCell()
*/
public function readFilterReadCell($column, $row, $worksheetName = '')
{
// define filter range
$rowMin = 2;
$rowMax = 6;
$columnMin = 'B';
$columnMax = 'D';
$r = (int) $row;
if ($r > $rowMax || $r < $rowMin) {
return false;
}
$col = sprintf('%04s', $column);
if (
$col > sprintf('%04s', $columnMax) ||
$col < sprintf('%04s', $columnMin)
) {
return false;
}
return true;
}
}

View File

@ -3,47 +3,42 @@
return [
[
'#N/A',
'A1',
'2',
2,
],
[
'="ABC"',
'A2',
'="ABC"',
],
[
'=A1',
'A3',
'=A1',
],
[
'=\'Worksheet1\'!A1',
'A4',
'=\'Worksheet1\'!A1',
],
[
'=\'Works heet1\'!A1',
'A4',
'=\'Works heet1\'!A1',
],
[
'="HELLO WORLD"',
'\'Worksheet1\'!A5',
'="HELLO WORLD"',
],
[
'="HELLO WORLD"',
'\'Work sheet1\'!A5',
'="HELLO WORLD"',
],
[
'="HELLO WORLD"',
'\'Work!sheet1\'!A5',
'="HELLO WORLD"',
'=\'Work!sheet1\'!A5',
'=\'Work!sheet1\'!A5',
],
[
'#N/A',
'\'Worksheet1\'!A6',
'123',
'A1',
],
[
'#N/A',
null,
],
[
'=SUM(B1,B2,B3)',
'=SUM(B1,B2,B3)',
],
];

View File

@ -14,7 +14,7 @@ return [
'Read the Docs',
],
[
Functions::REF(),
'exception',
null,
null,
],

View File

@ -2,7 +2,11 @@
return [
[
0,
'#VALUE!',
null,
],
[
'#REF!',
'B5',
],
];