Skip to content

Commit 24d7d81

Browse files
authored
Merge pull request #16 from MatanYadaev/non-happy-tests
Add non-happy path tests
2 parents 89f11df + d1e7a22 commit 24d7d81

18 files changed

+336
-144
lines changed

phpinsights.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use PHP_CodeSniffer\Standards\Generic\Sniffs\CodeAnalysis\UselessOverridingMethodSniff;
1212
use PHP_CodeSniffer\Standards\Generic\Sniffs\Files\LineLengthSniff;
1313
use SlevomatCodingStandard\Sniffs\Classes\SuperfluousExceptionNamingSniff;
14+
use SlevomatCodingStandard\Sniffs\Commenting\InlineDocCommentDeclarationSniff;
1415
use SlevomatCodingStandard\Sniffs\Functions\UnusedParameterSniff;
1516
use SlevomatCodingStandard\Sniffs\TypeHints\DisallowMixedTypeHintSniff;
1617
use SlevomatCodingStandard\Sniffs\TypeHints\ParameterTypeHintSniff;
@@ -90,8 +91,11 @@
9091
'ignoreComments' => false,
9192
],
9293
MaxNestingLevelSniff::class => [
94+
'maxNestingLevel' => 3,
95+
],
96+
InlineDocCommentDeclarationSniff::class => [
9397
'exclude' => [
94-
'src/Objects/Geometry.php',
98+
'src/Factory.php',
9599
],
96100
],
97101
UnusedParameterSniff::class => [
@@ -119,6 +123,7 @@
119123
CyclomaticComplexityIsHigh::class => [
120124
'exclude' => [
121125
'src/Factory.php',
126+
'src/Objects/GeometryCollection.php',
122127
],
123128
],
124129
],
@@ -136,7 +141,7 @@
136141

137142
'requirements' => [
138143
'min-quality' => 90,
139-
'min-complexity' => 90,
144+
'min-complexity' => 80,
140145
'min-architecture' => 90,
141146
'min-style' => 90,
142147
'disable-security-check' => true,

src/Exceptions/InvalidTypeException.php

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/Exceptions/UnsupportedDatabaseDriverException.php

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/Factory.php

Lines changed: 33 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
namespace MatanYadaev\EloquentSpatial;
66

77
use Geometry as geoPHPGeometry;
8+
use GeometryCollection as geoPHPGeometryCollection;
89
use geoPHP;
9-
use Illuminate\Support\Collection;
10+
use InvalidArgumentException;
1011
use LineString as geoPHPLineString;
1112
use MatanYadaev\EloquentSpatial\Objects\Geometry;
1213
use MatanYadaev\EloquentSpatial\Objects\GeometryCollection;
@@ -33,106 +34,56 @@ public static function parse(string $value): Geometry
3334
$value = substr($value, 4);
3435
}
3536

36-
/** @var geoPHPGeometry $geoPHPGeometry */
37-
$geoPHPGeometry = geoPHP::load($value);
37+
try {
38+
/** @var geoPHPGeometry|false $geoPHPGeometry */
39+
$geoPHPGeometry = geoPHP::load($value);
40+
} finally {
41+
if (! isset($geoPHPGeometry) || ! $geoPHPGeometry) {
42+
throw new InvalidArgumentException('Invalid spatial value');
43+
}
44+
}
3845

3946
return self::createFromGeometry($geoPHPGeometry);
4047
}
4148

