Skip to content

Commit

Permalink
Test coverage upgraded
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexandre-T committed Aug 5, 2024
1 parent 8b93bca commit 03e6568
Show file tree
Hide file tree
Showing 14 changed files with 314 additions and 6 deletions.
27 changes: 27 additions & 0 deletions lib/LongitudeOne/SpatialTypes/Exception/InvalidFamilyException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
/**
* This file is part of the spatial project.
*
* PHP 8.1 | 8.2 | 8.3
*
* Copyright Alexandre Tranchant <[email protected]> 2024
* Copyright Longitude One 2024
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
*/

declare(strict_types=1);

namespace LongitudeOne\SpatialTypes\Exception;

/**
* This exception is thrown when mixing objects with non-compatible families.
*
* Example: When a developer tries to add a geometric point to a geographic linestring,
* this exception is thrown.
*/
class InvalidFamilyException extends \Exception implements SpatialTypeExceptionInterface
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
/**
* This exception is thrown when a coordinate is invalid.
*/
class InvalidValueException extends \Exception implements SpatialTypeExceptionInterface
class InvalidValueException extends \InvalidArgumentException implements SpatialTypeExceptionInterface
{
public const OUT_OF_RANGE_LATITUDE = 'Out of range latitude value, latitude must be between -90 and 90, got "%s".';
public const OUT_OF_RANGE_LONGITUDE = 'Out of range longitude value, longitude must be between -180 and 180, got "%s".';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ public function getPoint(int $index): PointInterface;
*/
public function getPoints(): array;

/**
* Is the line string empty?
*
* A line string is empty when it does not contain any point.
*/
public function isEmpty(): bool;

/**
* Is the line string a line?
*
Expand Down
6 changes: 4 additions & 2 deletions lib/LongitudeOne/SpatialTypes/Trait/LineStringTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

namespace LongitudeOne\SpatialTypes\Trait;

use LongitudeOne\SpatialTypes\Exception\InvalidFamilyException;
use LongitudeOne\SpatialTypes\Exception\InvalidSridException;
use LongitudeOne\SpatialTypes\Exception\InvalidValueException;
use LongitudeOne\SpatialTypes\Exception\SpatialTypeExceptionInterface;
Expand All @@ -37,7 +38,8 @@ trait LineStringTrait
*
* @param array{0: float|int|string, 1: float|int|string, 2 ?: null|float|int, 3 ?: null|\DateTimeInterface|float|int}[]|LineStringInterface|PointInterface[] $lineString line string to add
*
* @throws InvalidValueException when the line string dimension is not compatible with the current dimension
* @throws InvalidValueException when the line string dimension is not compatible with the current dimension
* @throws InvalidFamilyException when the line string family is not compatible with the current family
*/
private function traitAddLineString(array|LineStringInterface $lineString): static
{
Expand All @@ -50,7 +52,7 @@ private function traitAddLineString(array|LineStringInterface $lineString): stat
}

if ($lineString->getFamily() !== $this->getFamily()) {
throw new InvalidValueException('The line string family is not compatible with the family of the current linestring collection.');
throw new InvalidFamilyException('The line string family is not compatible with the family of the current linestring collection.');
}

if (!empty($lineString->getSrid()) && !empty($this->getSrid()) && $lineString->getSrid() !== $this->getSrid()) {
Expand Down
7 changes: 6 additions & 1 deletion lib/LongitudeOne/SpatialTypes/Trait/PointTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
namespace LongitudeOne\SpatialTypes\Trait;

use LongitudeOne\SpatialTypes\Exception\InvalidDimensionException;
use LongitudeOne\SpatialTypes\Exception\InvalidFamilyException;
use LongitudeOne\SpatialTypes\Exception\InvalidSridException;
use LongitudeOne\SpatialTypes\Exception\InvalidValueException;
use LongitudeOne\SpatialTypes\Exception\MissingValueException;
Expand Down Expand Up @@ -62,6 +63,10 @@ public function addPoint(array|PointInterface $point): static
throw new InvalidSridException('The point SRID is not compatible with the SRID of this current spatial collection.');
}

if ($this->getFamily() !== $point->getFamily()) {
throw new InvalidFamilyException('The point family is not compatible with the family of the current spatial collection.');
}

$this->points[] = $point;

return $this;
Expand All @@ -81,7 +86,7 @@ public function addPoints(array $points): static
{
foreach ($points as $point) {
if (!is_array($point) && !$point instanceof PointInterface) {
throw new InvalidValueException('The point is missing.');
throw new InvalidValueException('Argument shall contain an array of PointInterface or an array of coordinates.');
}

$this->addPoint($point);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
namespace LongitudeOne\SpatialTypes\Types;

use LongitudeOne\SpatialTypes\Exception\InvalidDimensionException;
use LongitudeOne\SpatialTypes\Exception\InvalidFamilyException;
use LongitudeOne\SpatialTypes\Exception\InvalidSridException;
use LongitudeOne\SpatialTypes\Exception\InvalidValueException;
use LongitudeOne\SpatialTypes\Exception\MissingValueException;
Expand Down Expand Up @@ -58,7 +59,11 @@ public function __construct(array $lineStrings, ?int $srid = null)
*/
public function addLineString(array|LineStringInterface $lineString): static
{
return $this->traitAddLineString($lineString);
try {
return $this->traitAddLineString($lineString);
} catch (InvalidFamilyException $e) {
throw new InvalidFamilyException('The line string family is not compatible with the family of the current multilinestring.', $e->getCode(), $e);
}
}

/**
Expand Down
5 changes: 5 additions & 0 deletions lib/LongitudeOne/SpatialTypes/Types/AbstractPolygon.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
namespace LongitudeOne\SpatialTypes\Types;

use LongitudeOne\SpatialTypes\Exception\InvalidDimensionException;
use LongitudeOne\SpatialTypes\Exception\InvalidFamilyException;
use LongitudeOne\SpatialTypes\Exception\InvalidSridException;
use LongitudeOne\SpatialTypes\Exception\InvalidValueException;
use LongitudeOne\SpatialTypes\Exception\MissingValueException;
Expand Down Expand Up @@ -67,6 +68,10 @@ public function addRing(array|LineStringInterface $ring): static
throw new InvalidValueException('The line string is not a ring.');
}

if ($ring->getFamily() !== $this->getFamily()) {
throw new InvalidFamilyException('The ring family is not compatible with the family of the current polygon.');
}

return $this->traitAddLineString($ring);
}

Expand Down
25 changes: 25 additions & 0 deletions quality/php-stan/phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,32 @@ parameters:
count: 1
path: ../../tests/LongitudeOne/SpatialTypes/Tests/Old/Types/Geometry/MultiPointTest.php

-
message: "#^Parameter \\#1 \\$points of static method LongitudeOne\\\\SpatialTypes\\\\Factory\\\\FactoryLineString\\:\\:fromArrayOfPoints\\(\\) expects array\\<LongitudeOne\\\\SpatialTypes\\\\Interfaces\\\\PointInterface\\>, array\\<int, string\\> given\\.$#"
count: 1
path: ../../tests/LongitudeOne/SpatialTypes/Tests/Unit/Factory/FactoryLineStringTest.php

-
message: "#^Parameter \\#1 \\$point of static method LongitudeOne\\\\SpatialTypes\\\\Factory\\\\FactoryPoint\\:\\:fromIndexedArray\\(\\) expects array\\{0\\: float\\|int\\|string, 1\\: float\\|int\\|string, 2\\?\\: float\\|int\\|null, 3\\?\\: DateTimeInterface\\|float\\|int\\|null\\}, array\\<int\\> given\\.$#"
count: 1
path: ../../tests/LongitudeOne/SpatialTypes/Tests/Unit/Factory/FactoryPointTest.php

-
message: "#^Parameter \\#1 \\$point of static method LongitudeOne\\\\SpatialTypes\\\\Factory\\\\FactoryPoint\\:\\:fromIndexedArray\\(\\) expects array\\{0\\: float\\|int\\|string, 1\\: float\\|int\\|string, 2\\?\\: float\\|int\\|null, 3\\?\\: DateTimeInterface\\|float\\|int\\|null\\}, array\\{1, null\\} given\\.$#"
count: 1
path: ../../tests/LongitudeOne/SpatialTypes/Tests/Unit/Factory/FactoryPointTest.php

-
message: "#^Parameter \\#1 \\$point of static method LongitudeOne\\\\SpatialTypes\\\\Factory\\\\FactoryPoint\\:\\:fromIndexedArray\\(\\) expects array\\{0\\: float\\|int\\|string, 1\\: float\\|int\\|string, 2\\?\\: float\\|int\\|null, 3\\?\\: DateTimeInterface\\|float\\|int\\|null\\}, array\\{null, 2\\} given\\.$#"
count: 1
path: ../../tests/LongitudeOne/SpatialTypes/Tests/Unit/Factory/FactoryPointTest.php

-
message: "#^Unreachable statement \\- code above always terminates\\.$#"
count: 1
path: ../../tests/LongitudeOne/SpatialTypes/Tests/Unit/Factory/FactoryPointTest.php

-
message: "#^Parameter \\#1 \\$points of method LongitudeOne\\\\SpatialTypes\\\\Types\\\\AbstractLineString\\:\\:addPoints\\(\\) expects array\\<array\\{0\\: float\\|int\\|string, 1\\: float\\|int\\|string, 2\\?\\: float\\|int\\|null, 3\\?\\: DateTimeInterface\\|float\\|int\\|null\\}\\|LongitudeOne\\\\SpatialTypes\\\\Interfaces\\\\PointInterface\\>, array\\{'foo', 'bar'\\} given\\.$#"
count: 1
path: ../../tests/LongitudeOne/SpatialTypes/Tests/Unit/Types/Geometry/LineStringTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class MultiPointTest extends TestCase
public function testBadMultiPointConstructor(): void
{
$this->expectException(InvalidValueException::class);
$this->expectExceptionMessage('The point is missing.');
$this->expectExceptionMessage('Argument shall contain an array of PointInterface or an array of coordinates.');

new MultiPoint([1, 2, 3, 4]);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<?php
/**
* This file is part of the spatial project.
*
* PHP 8.1 | 8.2 | 8.3
*
* Copyright Alexandre Tranchant <[email protected]> 2024
* Copyright Longitude One 2024
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
*/

declare(strict_types=1);

namespace LongitudeOne\SpatialTypes\Tests\Unit\Factory;

use LongitudeOne\SpatialTypes\Enum\DimensionEnum;
use LongitudeOne\SpatialTypes\Enum\FamilyEnum;
use LongitudeOne\SpatialTypes\Exception\InvalidDimensionException;
use LongitudeOne\SpatialTypes\Exception\InvalidValueException;
use LongitudeOne\SpatialTypes\Factory\FactoryLineString;
use LongitudeOne\SpatialTypes\Interfaces\LineStringInterface;
use LongitudeOne\SpatialTypes\Types\Geography\Point as GeographicPoint;
use LongitudeOne\SpatialTypes\Types\Geometry\Point;
use PHPUnit\Framework\TestCase;

/**
* @internal
*
* @covers \LongitudeOne\SpatialTypes\Factory\FactoryLineString
*/
class FactoryLineStringTest extends TestCase
{
/**
* Test the creation of a line string from an array of points.
*/
public function testFromArrayOfPoints(): void
{
$points = [
new GeographicPoint(1, 2),
new GeographicPoint(3, 4),
];

$lineString = FactoryLineString::fromArrayOfPoints($points, 4326, FamilyEnum::GEOGRAPHY, DimensionEnum::X_Y);

static::assertInstanceOf(LineStringInterface::class, $lineString);
static::assertCount(2, $lineString->getPoints());
static::assertSame(4326, $lineString->getSrid());
static::assertSame(FamilyEnum::GEOGRAPHY, $lineString->getFamily());
static::assertFalse($lineString->hasM());
static::assertFalse($lineString->hasZ());
static::assertFalse($lineString->isEmpty());
}

/**
* Test the creation of a line string from an array of points with an invalid dimension.
*/
public function testFromArrayOfPointsInvalidDimension(): void
{
$this->expectException(InvalidDimensionException::class);

$points = [
new Point(1, 2),
];

FactoryLineString::fromArrayOfPoints($points, 4326, FamilyEnum::GEOGRAPHY, DimensionEnum::X_Y_Z);
}

/**
* Test the creation of a line string from an array of points with an invalid value.
*/
public function testFromArrayOfPointsInvalidValue(): void
{
$this->expectException(InvalidValueException::class);

FactoryLineString::fromArrayOfPoints(['invalid_point'], 4326, FamilyEnum::GEOGRAPHY, DimensionEnum::X_Y);
}

/**
* Test the creation of a line string from an indexed array of coordinates.
*/
public function testFromIndexedArray(): void
{
$indexedArray = [
[0.0, 0.0],
[1.0, 1.0],
];

$lineString = FactoryLineString::fromIndexedArray($indexedArray, 4326, FamilyEnum::GEOGRAPHY, DimensionEnum::X_Y);

static::assertInstanceOf(LineStringInterface::class, $lineString);
static::assertCount(2, $lineString->getPoints());
static::assertSame(4326, $lineString->getSrid());
static::assertSame(FamilyEnum::GEOGRAPHY, $lineString->getFamily());
static::assertFalse($lineString->hasM());
static::assertFalse($lineString->hasZ());
static::assertFalse($lineString->isEmpty());
}

/**
* Test the creation of a line string from an indexed array of points.
*/
public function testFromIndexedArrayWithPoints(): void
{
$points = [
new Point(1, 2),
new Point(3, 4),
];

$lineString = FactoryLineString::fromIndexedArray($points, 4326, FamilyEnum::GEOMETRY, DimensionEnum::X_Y);

static::assertInstanceOf(LineStringInterface::class, $lineString);
static::assertCount(2, $lineString->getPoints());
static::assertSame(4326, $lineString->getSrid());
static::assertSame(FamilyEnum::GEOMETRY, $lineString->getFamily());
static::assertFalse($lineString->hasM());
static::assertFalse($lineString->hasZ());
static::assertFalse($lineString->isEmpty());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use LongitudeOne\SpatialTypes\Enum\FamilyEnum;
use LongitudeOne\SpatialTypes\Enum\TypeEnum;
use LongitudeOne\SpatialTypes\Exception\InvalidDimensionException;
use LongitudeOne\SpatialTypes\Exception\InvalidValueException;
use LongitudeOne\SpatialTypes\Exception\MissingValueException;
use LongitudeOne\SpatialTypes\Exception\SpatialTypeExceptionInterface;
use LongitudeOne\SpatialTypes\Factory\FactoryPoint;
Expand Down Expand Up @@ -127,6 +128,36 @@ public function testFromIndexedArray(): void
static::assertSame(TypeEnum::POINT->value, $point->getType());
}

/**
* Test the factory with an invalid value.
*/
public function testFromIndexedArrayInvalidCoordinate(): void
{
self::expectException(InvalidValueException::class);
self::expectExceptionMessage('Invalid coordinate value, got "invalid".');
FactoryPoint::fromIndexedArray(['invalid', 2]);
}

/**
* Test the factory with the first coordinate missing in the array.
*/
public function testFromIndexedArrayMissingFirstCoordinate(): void
{
self::expectException(MissingValueException::class);
self::expectExceptionMessage('The first coordinate of array is missing.');
FactoryPoint::fromIndexedArray([null, 2]);
}

/**
* Test the factory with some bad values in an array.
*/
public function testFromIndexedArrayMissingSecondCoordinate(): void
{
self::expectException(MissingValueException::class);
self::expectExceptionMessage('The second coordinate of array is missing.');
FactoryPoint::fromIndexedArray([1, null]);
}

// phpcs:disable Squiz.Commenting.FunctionComment.IncorrectTypeHint

/**
Expand All @@ -143,4 +174,27 @@ public function testFromIndexedArrayWithBadValues(array $values, string $excepte
self::expectExceptionMessage($expectedMessage);
FactoryPoint::fromIndexedArray($values);
}

/**
* Test the factory with some non-compatible dimensions.
*/
public function testFromIndexedArrayWithDifferentDimensions(): void
{
static::markTestSkipped('The third dimensions have not been created yet.');
$point = FactoryPoint::fromIndexedArray([1, 2, 3], 4326, FamilyEnum::GEOGRAPHY, DimensionEnum::X_Y_Z);
static::assertSame(1, $point->getX());
static::assertSame(2, $point->getY());
static::assertSame(3, $point->getZ());
static::assertFalse($point->hasM());
static::assertSame(FamilyEnum::GEOGRAPHY, $point->getFamily());
static::assertSame(TypeEnum::POINT->value, $point->getType());

$point = FactoryPoint::fromIndexedArray([1, 2, null, 4], 4326, FamilyEnum::GEOGRAPHY, DimensionEnum::X_Y_M);
static::assertSame(1, $point->getX());
static::assertSame(2, $point->getY());
static::assertSame(4, $point->getM());
static::assertFalse($point->hasZ());
static::assertSame(FamilyEnum::GEOGRAPHY, $point->getFamily());
static::assertSame(TypeEnum::POINT->value, $point->getType());
}
}
Loading

0 comments on commit 03e6568

Please sign in to comment.