diff --git a/phpstan.neon b/phpstan.neon index 5a9fd29..4e4c88b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -6,9 +6,6 @@ parameters: - tests level: max ignoreErrors: - - - message: '#^Undefined variable\: \$this$#' - path: tests/*.php - message: '#^Call to an undefined method Pest\\Expectation\|Pest\\Support\\Extendable\:\:.+\(\)\.$#' path: tests/*.php diff --git a/src/Objects/Geometry.php b/src/Objects/Geometry.php index 386d466..3f9f167 100644 --- a/src/Objects/Geometry.php +++ b/src/Objects/Geometry.php @@ -123,7 +123,7 @@ public function toArray(): array public function toFeatureCollectionJson(): string { if (static::class === GeometryCollection::class) { - /** @var GeometryCollection $this */ + /** @var GeometryCollection $this */ $geometries = $this->geometries; } else { $geometries = collect([$this]); diff --git a/src/Objects/GeometryCollection.php b/src/Objects/GeometryCollection.php index b92fd8d..a15603a 100644 --- a/src/Objects/GeometryCollection.php +++ b/src/Objects/GeometryCollection.php @@ -9,23 +9,17 @@ use Illuminate\Support\Str; use InvalidArgumentException; -/** - * @template TGeometry of Geometry - * - * @implements ArrayAccess - */ class GeometryCollection extends Geometry implements ArrayAccess { - /** @var Collection */ + /** @var Collection */ protected Collection $geometries; - /** @var class-string */ protected string $collectionOf = Geometry::class; protected int $minimumGeometries = 0; /** - * @param Collection|array $geometries + * @param Collection|array $geometries * * @throws InvalidArgumentException */ @@ -41,12 +35,6 @@ public function __construct(Collection|array $geometries) $this->validateGeometriesCount(); } - /** - * @param bool $withFunction - * @return string - * - * @phpcsSuppress SlevomatCodingStandard.Functions.UnusedParameter - */ public function toWkt(bool $withFunction = true): string { $wkt = $this->toCollectionWkt(withFunction: true); @@ -84,7 +72,7 @@ public function toArray(): array } /** - * @return Collection + * @return Collection */ public function getGeometries(): Collection { @@ -102,20 +90,21 @@ public function offsetExists($offset): bool /** * @param int $offset - * @return TGeometry|null + * @return Geometry */ - public function offsetGet($offset): ?Geometry + public function offsetGet($offset): Geometry { + // @phpstan-ignore-next-line return $this->geometries[$offset]; } /** * @param int $offset - * @param TGeometry $geometry + * @param Geometry $value */ - public function offsetSet($offset, $geometry): void + public function offsetSet($offset, $value): void { - $this->geometries[$offset] = $geometry; + $this->geometries[$offset] = $value; $this->validateGeometriesType(); } diff --git a/src/Objects/MultiLineString.php b/src/Objects/MultiLineString.php index 676bfb4..dfc3fba 100644 --- a/src/Objects/MultiLineString.php +++ b/src/Objects/MultiLineString.php @@ -4,11 +4,15 @@ namespace MatanYadaev\EloquentSpatial\Objects; +use Illuminate\Support\Collection; +use InvalidArgumentException; + /** - * @method array getGeometries() - * @method LineString offsetGet(mixed $offset) + * @property Collection $geometries * - * @extends GeometryCollection + * @method Collection getGeometries() + * @method LineString offsetGet(int $offset) + * @method void offsetSet(int $offset, LineString $value) */ class MultiLineString extends GeometryCollection { @@ -17,11 +21,16 @@ class MultiLineString extends GeometryCollection protected int $minimumGeometries = 1; /** - * @param bool $withFunction - * @return string + * @param Collection|array $geometries * - * @phpcsSuppress SlevomatCodingStandard.Functions.UnusedParameter + * @throws InvalidArgumentException */ + public function __construct(Collection|array $geometries) + { + // @phpstan-ignore-next-line + parent::__construct($geometries); + } + public function toWkt(bool $withFunction = true): string { $wkt = $this->toCollectionWkt(withFunction: false); diff --git a/src/Objects/MultiPoint.php b/src/Objects/MultiPoint.php index faa1f14..e531e3d 100644 --- a/src/Objects/MultiPoint.php +++ b/src/Objects/MultiPoint.php @@ -8,12 +8,6 @@ class MultiPoint extends PointCollection { protected int $minimumGeometries = 1; - /** - * @param bool $withFunction - * @return string - * - * @phpcsSuppress SlevomatCodingStandard.Functions.UnusedParameter - */ public function toWkt(bool $withFunction = true): string { $wkt = $this->toCollectionWkt(withFunction: false); diff --git a/src/Objects/MultiPolygon.php b/src/Objects/MultiPolygon.php index 07fa5bd..a038860 100644 --- a/src/Objects/MultiPolygon.php +++ b/src/Objects/MultiPolygon.php @@ -4,11 +4,15 @@ namespace MatanYadaev\EloquentSpatial\Objects; +use Illuminate\Support\Collection; +use InvalidArgumentException; + /** - * @method array getGeometries() - * @method Polygon offsetGet(mixed $offset) + * @property Collection $geometries * - * @extends GeometryCollection + * @method Collection getGeometries() + * @method Polygon offsetGet(int $offset) + * @method void offsetSet(int $offset, Polygon $value) */ class MultiPolygon extends GeometryCollection { @@ -17,11 +21,16 @@ class MultiPolygon extends GeometryCollection protected int $minimumGeometries = 1; /** - * @param bool $withFunction - * @return string + * @param Collection|array $geometries * - * @phpcsSuppress SlevomatCodingStandard.Functions.UnusedParameter + * @throws InvalidArgumentException */ + public function __construct(Collection|array $geometries) + { + // @phpstan-ignore-next-line + parent::__construct($geometries); + } + public function toWkt(bool $withFunction = true): string { $wkt = $this->toCollectionWkt(withFunction: false); diff --git a/src/Objects/PointCollection.php b/src/Objects/PointCollection.php index c58ac0b..f04a3f9 100644 --- a/src/Objects/PointCollection.php +++ b/src/Objects/PointCollection.php @@ -4,13 +4,28 @@ namespace MatanYadaev\EloquentSpatial\Objects; +use Illuminate\Support\Collection; +use InvalidArgumentException; + /** - * @method array getGeometries() - * @method Point offsetGet(mixed $offset) + * @property Collection $geometries * - * @extends GeometryCollection + * @method Collection getGeometries() + * @method Point offsetGet(int $offset) + * @method void offsetSet(int $offset, Point $value) */ abstract class PointCollection extends GeometryCollection { protected string $collectionOf = Point::class; + + /** + * @param Collection|array $geometries + * + * @throws InvalidArgumentException + */ + public function __construct(Collection|array $geometries) + { + // @phpstan-ignore-next-line + parent::__construct($geometries); + } } diff --git a/tests/GeometryCastTest.php b/tests/GeometryCastTest.php index 1175400..43b4d75 100644 --- a/tests/GeometryCastTest.php +++ b/tests/GeometryCastTest.php @@ -1,158 +1,106 @@ create([ - 'point' => $point, - ]); - - $this->assertEquals($point, $testPlace->point); - } - - /** @test */ - public function it_creates_model_record_with_geometry_null(): void - { - /** @var TestPlace $testPlace */ - $testPlace = TestPlace::factory()->create([ - 'point' => null, - ]); - - $this->assertEquals(null, $testPlace->point); - } - - /** @test */ - public function it_updates_model_record(): void - { - $point = new Point(180, 0); - $point2 = new Point(0, 0); - - /** @var TestPlace $testPlace */ - $testPlace = TestPlace::factory()->create([ - 'point' => $point, - ]); +uses(DatabaseMigrations::class); - $testPlace->update([ - 'point' => $point2, - ]); +it('creates a model record with null geometry', function (): void { + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::factory()->create(['point' => null]); - $this->assertEquals($point2, $testPlace->point); - } + expect($testPlace->point)->toBeNull(); +}); - /** @test */ - public function it_updates_model_record_with_geometry_null(): void - { - $point = new Point(180, 0); +it('updates a model record', function (): void { + $point = new Point(180, 0); + $point2 = new Point(0, 0); + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::factory()->create(['point' => $point]); - /** @var TestPlace $testPlace */ - $testPlace = TestPlace::factory()->create([ - 'point' => $point, - ]); + $testPlace->update(['point' => $point2]); - $testPlace->update([ - 'point' => null, - ]); + expect($testPlace->point)->not->toEqual($point); + expect($testPlace->point)->toEqual($point2); +}); - $this->assertEquals(null, $testPlace->point); - } +it('updates a model record with null geometry', function (): void { + $point = new Point(180, 0); + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::factory()->create(['point' => $point]); - /** @test */ - public function it_gets_original_geometry_field(): void - { - $point = new Point(180, 0); - $point2 = new Point(180, 0); + $testPlace->update(['point' => null]); - /** @var TestPlace $testPlace */ - $testPlace = TestPlace::factory()->create([ - 'point' => $point, - ]); - $testPlace->point = $point2; - $testPlace->save(); + expect($testPlace->point)->toBeNull(); +}); - $this->assertEquals($point, $testPlace->getOriginal('point')); - } +it('gets original geometry field', function (): void { + $point = new Point(180, 0); + $point2 = new Point(0, 0); + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::factory()->create(['point' => $point]); - /** @test */ - public function it_serializes_model_to_array_with_geometry(): void - { - $point = new Point(180, 0); + $testPlace->point = $point2; - /** @var TestPlace $testPlace */ - $testPlace = TestPlace::factory()->create([ - 'point' => $point, - ]); + expect($testPlace->getOriginal('point'))->toEqual($point); + expect($testPlace->point)->not->toEqual($point); + expect($testPlace->point)->toEqual($point2); +}); - $this->assertEquals($point->toArray(), $testPlace->toArray()['point']); - } +it('serializes a model record to array with geometry', function (): void { + $point = new Point(180, 0); + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::factory()->create(['point' => $point]); - /** @test */ - public function it_serializes_model_to_json_with_geometry(): void - { - $point = new Point(180, 0); + $serialized = $testPlace->toArray(); - /** @var TestPlace $testPlace */ - $testPlace = TestPlace::factory()->create([ - 'point' => $point, - ]); + $expectedArray = $point->toArray(); + expect($serialized['point'])->toEqual($expectedArray); +}); - $json = $testPlace->toJson(); - // @phpstan-ignore-next-line - $jsonOfPoint = json_encode(json_decode($json, true)['point']); +it('serializes a model record to json with geometry', function (): void { + $point = new Point(180, 0); + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::factory()->create(['point' => $point]); - $this->assertEquals($point->toJson(), $jsonOfPoint); - } + $serialized = $testPlace->toJson(); - /** @test */ - public function it_throws_exception_when_serializing_invalid_geometry_object(): void - { - $this->expectException(InvalidArgumentException::class); + // @phpstan-ignore-next-line + $json = json_encode(json_decode($serialized, true)['point']); + $expectedJson = $point->toJson(); + expect($json)->toBe($expectedJson); +}); +it('throws exception when cast serializing incorrect geometry object', function (): void { + expect(function (): void { TestPlace::factory()->make([ 'point' => new LineString([ new Point(180, 0), new Point(179, 1), ]), ]); - } - - /** @test */ - public function it_throws_exception_when_serializing_invalid_type(): void - { - $this->expectException(InvalidArgumentException::class); + })->toThrow(InvalidArgumentException::class); +}); +it('throws exception when cast serializing non-geometry object', function (): void { + expect(function (): void { TestPlace::factory()->make([ 'point' => 'not-a-point-object', ]); - } - - /** @test */ - public function it_throws_exception_when_deserializing_invalid_geometry_object(): void - { - $this->expectException(InvalidArgumentException::class); - - TestPlace::insert(array_merge(TestPlace::factory()->definition(), [ - 'point_with_line_string_cast' => DB::raw('POINT(0, 180)'), - ])); + })->toThrow(InvalidArgumentException::class); +}); - /** @var TestPlace $testPlace */ - $testPlace = TestPlace::firstOrFail(); +it('throws exception when cast deserializing incorrect geometry object', function (): void { + TestPlace::insert(array_merge(TestPlace::factory()->definition(), [ + 'point_with_line_string_cast' => DB::raw('POINT(0, 180)'), + ])); + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::firstOrFail(); + expect(function () use ($testPlace): void { $testPlace->getAttribute('point_with_line_string_cast'); - } -} + })->toThrow(InvalidArgumentException::class); +}); diff --git a/tests/Objects/GeometryCollectionTest.php b/tests/Objects/GeometryCollectionTest.php index c653b82..5ffa774 100644 --- a/tests/Objects/GeometryCollectionTest.php +++ b/tests/Objects/GeometryCollectionTest.php @@ -1,224 +1,123 @@ create([ - 'geometry_collection' => new GeometryCollection([ - new Polygon([ - new LineString([ - new Point(180, 0), - new Point(179, 1), - new Point(178, 2), - new Point(177, 3), - new Point(180, 0), - ]), - ]), +uses(DatabaseMigrations::class); + +it('creates a model record with geometry collection', function (): void { + $geometryCollection = new GeometryCollection([ + new Polygon([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + new Point(178, 2), + new Point(177, 3), new Point(180, 0), ]), - ]); - - $this->assertTrue($testPlace->geometry_collection instanceof GeometryCollection); - - /** @var Polygon $polygon */ - $polygon = $testPlace->geometry_collection[0]; - $lineString = $polygon[0]; - - $this->assertEquals(180, $lineString[0]->latitude); - $this->assertEquals(0, $lineString[0]->longitude); - $this->assertEquals(179, $lineString[1]->latitude); - $this->assertEquals(1, $lineString[1]->longitude); - $this->assertEquals(178, $lineString[2]->latitude); - $this->assertEquals(2, $lineString[2]->longitude); - $this->assertEquals(177, $lineString[3]->latitude); - $this->assertEquals(3, $lineString[3]->longitude); - $this->assertEquals(180, $lineString[4]->latitude); - $this->assertEquals(0, $lineString[4]->longitude); - - /** @var Point $point */ - $point = $testPlace->geometry_collection[1]; - - $this->assertEquals(180, $point->latitude); - $this->assertEquals(0, $point->longitude); - - $this->assertDatabaseCount($testPlace->getTable(), 1); - } - - /** @test */ - public function it_stores_geometry_collection_from_geo_json(): void - { - /** @var TestPlace $testPlace */ - $testPlace = TestPlace::factory()->create([ - 'geometry_collection' => GeometryCollection::fromJson('{"type":"GeometryCollection","geometries":[{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]},{"type":"Point","coordinates":[0,180]}]}'), - ]); - - $this->assertTrue($testPlace->geometry_collection instanceof GeometryCollection); - - /** @var Polygon $polygon */ - $polygon = $testPlace->geometry_collection[0]; - $lineString = $polygon[0]; - - $this->assertEquals(180, $lineString[0]->latitude); - $this->assertEquals(0, $lineString[0]->longitude); - $this->assertEquals(179, $lineString[1]->latitude); - $this->assertEquals(1, $lineString[1]->longitude); - $this->assertEquals(178, $lineString[2]->latitude); - $this->assertEquals(2, $lineString[2]->longitude); - $this->assertEquals(177, $lineString[3]->latitude); - $this->assertEquals(3, $lineString[3]->longitude); - $this->assertEquals(180, $lineString[4]->latitude); - $this->assertEquals(0, $lineString[4]->longitude); - - /** @var Point $point */ - $point = $testPlace->geometry_collection[1]; - - $this->assertEquals(180, $point->latitude); - $this->assertEquals(0, $point->longitude); - - $this->assertDatabaseCount($testPlace->getTable(), 1); - } - - /** @test */ - public function it_stores_geometry_collection_from_feature_collection_geo_json(): void - { - /** @var TestPlace $testPlace */ - $testPlace = TestPlace::factory()->create([ - 'geometry_collection' => GeometryCollection::fromJson('{"type":"FeatureCollection","features":[{"type":"Feature","properties":[],"geometry":{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]}},{"type":"Feature","properties":[],"geometry":{"type":"Point","coordinates":[0,180]}}]}'), - ]); - - $this->assertTrue($testPlace->geometry_collection instanceof GeometryCollection); - - /** @var Polygon $polygon */ - $polygon = $testPlace->geometry_collection[0]; - $lineString = $polygon[0]; - - $this->assertEquals(180, $lineString[0]->latitude); - $this->assertEquals(0, $lineString[0]->longitude); - $this->assertEquals(179, $lineString[1]->latitude); - $this->assertEquals(1, $lineString[1]->longitude); - $this->assertEquals(178, $lineString[2]->latitude); - $this->assertEquals(2, $lineString[2]->longitude); - $this->assertEquals(177, $lineString[3]->latitude); - $this->assertEquals(3, $lineString[3]->longitude); - $this->assertEquals(180, $lineString[4]->latitude); - $this->assertEquals(0, $lineString[4]->longitude); - - /** @var Point $point */ - $point = $testPlace->geometry_collection[1]; - - $this->assertEquals(180, $point->latitude); - $this->assertEquals(0, $point->longitude); - - $this->assertDatabaseCount($testPlace->getTable(), 1); - } - - /** @test */ - public function it_generates_geometry_collection_geo_json(): void - { - $geometryCollection = new GeometryCollection([ - new Polygon([ - new LineString([ - new Point(180, 0), - new Point(179, 1), - new Point(178, 2), - new Point(177, 3), - new Point(180, 0), - ]), + ]), + new Point(180, 0), + ]); + + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::factory()->create(['geometry_collection' => $geometryCollection]); + + expect($testPlace->geometry_collection)->toBeInstanceOf(GeometryCollection::class); + expect($testPlace->geometry_collection)->toEqual($geometryCollection); +}); + +it('creates geometry collection from JSON', function (): void { + $geometryCollection = new GeometryCollection([ + new Polygon([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + new Point(178, 2), + new Point(177, 3), + new Point(180, 0), ]), - new Point(180, 0), - ]); - - $this->assertEquals( - '{"type":"GeometryCollection","geometries":[{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]},{"type":"Point","coordinates":[0,180]}]}', - $geometryCollection->toJson() - ); - } - - /** @test */ - public function it_generates_geometry_collection_feature_collection_json(): void - { - $geometryCollection = new GeometryCollection([ - new Polygon([ - new LineString([ - new Point(180, 0), - new Point(179, 1), - new Point(178, 2), - new Point(177, 3), - new Point(180, 0), - ]), + ]), + new Point(180, 0), + ]); + + $geometryCollectionFromJson = GeometryCollection::fromJson('{"type":"GeometryCollection","geometries":[{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]},{"type":"Point","coordinates":[0,180]}]}'); + + expect($geometryCollectionFromJson)->toEqual($geometryCollection); +}); + +it('creates geometry collection from feature collection JSON', function (): void { + $geometryCollection = new GeometryCollection([ + new Polygon([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + new Point(178, 2), + new Point(177, 3), + new Point(180, 0), ]), - new Point(180, 0), - ]); + ]), + new Point(180, 0), + ]); + + $geometryCollectionFromFeatureCollectionJson = GeometryCollection::fromJson('{"type":"FeatureCollection","features":[{"type":"Feature","properties":[],"geometry":{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]}},{"type":"Feature","properties":[],"geometry":{"type":"Point","coordinates":[0,180]}}]}'); - $this->assertEquals( - '{"type":"FeatureCollection","features":[{"type":"Feature","properties":[],"geometry":{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]}},{"type":"Feature","properties":[],"geometry":{"type":"Point","coordinates":[0,180]}}]}', - $geometryCollection->toFeatureCollectionJson() - ); - } + expect($geometryCollectionFromFeatureCollectionJson)->toEqual($geometryCollection); +}); - /** @test */ - public function it_does_not_throw_exception_when_geometry_collection_has_0_geometries(): void - { - $geometryCollection = new GeometryCollection([]); +it('generates geometry collection JSON', function (): void { + $geometryCollection = new GeometryCollection([ + new Polygon([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + new Point(178, 2), + new Point(177, 3), + new Point(180, 0), + ]), + ]), + new Point(180, 0), + ]); - $this->assertCount(0, $geometryCollection->getGeometries()); - } + $json = $geometryCollection->toJson(); - /** @test */ - public function it_throws_exception_when_geometry_collection_has_composed_by_invalid_value(): void - { - $this->expectException(InvalidArgumentException::class); + $expectedJson = '{"type":"GeometryCollection","geometries":[{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]},{"type":"Point","coordinates":[0,180]}]}'; + expect($json)->toBe($expectedJson); +}); - // @phpstan-ignore-next-line - new GeometryCollection([ - 'invalid-value', - ]); - } - - /** @test */ - public function it_unsets_geometry_collection_item(): void - { - $geometryCollection = new GeometryCollection([ - new Polygon([ - new LineString([ - new Point(180, 0), - new Point(179, 1), - new Point(178, 2), - new Point(177, 3), - new Point(180, 0), - ]), +it('generates geometry collection feature collection JSON', function (): void { + $geometryCollection = new GeometryCollection([ + new Polygon([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + new Point(178, 2), + new Point(177, 3), + new Point(180, 0), ]), - new Point(180, 0), - ]); + ]), + new Point(180, 0), + ]); + + $featureCollectionJson = $geometryCollection->toFeatureCollectionJson(); - unset($geometryCollection[0]); + $expectedFeatureCollectionJson = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":[],"geometry":{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]}},{"type":"Feature","properties":[],"geometry":{"type":"Point","coordinates":[0,180]}}]}'; + expect($featureCollectionJson)->toBe($expectedFeatureCollectionJson); +}); - $this->assertInstanceOf(Point::class, $geometryCollection[0]); - $this->assertCount(1, $geometryCollection->getGeometries()); - } +it('does not throw exception when geometry collection has no geometries', function (): void { + $geometryCollection = new GeometryCollection([]); - /** @test */ - public function it_unsets_geometry_collection_item_below_minimum(): void - { - $this->expectException(InvalidArgumentException::class); + expect($geometryCollection->getGeometries())->toHaveCount(0); +}); - $polygon = new Polygon([ +it('unsets geometry collection item', function (): void { + $point = new Point(180, 0); + $geometryCollection = new GeometryCollection([ + new Polygon([ new LineString([ new Point(180, 0), new Point(179, 1), @@ -226,67 +125,58 @@ public function it_unsets_geometry_collection_item_below_minimum(): void new Point(177, 3), new Point(180, 0), ]), - ]); + ]), + $point, + ]); - unset($polygon[0]); - } - - /** @test */ - public function it_checks_if_geometry_collection_item_is_exists(): void - { - $geometryCollection = new GeometryCollection([ - new Polygon([ - new LineString([ - new Point(180, 0), - new Point(179, 1), - new Point(178, 2), - new Point(177, 3), - new Point(180, 0), - ]), - ]), - new Point(180, 0), - ]); - - $this->assertTrue(isset($geometryCollection[0])); - $this->assertTrue(isset($geometryCollection[1])); - $this->assertFalse(isset($geometryCollection[2])); - } - - /** @test */ - public function it_sets_valid_item_to_geometry_collection(): void - { - /** @var TestPlace $testPlace */ - $testPlace = TestPlace::factory()->create([ - 'polygon' => new Polygon([ - new LineString([ - new Point(180, 0), - new Point(179, 1), - new Point(178, 2), - new Point(177, 3), - new Point(180, 0), - ]), - ]), - ]); + unset($geometryCollection[0]); - $testPlace->polygon[1] = new LineString([ + expect($geometryCollection[0])->toBe($point); + expect($geometryCollection->getGeometries())->toHaveCount(1); +}); + +it('throws exception when unsetting geometry collection item below minimum', function (): void { + $polygon = new Polygon([ + new LineString([ new Point(180, 0), new Point(179, 1), new Point(178, 2), new Point(177, 3), new Point(180, 0), - ]); - - $testPlace->save(); + ]), + ]); - $this->assertInstanceOf(LineString::class, $testPlace->polygon[1]); - } - - /** @test */ - public function it_sets_invalid_item_to_geometry_collection(): void - { - $this->expectException(InvalidArgumentException::class); + expect(function () use ($polygon): void { + unset($polygon[0]); + })->toThrow(InvalidArgumentException::class); +}); - $polygon = new Polygon([ +it('checks if geometry collection item is exists', function (): void { + $geometryCollection = new GeometryCollection([ + new Polygon([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + new Point(178, 2), + new Point(177, 3), + new Point(180, 0), + ]), + ]), + new Point(180, 0), + ]); + + $firstItemExists = isset($geometryCollection[0]); + $secondItemExists = isset($geometryCollection[1]); + $thirdItemExists = isset($geometryCollection[2]); + + expect($firstItemExists)->toBeTrue(); + expect($secondItemExists)->toBeTrue(); + expect($thirdItemExists)->toBeFalse(); +}); + +it('sets item to geometry collection', function (): void { + $geometryCollection = new GeometryCollection([ + new Polygon([ new LineString([ new Point(180, 0), new Point(179, 1), @@ -294,9 +184,32 @@ public function it_sets_invalid_item_to_geometry_collection(): void new Point(177, 3), new Point(180, 0), ]), - ]); + ]), + new Point(180, 0), + ]); + $lineString = new LineString([ + new Point(180, 0), + new Point(179, 1), + ]); + + $geometryCollection[2] = $lineString; + + expect($geometryCollection[2])->toBe($lineString); +}); + +it('throws exception when setting invalid item to geometry collection', function (): void { + $polygon = new Polygon([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + new Point(178, 2), + new Point(177, 3), + new Point(180, 0), + ]), + ]); + expect(function () use ($polygon): void { // @phpstan-ignore-next-line $polygon[1] = new Point(180, 0); - } -} + })->toThrow(InvalidArgumentException::class); +}); diff --git a/tests/Objects/LineStringTest.php b/tests/Objects/LineStringTest.php index 01d3444..7981c33 100644 --- a/tests/Objects/LineStringTest.php +++ b/tests/Objects/LineStringTest.php @@ -1,98 +1,74 @@ create([ - 'line_string' => new LineString([ - new Point(180, 0), - new Point(179, 1), - ]), - ]); +uses(DatabaseMigrations::class); - $this->assertTrue($testPlace->line_string instanceof LineString); +it('creates a model record with line string', function (): void { + $lineString = new LineString([ + new Point(180, 0), + new Point(179, 1), + ]); - $this->assertEquals(180, $testPlace->line_string[0]->latitude); - $this->assertEquals(0, $testPlace->line_string[0]->longitude); - $this->assertEquals(179, $testPlace->line_string[1]->latitude); - $this->assertEquals(1, $testPlace->line_string[1]->longitude); + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::factory()->create(['line_string' => $lineString]); - $this->assertDatabaseCount($testPlace->getTable(), 1); - } + expect($testPlace->line_string)->toBeInstanceOf(LineString::class); + expect($testPlace->line_string)->toEqual($lineString); +}); - /** @test */ - public function it_stores_line_string_from_json(): void - { - /** @var TestPlace $testPlace */ - $testPlace = TestPlace::factory()->create([ - 'line_string' => LineString::fromJson('{"type":"LineString","coordinates":[[0,180],[1,179]]}'), - ]); +it('creates line string from JSON', function (): void { + $lineString = new LineString([ + new Point(180, 0), + new Point(179, 1), + ]); - $this->assertTrue($testPlace->line_string instanceof LineString); + $lineStringFromJson = LineString::fromJson('{"type":"LineString","coordinates":[[0,180],[1,179]]}'); - $this->assertEquals(180, $testPlace->line_string[0]->latitude); - $this->assertEquals(0, $testPlace->line_string[0]->longitude); - $this->assertEquals(179, $testPlace->line_string[1]->latitude); - $this->assertEquals(1, $testPlace->line_string[1]->longitude); + expect($lineStringFromJson)->toEqual($lineString); +}); - $this->assertDatabaseCount($testPlace->getTable(), 1); - } +it('generates line string JSON', function (): void { + $lineString = new LineString([ + new Point(180, 0), + new Point(179, 1), + ]); - /** @test */ - public function it_generates_line_string_geo_json(): void - { - $lineString = new LineString([ - new Point(180, 0), - new Point(179, 1), - ]); + $json = $lineString->toJson(); - $this->assertEquals('{"type":"LineString","coordinates":[[0,180],[1,179]]}', $lineString->toJson()); - } + $expectedJson = '{"type":"LineString","coordinates":[[0,180],[1,179]]}'; + expect($json)->toBe($expectedJson); +}); - /** @test */ - public function it_generates_line_string_feature_collection_json(): void - { - $lineString = new LineString([ - new Point(180, 0), - new Point(179, 1), - ]); +it('generates line string feature collection JSON', function (): void { + $lineString = new LineString([ + new Point(180, 0), + new Point(179, 1), + ]); - $this->assertEquals('{"type":"FeatureCollection","features":[{"type":"Feature","properties":[],"geometry":{"type":"LineString","coordinates":[[0,180],[1,179]]}}]}', $lineString->toFeatureCollectionJson()); - } + $featureCollectionJson = $lineString->toFeatureCollectionJson(); - /** @test */ - public function it_throws_exception_when_line_string_has_less_than_2_points(): void - { - $this->expectException(InvalidArgumentException::class); + $expectedFeatureCollectionJson = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":[],"geometry":{"type":"LineString","coordinates":[[0,180],[1,179]]}}]}'; + expect($featureCollectionJson)->toBe($expectedFeatureCollectionJson); +}); +it('throws exception when line string has less than two points', function (): void { + expect(function (): void { new LineString([ new Point(180, 0), ]); - } - - /** @test */ - public function it_throws_exception_when_line_string_has_composed_by_polygon(): void - { - $this->expectException(InvalidArgumentException::class); + })->toThrow(InvalidArgumentException::class); +}); +it('throws exception when creating line string from incorrect geometry', function (): void { + expect(function (): void { // @phpstan-ignore-next-line new LineString([ Polygon::fromJson('{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]}'), ]); - } -} + })->toThrow(InvalidArgumentException::class); +}); diff --git a/tests/Objects/MultiLineStringTest.php b/tests/Objects/MultiLineStringTest.php index 7719afb..6767163 100644 --- a/tests/Objects/MultiLineStringTest.php +++ b/tests/Objects/MultiLineStringTest.php @@ -1,106 +1,80 @@ create([ - 'multi_line_string' => new MultiLineString([ - new LineString([ - new Point(180, 0), - new Point(179, 1), - ]), - ]), - ]); - - $this->assertTrue($testPlace->multi_line_string instanceof MultiLineString); - - $lineString = $testPlace->multi_line_string[0]; - - $this->assertEquals(180, $lineString[0]->latitude); - $this->assertEquals(0, $lineString[0]->longitude); - $this->assertEquals(179, $lineString[1]->latitude); - $this->assertEquals(1, $lineString[1]->longitude); - - $this->assertDatabaseCount($testPlace->getTable(), 1); - } - - /** @test */ - public function it_stores_multi_line_string_from_geo_json(): void - { - /** @var TestPlace $testPlace */ - $testPlace = TestPlace::factory()->create([ - 'multi_line_string' => MultiLineString::fromJson('{"type":"MultiLineString","coordinates":[[[0,180],[1,179]]]}'), - ]); - - $this->assertTrue($testPlace->multi_line_string instanceof MultiLineString); - - $lineString = $testPlace->multi_line_string[0]; - - $this->assertEquals(180, $lineString[0]->latitude); - $this->assertEquals(0, $lineString[0]->longitude); - $this->assertEquals(179, $lineString[1]->latitude); - $this->assertEquals(1, $lineString[1]->longitude); - - $this->assertDatabaseCount($testPlace->getTable(), 1); - } - - /** @test */ - public function it_generates_multi_line_string_geo_json(): void - { - $multiLineString = new MultiLineString([ - new LineString([ - new Point(180, 0), - new Point(179, 1), - ]), - ]); - - $this->assertEquals('{"type":"MultiLineString","coordinates":[[[0,180],[1,179]]]}', $multiLineString->toJson()); - } - - /** @test */ - public function it_generates_multi_line_string_feature_collection_json(): void - { - $multiLineString = new MultiLineString([ - new LineString([ - new Point(180, 0), - new Point(179, 1), - ]), - ]); - - $this->assertEquals('{"type":"FeatureCollection","features":[{"type":"Feature","properties":[],"geometry":{"type":"MultiLineString","coordinates":[[[0,180],[1,179]]]}}]}', $multiLineString->toFeatureCollectionJson()); - } - - /** @test */ - public function it_throws_exception_when_multi_line_string_has_0_line_strings(): void - { - $this->expectException(InvalidArgumentException::class); - +uses(DatabaseMigrations::class); + +it('creates a model record with multi line string', function (): void { + $multiLineString = new MultiLineString([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + ]), + ]); + + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::factory()->create(['multi_line_string' => $multiLineString]); + + expect($testPlace->multi_line_string)->toBeInstanceOf(MultiLineString::class); + expect($testPlace->multi_line_string)->toEqual($multiLineString); +}); + +it('creates multi line string from JSON', function (): void { + $multiLineString = new MultiLineString([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + ]), + ]); + + $multiLineStringFromJson = MultiLineString::fromJson('{"type":"MultiLineString","coordinates":[[[0,180],[1,179]]]}'); + + expect($multiLineStringFromJson)->toEqual($multiLineString); +}); + +it('generates multi line string JSON', function (): void { + $multiLineString = new MultiLineString([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + ]), + ]); + + $json = $multiLineString->toJson(); + + $expectedJson = '{"type":"MultiLineString","coordinates":[[[0,180],[1,179]]]}'; + expect($json)->toBe($expectedJson); +}); + +it('generates multi line string feature collection JSON', function (): void { + $multiLineString = new MultiLineString([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + ]), + ]); + + $featureCollectionJson = $multiLineString->toFeatureCollectionJson(); + + $expectedFeatureCollectionJson = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":[],"geometry":{"type":"MultiLineString","coordinates":[[[0,180],[1,179]]]}}]}'; + expect($featureCollectionJson)->toBe($expectedFeatureCollectionJson); +}); + +it('throws exception when multi line string has no line strings', function (): void { + expect(function (): void { new MultiLineString([]); - } - - /** @test */ - public function it_throws_exception_when_multi_line_string_has_composed_by_point(): void - { - $this->expectException(InvalidArgumentException::class); + })->toThrow(InvalidArgumentException::class); +}); +it('throws exception when creating multi line string from incorrect geometry', function (): void { + expect(function (): void { // @phpstan-ignore-next-line new MultiLineString([ new Point(0, 0), ]); - } -} + })->toThrow(InvalidArgumentException::class); +}); diff --git a/tests/Objects/MultiPointTest.php b/tests/Objects/MultiPointTest.php index 81e7e3b..7e748da 100644 --- a/tests/Objects/MultiPointTest.php +++ b/tests/Objects/MultiPointTest.php @@ -1,90 +1,68 @@ create([ - 'multi_point' => new MultiPoint([ - new Point(180, 0), - ]), - ]); +uses(DatabaseMigrations::class); - $this->assertTrue($testPlace->multi_point instanceof MultiPoint); +it('creates a model record with multi point', function (): void { + $multiPoint = new MultiPoint([ + new Point(180, 0), + ]); - $this->assertEquals(180, $testPlace->multi_point[0]->latitude); - $this->assertEquals(0, $testPlace->multi_point[0]->longitude); + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::factory()->create(['multi_point' => $multiPoint]); - $this->assertDatabaseCount($testPlace->getTable(), 1); - } + expect($testPlace->multi_point)->toBeInstanceOf(MultiPoint::class); + expect($testPlace->multi_point)->toEqual($multiPoint); +}); - /** @test */ - public function it_stores_multi_point_from_json(): void - { - /** @var TestPlace $testPlace */ - $testPlace = TestPlace::factory()->create([ - 'multi_point' => MultiPoint::fromJson('{"type":"MultiPoint","coordinates":[[0,180]]}'), - ]); +it('creates multi point from JSON', function (): void { + $multiPoint = new MultiPoint([ + new Point(180, 0), + ]); - $this->assertTrue($testPlace->multi_point instanceof MultiPoint); + $multiPointFromJson = MultiPoint::fromJson('{"type":"MultiPoint","coordinates":[[0,180]]}'); - $this->assertEquals(180, $testPlace->multi_point[0]->latitude); - $this->assertEquals(0, $testPlace->multi_point[0]->longitude); + expect($multiPointFromJson)->toEqual($multiPoint); +}); - $this->assertDatabaseCount($testPlace->getTable(), 1); - } +it('generates multi point JSON', function (): void { + $multiPoint = new MultiPoint([ + new Point(180, 0), + ]); - /** @test */ - public function it_generates_multi_point_geo_json(): void - { - $multiPoint = new MultiPoint([ - new Point(180, 0), - ]); + $json = $multiPoint->toJson(); - $this->assertEquals('{"type":"MultiPoint","coordinates":[[0,180]]}', $multiPoint->toJson()); - } + $expectedJson = '{"type":"MultiPoint","coordinates":[[0,180]]}'; + expect($json)->toBe($expectedJson); +}); - /** @test */ - public function it_generates_multi_point_feature_collection_json(): void - { - $multiPoint = new MultiPoint([ - new Point(180, 0), - ]); +it('generates multi point feature collection JSON', function (): void { + $multiPoint = new MultiPoint([ + new Point(180, 0), + ]); - $this->assertEquals('{"type":"FeatureCollection","features":[{"type":"Feature","properties":[],"geometry":{"type":"MultiPoint","coordinates":[[0,180]]}}]}', $multiPoint->toFeatureCollectionJson()); - } + $multiPointFeatureCollectionJson = $multiPoint->toFeatureCollectionJson(); - /** @test */ - public function it_throws_exception_when_multi_point_has_0_points(): void - { - $this->expectException(InvalidArgumentException::class); + $expectedFeatureCollectionJson = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":[],"geometry":{"type":"MultiPoint","coordinates":[[0,180]]}}]}'; + expect($multiPointFeatureCollectionJson)->toBe($expectedFeatureCollectionJson); +}); +it('throws exception when multi point has no points', function (): void { + expect(function (): void { new MultiPoint([]); - } - - /** @test */ - public function it_throws_exception_when_multi_point_has_composed_by_polygon(): void - { - $this->expectException(InvalidArgumentException::class); + })->toThrow(InvalidArgumentException::class); +}); +it('throws exception when creating multi point from incorrect geometry', function (): void { + expect(function (): void { // @phpstan-ignore-next-line - new MultiLineString([ + new MultiPoint([ Polygon::fromJson('{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]}'), ]); - } -} + })->toThrow(InvalidArgumentException::class); +}); diff --git a/tests/Objects/MultiPolygonTest.php b/tests/Objects/MultiPolygonTest.php index 36768ff..a1d666e 100644 --- a/tests/Objects/MultiPolygonTest.php +++ b/tests/Objects/MultiPolygonTest.php @@ -1,134 +1,101 @@ create([ - 'multi_polygon' => new MultiPolygon([ - new Polygon([ - new LineString([ - new Point(180, 0), - new Point(179, 1), - new Point(178, 2), - new Point(177, 3), - new Point(180, 0), - ]), - ]), +uses(DatabaseMigrations::class); + +it('creates a model record with multi polygon', function (): void { + $multiPolygon = new MultiPolygon([ + new Polygon([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + new Point(178, 2), + new Point(177, 3), + new Point(180, 0), ]), - ]); - - $this->assertTrue($testPlace->multi_polygon instanceof MultiPolygon); - - $lineString = $testPlace->multi_polygon[0][0]; - - $this->assertEquals(180, $lineString[0]->latitude); - $this->assertEquals(0, $lineString[0]->longitude); - $this->assertEquals(179, $lineString[1]->latitude); - $this->assertEquals(1, $lineString[1]->longitude); - $this->assertEquals(178, $lineString[2]->latitude); - $this->assertEquals(2, $lineString[2]->longitude); - $this->assertEquals(177, $lineString[3]->latitude); - $this->assertEquals(3, $lineString[3]->longitude); - $this->assertEquals(180, $lineString[4]->latitude); - $this->assertEquals(0, $lineString[4]->longitude); - - $this->assertDatabaseCount($testPlace->getTable(), 1); - } - - /** @test */ - public function it_stores_multi_polygon_from_geo_json(): void - { - /** @var TestPlace $testPlace */ - $testPlace = TestPlace::factory()->create([ - 'multi_polygon' => MultiPolygon::fromJson('{"type":"MultiPolygon","coordinates":[[[[0,180],[1,179],[2,178],[3,177],[0,180]]]]}'), - ]); - - $this->assertTrue($testPlace->multi_polygon instanceof MultiPolygon); - - $lineString = $testPlace->multi_polygon[0][0]; - - $this->assertEquals(180, $lineString[0]->latitude); - $this->assertEquals(0, $lineString[0]->longitude); - $this->assertEquals(179, $lineString[1]->latitude); - $this->assertEquals(1, $lineString[1]->longitude); - $this->assertEquals(178, $lineString[2]->latitude); - $this->assertEquals(2, $lineString[2]->longitude); - $this->assertEquals(177, $lineString[3]->latitude); - $this->assertEquals(3, $lineString[3]->longitude); - $this->assertEquals(180, $lineString[4]->latitude); - $this->assertEquals(0, $lineString[4]->longitude); - - $this->assertDatabaseCount($testPlace->getTable(), 1); - } - - /** @test */ - public function it_generates_multi_polygon_geo_json(): void - { - $multiPolygon = new MultiPolygon([ - new Polygon([ - new LineString([ - new Point(180, 0), - new Point(179, 1), - new Point(178, 2), - new Point(177, 3), - new Point(180, 0), - ]), + ]), + ]); + + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::factory()->create(['multi_polygon' => $multiPolygon]); + + expect($testPlace->multi_polygon)->toBeInstanceOf(MultiPolygon::class); + expect($testPlace->multi_polygon)->toEqual($multiPolygon); +}); + +it('creates multi polygon from JSON', function (): void { + $multiPolygon = new MultiPolygon([ + new Polygon([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + new Point(178, 2), + new Point(177, 3), + new Point(180, 0), ]), - ]); - - $this->assertEquals('{"type":"MultiPolygon","coordinates":[[[[0,180],[1,179],[2,178],[3,177],[0,180]]]]}', $multiPolygon->toJson()); - } - - /** @test */ - public function it_generates_multi_polygon_feature_collection_json(): void - { - $multiPolygon = new MultiPolygon([ - new Polygon([ - new LineString([ - new Point(180, 0), - new Point(179, 1), - new Point(178, 2), - new Point(177, 3), - new Point(180, 0), - ]), + ]), + ]); + + $multiPolygonFromJson = MultiPolygon::fromJson('{"type":"MultiPolygon","coordinates":[[[[0,180],[1,179],[2,178],[3,177],[0,180]]]]}'); + + expect($multiPolygonFromJson)->toEqual($multiPolygon); +}); + +it('generates multi polygon JSON', function (): void { + $multiPolygon = new MultiPolygon([ + new Polygon([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + new Point(178, 2), + new Point(177, 3), + new Point(180, 0), ]), - ]); + ]), + ]); + + $json = $multiPolygon->toJson(); + + $expectedJson = '{"type":"MultiPolygon","coordinates":[[[[0,180],[1,179],[2,178],[3,177],[0,180]]]]}'; + expect($json)->toBe($expectedJson); +}); + +it('generates multi polygon feature collection JSON', function (): void { + $multiPolygon = new MultiPolygon([ + new Polygon([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + new Point(178, 2), + new Point(177, 3), + new Point(180, 0), + ]), + ]), + ]); - $this->assertEquals('{"type":"FeatureCollection","features":[{"type":"Feature","properties":[],"geometry":{"type":"MultiPolygon","coordinates":[[[[0,180],[1,179],[2,178],[3,177],[0,180]]]]}}]}', $multiPolygon->toFeatureCollectionJson()); - } + $featureCollectionJson = $multiPolygon->toFeatureCollectionJson(); - /** @test */ - public function it_throws_exception_when_multi_polygon_has_0_polygons(): void - { - $this->expectException(InvalidArgumentException::class); + $expectedFeatureCollectionJson = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":[],"geometry":{"type":"MultiPolygon","coordinates":[[[[0,180],[1,179],[2,178],[3,177],[0,180]]]]}}]}'; + expect($featureCollectionJson)->toBe($expectedFeatureCollectionJson); +}); +it('throws exception when multi polygon has no polygons', function (): void { + expect(function (): void { new MultiPolygon([]); - } - - /** @test */ - public function it_throws_exception_when_multi_polygon_has_composed_by_point(): void - { - $this->expectException(InvalidArgumentException::class); + })->toThrow(InvalidArgumentException::class); +}); +it('throws exception when creating multi polygon from incorrect geometry', function (): void { + expect(function (): void { // @phpstan-ignore-next-line new MultiPolygon([ new Point(0, 0), ]); - } -} + })->toThrow(InvalidArgumentException::class); +}); diff --git a/tests/Objects/PointTest.php b/tests/Objects/PointTest.php index f605ec5..4b3c716 100644 --- a/tests/Objects/PointTest.php +++ b/tests/Objects/PointTest.php @@ -14,7 +14,6 @@ expect($testPlace->point)->toBeInstanceOf(Point::class); expect($testPlace->point)->toEqual($point); - expect($testPlace->count())->toBe(1); }); it('creates point from JSON', function (): void { @@ -28,11 +27,14 @@ it('generates point json', function (): void { $point = new Point(180, 0); - expect($point->toJson())->toBe('{"type":"Point","coordinates":[0,180]}'); + $json = $point->toJson(); + + $expectedJson = '{"type":"Point","coordinates":[0,180]}'; + expect($json)->toBe($expectedJson); }); it('throws exception when creating point from invalid JSON', function (): void { - $this->expectException(InvalidArgumentException::class); - - Point::fromJson('{"type":"Point","coordinates":[]}'); + expect(function (): void { + Point::fromJson('{"type":"Point","coordinates":[]}'); + })->toThrow(InvalidArgumentException::class); }); diff --git a/tests/Objects/PolygonTest.php b/tests/Objects/PolygonTest.php index b4918f2..9b910d6 100644 --- a/tests/Objects/PolygonTest.php +++ b/tests/Objects/PolygonTest.php @@ -1,127 +1,92 @@ create([ - 'polygon' => new Polygon([ - new LineString([ - new Point(180, 0), - new Point(179, 1), - new Point(178, 2), - new Point(177, 3), - new Point(180, 0), - ]), - ]), - ]); - - $this->assertTrue($testPlace->polygon instanceof Polygon); - - $lineString = $testPlace->polygon[0]; - - $this->assertEquals(180, $lineString[0]->latitude); - $this->assertEquals(0, $lineString[0]->longitude); - $this->assertEquals(179, $lineString[1]->latitude); - $this->assertEquals(1, $lineString[1]->longitude); - $this->assertEquals(178, $lineString[2]->latitude); - $this->assertEquals(2, $lineString[2]->longitude); - $this->assertEquals(177, $lineString[3]->latitude); - $this->assertEquals(3, $lineString[3]->longitude); - $this->assertEquals(180, $lineString[4]->latitude); - $this->assertEquals(0, $lineString[4]->longitude); - - $this->assertDatabaseCount($testPlace->getTable(), 1); - } - - /** @test */ - public function it_stores_polygon_from_geo_json(): void - { - /** @var TestPlace $testPlace */ - $testPlace = TestPlace::factory()->create([ - 'polygon' => Polygon::fromJson('{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]}'), - ]); - - $this->assertTrue($testPlace->polygon instanceof Polygon); - - $lineString = $testPlace->polygon[0]; - - $this->assertEquals(180, $lineString[0]->latitude); - $this->assertEquals(0, $lineString[0]->longitude); - $this->assertEquals(179, $lineString[1]->latitude); - $this->assertEquals(1, $lineString[1]->longitude); - $this->assertEquals(178, $lineString[2]->latitude); - $this->assertEquals(2, $lineString[2]->longitude); - $this->assertEquals(177, $lineString[3]->latitude); - $this->assertEquals(3, $lineString[3]->longitude); - $this->assertEquals(180, $lineString[4]->latitude); - $this->assertEquals(0, $lineString[4]->longitude); - - $this->assertDatabaseCount($testPlace->getTable(), 1); - } - - /** @test */ - public function it_generates_polygon_geo_json(): void - { - $polygon = new Polygon([ - new LineString([ - new Point(180, 0), - new Point(179, 1), - new Point(178, 2), - new Point(177, 3), - new Point(180, 0), - ]), - ]); - - $this->assertEquals('{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]}', $polygon->toJson()); - } - - /** @test */ - public function it_generates_polygon_feature_collection_json(): void - { - $polygon = new Polygon([ - new LineString([ - new Point(180, 0), - new Point(179, 1), - new Point(178, 2), - new Point(177, 3), - new Point(180, 0), - ]), - ]); - - $this->assertEquals('{"type":"FeatureCollection","features":[{"type":"Feature","properties":[],"geometry":{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]}}]}', $polygon->toFeatureCollectionJson()); - } - - /** @test */ - public function it_throws_exception_when_polygon_has_0_line_strings(): void - { - $this->expectException(InvalidArgumentException::class); - +uses(DatabaseMigrations::class); + +it('creates a model record with polygon', function (): void { + $polygon = new Polygon([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + new Point(178, 2), + new Point(177, 3), + new Point(180, 0), + ]), + ]); + + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::factory()->create(['polygon' => $polygon]); + + expect($testPlace->polygon)->toBeInstanceOf(Polygon::class); + expect($testPlace->polygon)->toEqual($polygon); +}); + +it('creates polygon from JSON', function (): void { + $polygon = new Polygon([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + new Point(178, 2), + new Point(177, 3), + new Point(180, 0), + ]), + ]); + + $polygonFromJson = Polygon::fromJson('{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]}'); + + expect($polygonFromJson)->toEqual($polygon); +}); + +it('generates polygon JSON', function (): void { + $polygon = new Polygon([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + new Point(178, 2), + new Point(177, 3), + new Point(180, 0), + ]), + ]); + + $json = $polygon->toJson(); + + $expectedJson = '{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]}'; + expect($json)->toBe($expectedJson); +}); + +it('generates polygon feature collection JSON', function (): void { + $polygon = new Polygon([ + new LineString([ + new Point(180, 0), + new Point(179, 1), + new Point(178, 2), + new Point(177, 3), + new Point(180, 0), + ]), + ]); + + $featureCollectionJson = $polygon->toFeatureCollectionJson(); + + $expectedFeatureCollectionJson = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":[],"geometry":{"type":"Polygon","coordinates":[[[0,180],[1,179],[2,178],[3,177],[0,180]]]}}]}'; + expect($featureCollectionJson)->toBe($expectedFeatureCollectionJson); +}); + +it('throws exception when polygon has no line strings', function (): void { + expect(function (): void { new Polygon([]); - } - - /** @test */ - public function it_throws_exception_when_polygon_has_composed_by_point(): void - { - $this->expectException(InvalidArgumentException::class); + })->toThrow(InvalidArgumentException::class); +}); +it('throws exception when creating polygon from incorrect geometry', function (): void { + expect(function (): void { // @phpstan-ignore-next-line new Polygon([ new Point(0, 0), ]); - } -} + })->toThrow(InvalidArgumentException::class); +});