4249
protected static function createFromGeometry(geoPHPGeometry $geometry): Geometry
4350
{
4451
if ($geometry instanceof geoPHPPoint) {
45-
return self::createPoint($geometry->coords[1], $geometry->coords[0]);
52+
if ($geometry->coords[0] === null || $geometry->coords[1] === null) {
53+
if (! isset($geoPHPGeometry) || ! $geoPHPGeometry) {
54+
throw new InvalidArgumentException('Invalid spatial value');
55+
}
56+
}
57+
58+
return new Point($geometry->coords[1], $geometry->coords[0]);
4659
}
4760

61+
/** @var geoPHPGeometryCollection $geometry */
4862
$components = collect($geometry->components)
4963
->map(static function (geoPHPGeometry $geometryComponent): Geometry {
5064
return self::createFromGeometry($geometryComponent);
5165
});
5266

53-
$className = $geometry::class;
54-
55-
if ($className === geoPHPMultiPoint::class) {
56-
return self::createMultiPoint($components);
57-
}
58-
if ($className === geoPHPLineString::class) {
59-
return self::createLineString($components);
60-
}
61-
if ($className === geoPHPPolygon::class) {
62-
return self::createPolygon($components);
63-
}
64-
if ($className === geoPHPMultiLineString::class) {
65-
return self::createMultiLineString($components);
66-
}
67-
if ($className === geoPHPMultiPolygon::class) {
68-
return self::createMultiPolygon($components);
67+
if ($geometry::class === geoPHPMultiPoint::class) {
68+
return new MultiPoint($components);
6969
}
7070

71-
return self::createGeometryCollection($components);
72-
}
73-
74-
protected static function createPoint(float $latitude, float $longitude): Point
75-
{
76-
return new Point($latitude, $longitude);
77-
}
78-
79-
/**
80-
* @param Collection<Point> $points
81-
*
82-
* @return MultiPoint
83-
*/
84-
protected static function createMultiPoint(Collection $points): MultiPoint
85-
{
86-
return new MultiPoint($points);
87-
}
88-
89-
/**
90-
* @param Collection<Point> $points
91-
*
92-
* @return LineString
93-
*/
94-
protected static function createLineString(Collection $points): LineString
95-
{
96-
return new LineString($points);
97-
}
71+
if ($geometry::class === geoPHPLineString::class) {
72+
return new LineString($components);
73+
}
9874

99-
/**
100-
* @param Collection<LineString> $lineStrings
101-
*
102-
* @return Polygon
103-
*/
104-
protected static function createPolygon(Collection $lineStrings): Polygon
105-
{
106-
return new Polygon($lineStrings);
107-
}
75+
if ($geometry::class === geoPHPPolygon::class) {
76+
return new Polygon($components);
77+
}
10878

109-
/**
110-
* @param Collection<LineString> $lineStrings
111-
*
112-
* @return MultiLineString
113-
*/
114-
protected static function createMultiLineString(Collection $lineStrings): MultiLineString
115-
{
116-
return new MultiLineString($lineStrings);
117-
}
79+
if ($geometry::class === geoPHPMultiLineString::class) {
80+
return new MultiLineString($components);
81+
}
11882

119-
/**
120-
* @param Collection<Polygon> $polygons
121-
*
122-
* @return MultiPolygon
123-
*/
124-
protected static function createMultiPolygon(Collection $polygons): MultiPolygon
125-
{
126-
return new MultiPolygon($polygons);
127-
}
83+
if ($geometry::class === geoPHPMultiPolygon::class) {
84+
return new MultiPolygon($components);
85+
}
12886

129-
/**
130-
* @param Collection<Geometry> $geometries
131-
*
132-
* @return GeometryCollection
133-
*/
134-
protected static function createGeometryCollection(Collection $geometries): GeometryCollection
135-
{
136-
return new GeometryCollection($geometries);
87+
return new GeometryCollection($components);
13788
}
13889
}

src/GeometryCast.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@
77
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
88
use Illuminate\Database\Eloquent\Model;
99
use Illuminate\Database\Query\Expression;
10-
use MatanYadaev\EloquentSpatial\Exceptions\InvalidTypeException;
10+
use InvalidArgumentException;
1111
use MatanYadaev\EloquentSpatial\Objects\Geometry;
1212

1313
class GeometryCast implements CastsAttributes
1414
{
15+
/** @var class-string<Geometry> */
1516
private string $className;
1617

18+
/**
19+
* @param class-string<Geometry> $className
20+
*/
1721
public function __construct(string $className)
1822
{
1923
$this->className = $className;
@@ -33,18 +37,18 @@ public function get($model, string $key, $wkt, array $attributes): ?Geometry
3337
return null;
3438
}
3539

36-
return $this->className::fromWkt($wkt, false);
40+
return $this->className::fromWkb($wkt);
3741
}
3842

3943
/**
4044
* @param Model $model
4145
* @param string $key
42-
* @param Geometry|null $geometry
46+
* @param Geometry|mixed|null $geometry
4347
* @param array<string, mixed> $attributes
4448
*
4549
* @return Expression|string|null
4650
*
47-
* @throws InvalidTypeException
51+
* @throws InvalidArgumentException
4852
*/
4953
public function set($model, string $key, $geometry, array $attributes): Expression | string | null
5054
{
@@ -53,7 +57,10 @@ public function set($model, string $key, $geometry, array $attributes): Expressi
5357
}
5458

5559
if (! ($geometry instanceof $this->className)) {
56-
throw new InvalidTypeException($this->className, $geometry);
60+
$geometryType = is_object($geometry) ? $geometry::class : gettype($geometry);
61+
throw new InvalidArgumentException(
62+
sprintf('Expected %s, %s given.', static::class, $geometryType)
63+
);
5764
}
5865

