Files
oleibman 40911aa104 Update Phpstan and Tcpdf
Many problems with Dependabot this month. Phpstan introduced a lot of new "errors". These are now fixed or annotated. I combined this with a change to require comments for `phpstan-ignore`. These won't always be useful, but I think requiring them makes sense.

Tcpdf is more of a non-update. Our composer.json specified `^6.5`. For some reason, Dependabot decided it was okay to change that to `^6.5||^7.0`, which seems presumptuous. (One of the triggers was probably the elimination of Php8.1, since the new product requires 8.2+.) Tcpdf is nominally deprecated, replaced by tc-lib-pdf. Tcpdf 7 passes control to the new product. However, the upgrade is not straightforward. The user needs to supply font files which were formerly distributed with the product, and a code change to define a (shudder) global constant is required. Consequently, Dependabot's upgrade failed its unit tests. While I may evaluate what might be needed at some point in the future, for now I am just updating composer.json to reject Tcpdf 7+.
2026-08-01 22:06:38 -07:00

357 lines
12 KiB
PHP

<?php
declare(strict_types=1);
namespace PhpOffice\PhpSpreadsheetTests\Cell;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Exception;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use TypeError;
class CoordinateTest extends TestCase
{
#[DataProvider('providerColumnString')]
public function testColumnIndexFromString(mixed $expectedResult, string $string): void
{
$columnIndex = Coordinate::columnIndexFromString($string);
self::assertEquals($expectedResult, $columnIndex);
$stringBack = Coordinate::stringFromColumnIndex($columnIndex);
self::assertEquals($stringBack, $string, 'should be able to get the original input with opposite method');
}
public static function providerColumnString(): array
{
return require 'tests/data/ColumnString.php';
}
public function testColumnIndexFromStringTooLong(): void
{
$this->expectException(Exception::class);
$this->expectExceptionMessage('Column string index can not be beyond XFD');
Coordinate::columnIndexFromString('ABCD');
}
public function testColumnIndexFromStringTooShort(): void
{
$this->expectException(Exception::class);
$this->expectExceptionMessage('Column string index can not be empty');
Coordinate::columnIndexFromString('');
}
#[DataProvider('providerColumnIndex')]
public function testStringFromColumnIndex(mixed $expectedResult, int $columnIndex): void
{
if ($expectedResult === 'exception') {
$this->expectException(Exception::class);
$this->expectExceptionMessage('Invalid column index');
}
$string = Coordinate::stringFromColumnIndex($columnIndex);
self::assertEquals($expectedResult, $string);
$columnIndexBack = Coordinate::columnIndexFromString($string);
self::assertEquals($columnIndexBack, $columnIndex, 'should be able to get the original input with opposite method');
}
public static function providerColumnIndex(): array
{
return require 'tests/data/ColumnIndex.php';
}
#[DataProvider('providerCoordinates')]
public function testCoordinateFromString(mixed $expectedResult, string $rangeSet): void
{
$result = Coordinate::coordinateFromString($rangeSet);
self::assertEquals($expectedResult, $result);
}
public static function providerCoordinates(): array
{
return require 'tests/data/CellCoordinates.php';
}
/** @param mixed[] $expectedResult */
#[DataProvider('providerIndexesFromString')]
public function testIndexesFromString(array $expectedResult, string $rangeSet): void
{
$result = Coordinate::indexesFromString($rangeSet);
self::assertSame($expectedResult, $result);
}
public static function providerIndexesFromString(): array
{
return require 'tests/data/Cell/IndexesFromString.php';
}
public function testCoordinateFromStringWithRangeAddress(): void
{
$cellAddress = 'A1:AI2012';
try {
Coordinate::coordinateFromString($cellAddress);
} catch (\Exception $e) {
self::assertInstanceOf(Exception::class, $e);
self::assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells');
return;
}
self::fail('An expected exception has not been raised.');
}
public function testCoordinateFromStringWithEmptyAddress(): void
{
$cellAddress = '';
try {
Coordinate::coordinateFromString($cellAddress);
} catch (\Exception $e) {
self::assertInstanceOf(Exception::class, $e);
self::assertEquals($e->getMessage(), 'Cell coordinate can not be zero-length string');
return;
}
self::fail('An expected exception has not been raised.');
}
public function testCoordinateFromStringWithInvalidAddress(): void
{
$cellAddress = 'AI';
try {
Coordinate::coordinateFromString($cellAddress);
} catch (\Exception $e) {
self::assertInstanceOf(Exception::class, $e);
self::assertEquals($e->getMessage(), 'Invalid cell coordinate ' . $cellAddress);
return;
}
self::fail('An expected exception has not been raised.');
}
#[DataProvider('providerAbsoluteCoordinates')]
public function testAbsoluteCoordinateFromString(string $expectedResult, string $rangeSet): void
{
$result = Coordinate::absoluteCoordinate($rangeSet);
self::assertEquals($expectedResult, $result);
}
public static function providerAbsoluteCoordinates(): array
{
return require 'tests/data/CellAbsoluteCoordinate.php';
}
public function testAbsoluteCoordinateFromStringWithRangeAddress(): void
{
$cellAddress = 'A1:AI2012';
try {
Coordinate::absoluteCoordinate($cellAddress);
} catch (\Exception $e) {
self::assertInstanceOf(Exception::class, $e);
self::assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells');
return;
}
self::fail('An expected exception has not been raised.');
}
#[DataProvider('providerAbsoluteReferences')]
public function testAbsoluteReferenceFromString(mixed $expectedResult, int|string $rangeSet): void
{
$result = Coordinate::absoluteReference((string) $rangeSet);
self::assertEquals($expectedResult, $result);
}
public static function providerAbsoluteReferences(): array
{
return require 'tests/data/CellAbsoluteReference.php';
}
public function testAbsoluteReferenceFromStringWithRangeAddress(): void
{
$cellAddress = 'A1:AI2012';
try {
Coordinate::absoluteReference($cellAddress);
} catch (\Exception $e) {
self::assertInstanceOf(Exception::class, $e);
self::assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells');
return;
}
self::fail('An expected exception has not been raised.');
}
/** @param mixed[] $expectedResult */
#[DataProvider('providerSplitRange')]
public function testSplitRange(array $expectedResult, string $rangeSet): void
{
$result = Coordinate::splitRange($rangeSet);
foreach ($result as $key => $split) {
if (!is_array($expectedResult[$key])) {
self::assertEquals($expectedResult[$key], $split[0]);
} else {
self::assertEquals($expectedResult[$key], $split);
}
}
}
public static function providerSplitRange(): array
{
return require 'tests/data/CellSplitRange.php';
}
/** @param array<array<string>> $rangeSets */
#[DataProvider('providerBuildRange')]
public function testBuildRange(mixed $expectedResult, array $rangeSets): void
{
$result = Coordinate::buildRange($rangeSets);
self::assertEquals($expectedResult, $result);
}
public static function providerBuildRange(): array
{
return require 'tests/data/CellBuildRange.php';
}
public function testBuildRangeInvalid(): void
{
$this->expectException(TypeError::class);
$cellRange = null;
Coordinate::buildRange($cellRange); // @phpstan-ignore argument.type (deliberate testing runtime)
}
public function testBuildRangeInvalid2(): void
{
$this->expectException(Exception::class);
$this->expectExceptionMessage('Range does not contain any information');
$cellRange = [];
Coordinate::buildRange($cellRange);
}
#[DataProvider('providerRangeBoundaries')]
public function testRangeBoundaries(mixed $expectedResult, string $rangeSet): void
{
$result = Coordinate::rangeBoundaries($rangeSet);
self::assertEquals($expectedResult, $result);
}
public static function providerRangeBoundaries(): array
{
return require 'tests/data/CellRangeBoundaries.php';
}
#[DataProvider('providerRangeDimension')]
public function testRangeDimension(mixed $expectedResult, string $rangeSet): void
{
$result = Coordinate::rangeDimension($rangeSet);
self::assertEquals($expectedResult, $result);
}
public static function providerRangeDimension(): array
{
return require 'tests/data/CellRangeDimension.php';
}
#[DataProvider('providerGetRangeBoundaries')]
public function testGetRangeBoundaries(mixed $expectedResult, string $rangeSet): void
{
$result = Coordinate::getRangeBoundaries($rangeSet);
self::assertEquals($expectedResult, $result);
}
public static function providerGetRangeBoundaries(): array
{
return require 'tests/data/CellGetRangeBoundaries.php';
}
#[DataProvider('providerCoordinateIsInsideRange')]
public static function testCoordinateIsInsideRange(bool $expectedResult, string $range, string $coordinate): void
{
$result = Coordinate::coordinateIsInsideRange($range, $coordinate);
self::assertEquals($result, $expectedResult);
}
public static function providerCoordinateIsInsideRange(): array
{
return require 'tests/data/Cell/CoordinateIsInsideRange.php';
}
#[DataProvider('providerCoordinateIsInsideRangeException')]
public static function testCoordinateIsInsideRangeException(string $expectedResult, string $range, string $coordinate): void
{
try {
Coordinate::coordinateIsInsideRange($range, $coordinate);
} catch (\Exception $e) {
self::assertInstanceOf(Exception::class, $e);
self::assertEquals($e->getMessage(), $expectedResult);
return;
}
self::fail('An expected exception has not been raised.');
}
public static function providerCoordinateIsInsideRangeException(): array
{
return require 'tests/data/Cell/CoordinateIsInsideRangeException.php';
}
/** @param mixed[] $expectedResult */
#[DataProvider('providerExtractAllCellReferencesInRange')]
public function testExtractAllCellReferencesInRange(array $expectedResult, string $rangeSet): void
{
$result = Coordinate::extractAllCellReferencesInRange($rangeSet);
self::assertEquals($expectedResult, $result);
}
public static function providerExtractAllCellReferencesInRange(): array
{
return require 'tests/data/CellExtractAllCellReferencesInRange.php';
}
#[DataProvider('providerInvalidRange')]
public function testExtractAllCellReferencesInRangeInvalidRange(string $range): void
{
$this->expectException(Exception::class);
$this->expectExceptionMessage('Invalid range: "' . $range . '"');
Coordinate::extractAllCellReferencesInRange($range);
}
public static function providerInvalidRange(): array
{
return [['Z1:A1'], ['A4:A1'], ['B1:A1'], ['AA1:Z1']];
}
/** @param array<string, mixed> $rangeSets */
#[DataProvider('providerMergeRangesInCollection')]
public function testMergeRangesInCollection(mixed $expectedResult, array $rangeSets): void
{
$result = Coordinate::mergeRangesInCollection($rangeSets);
self::assertEquals($expectedResult, $result);
}
public static function providerMergeRangesInCollection(): array
{
return require 'tests/data/CellMergeRangesInCollection.php';
}
#[DataProvider('providerCoordinateIsRange')]
public function testCoordinateIsRange(mixed $expectedResult, string $rangeSet): void
{
$result = Coordinate::coordinateIsRange($rangeSet);
self::assertEquals($expectedResult, $result);
}
public static function providerCoordinateIsRange(): array
{
return require 'tests/data/CoordinateIsRange.php';
}
}