5966
return $geometry->toWkt();

src/Objects/Geometry.php

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,51 +9,55 @@
99
use Illuminate\Contracts\Support\Arrayable;
1010
use Illuminate\Contracts\Support\Jsonable;
1111
use Illuminate\Database\Query\Expression;
12+
use InvalidArgumentException;
1213
use JsonSerializable;
13-
use MatanYadaev\EloquentSpatial\Exceptions\InvalidTypeException;
1414
use MatanYadaev\EloquentSpatial\Factory;
1515
use MatanYadaev\EloquentSpatial\GeometryCast;
1616

1717
abstract class Geometry implements Castable, Arrayable, Jsonable, JsonSerializable
1818
{
1919
abstract public function toWkt(): Expression;
2020

21+
public function toJson($options = 0): string
22+
{
23+
return json_encode($this, $options);
24+
}
25+
2126
/**
22-
* @param string $wkt
27+
* @param string $wkb
2328
*
2429
* @return static
2530
*
26-
* @throws InvalidTypeException
31+
* @throws InvalidArgumentException
2732
*/
28-
public static function fromWkt(string $wkt): static
33+
public static function fromWkb(string $wkb): static
2934
{
30-
$geometry = Factory::parse($wkt);
35+
$geometry = Factory::parse($wkb);
3136

3237
if (! ($geometry instanceof static)) {
33-
throw new InvalidTypeException(static::class, $geometry);
38+
throw new InvalidArgumentException(
39+
sprintf('Expected %s, %s given.', static::class, $geometry::class)
40+
);
3441
}
3542

3643
return $geometry;
3744
}
3845

39-
public function toJson($options = 0): string
40-
{
41-
return json_encode($this, $options);
42-
}
43-
4446
/**
4547
* @param string $geoJson
4648
*
4749
* @return static
4850
*
49-
* @throws InvalidTypeException
51+
* @throws InvalidArgumentException
5052
*/
5153
public static function fromJson(string $geoJson): static
5254
{
5355
$geometry = Factory::parse($geoJson);
5456

5557
if (! ($geometry instanceof static)) {
56-
throw new InvalidTypeException(static::class, $geometry);
58+
throw new InvalidArgumentException(
59+
sprintf('Expected %s, %s given.', static::class, $geometry::class)
60+
);
5761
}
5862

5963
return $geometry;
@@ -78,6 +82,11 @@ public function toArray(): array
7882
];
7983
}
8084

85+
/**
86+
* @return array{
87+
* type: string, properties: array<mixed>, geometry: array{type: string, coordinates: array<mixed>}
88+
* }
89+
*/
8190
public function toFeature(): array
8291
{
8392
return [

src/Objects/GeometryCollection.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ public function __construct(Collection | array $geometries)
3232

3333
$this->geometries = $geometries;
3434

35-
$this->validateGeometriesCount();
3635
$this->validateGeometriesType();
36+
$this->validateGeometriesCount();
3737
}
3838

3939
public function toWkt(): Expression
@@ -102,11 +102,13 @@ protected function validateGeometriesCount(): void
102102
{
103103
$geometriesCount = $this->geometries->count();
104104
if ($geometriesCount < $this->minimumGeometries) {
105-
$className = self::class;
106-
107105
throw new InvalidArgumentException(
108-
"{$className} must contain at least {$this->minimumGeometries} "
109-
.Str::plural('entries', $geometriesCount)
106+
sprintf(
107+
'%s must contain at least %s %s',
108+
static::class,
109+
$this->minimumGeometries,
110+
Str::plural('entries', $geometriesCount)
111+
)
110112
);
111113
}
112114
}
@@ -116,12 +118,10 @@ protected function validateGeometriesCount(): void
116118
*/
117119
protected function validateGeometriesType(): void
118120
{
119-
$this->geometries->each(function (Geometry $geometry): void {
120-
if (! ($geometry instanceof $this->collectionOf)) {
121-
$className = self::class;
122-
121+
$this->geometries->each(function (mixed $geometry): void {
122+
if (! is_object($geometry) || ! ($geometry instanceof $this->collectionOf)) {
123123
throw new InvalidArgumentException(
124-
"{$className} must be a collection of {$this->collectionOf}"
124+
sprintf('%s must be a collection of %s', static::class, $this->collectionOf)
125125
);
126126
}
127127
});

0 commit comments

Comments
 (0)