From 53c0142cad57a42ff7be999701e03269807b07eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Turan=20Karatu=C4=9F?= Date: Wed, 14 May 2025 17:01:00 +0300 Subject: [PATCH 1/3] feat(LocationCast): add expression support to get method --- src/Casts/LocationCast.php | 20 +++++++++++++++++++- tests/LocationCastTest.php | 32 ++++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/Casts/LocationCast.php b/src/Casts/LocationCast.php index 65bbf22..65feb31 100644 --- a/src/Casts/LocationCast.php +++ b/src/Casts/LocationCast.php @@ -19,7 +19,7 @@ public function get($model, string $key, $value, array $attributes): ?Point return null; } - $coordinates = explode(',', $value); + $coordinates = $this->getCoordinates($model, $value); if (count($coordinates) > 1) { $location = explode(',', str_replace(['POINT(', ')', ' '], ['', '', ','], $coordinates[0])); @@ -51,4 +51,22 @@ public function serialize($model, string $key, $value, array $attributes): array { return $value->toArray(); } + + private function getCoordinates($model, $value): array + { + if ($value instanceof Expression) { + preg_match( + pattern: "/ST_GeomFromText\(\s*'([^']+)'\s*(?:,\s*(\d+))?\s*(?:,\s*'([^']+)')?\s*\)/", + subject: (string) $value->getValue($model->getConnection()->getQueryGrammar()), + matches: $matches, + ); + + return [ + $matches[1], + (int) ($matches[2] ?? 0), + ]; + } + + return explode(',', $value); + } } diff --git a/tests/LocationCastTest.php b/tests/LocationCastTest.php index 3c440f0..5028324 100644 --- a/tests/LocationCastTest.php +++ b/tests/LocationCastTest.php @@ -2,15 +2,17 @@ namespace TarfinLabs\LaravelSpatial\Tests; +use Illuminate\Database\Query\Expression; use InvalidArgumentException; use Illuminate\Support\Facades\DB; +use PHPUnit\Framework\Attributes\Test; use TarfinLabs\LaravelSpatial\Casts\LocationCast; use TarfinLabs\LaravelSpatial\Tests\TestModels\Address; use TarfinLabs\LaravelSpatial\Types\Point; class LocationCastTest extends TestCase { - /** @test */ + #[Test] public function it_throws_an_exception_if_casted_attribute_set_to_a_non_point_value(): void { // 1. Arrange @@ -23,7 +25,7 @@ public function it_throws_an_exception_if_casted_attribute_set_to_a_non_point_va $address->location = 'dummy'; } - /** @test */ + #[Test] public function it_can_set_the_casted_attribute_to_a_point(): void { // 1. Arrange @@ -39,7 +41,7 @@ public function it_can_set_the_casted_attribute_to_a_point(): void $this->assertEquals(DB::raw("ST_GeomFromText('{$point->toWkt()}', 4326, 'axis-order=long-lat')"), $response); } - /** @test */ + #[Test] public function it_can_set_the_casted_attribute_to_a_point_with_srid(): void { // 1. Arrange @@ -55,7 +57,7 @@ public function it_can_set_the_casted_attribute_to_a_point_with_srid(): void $this->assertEquals(DB::raw("ST_GeomFromText('{$point->toWkt()}', {$point->getSrid()}, 'axis-order=long-lat')"), $response); } - /** @test */ + #[Test] public function it_can_get_a_casted_attribute(): void { // 1. Arrange @@ -73,7 +75,25 @@ public function it_can_get_a_casted_attribute(): void $this->assertEquals($point->getSrid(), $address->location->getSrid()); } - /** @test */ + #[Test] + public function it_can_get_a_casted_attribute_using_expression(): void + { + // 1. Arrange + $address = new Address(); + $point = new Point(27.1234, 39.1234); + + // 2. Act + $cast = new LocationCast(); + $result = $cast->get($address, 'location', new Expression($point->toGeomFromText()), $address->getAttributes()); + + // 3. Assert + $this->assertInstanceOf(Point::class, $result); + $this->assertEquals($point->getLat(), $result->getLat()); + $this->assertEquals($point->getLng(), $result->getLng()); + $this->assertEquals($point->getSrid(), $result->getSrid()); + } + + #[Test] public function it_returns_null_if_the_value_of_the_casted_column_is_null(): void { // 1. Arrange @@ -86,7 +106,7 @@ public function it_returns_null_if_the_value_of_the_casted_column_is_null(): voi $this->assertNull($address->location); } - /** @test */ + #[Test] public function it_can_serialize_a_casted_attribute(): void { // 1. Arrange From fd263cd8bcb4a6ffdea731e23a8ab239fd2960d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Turan=20Karatu=C4=9F?= Date: Wed, 14 May 2025 17:01:26 +0300 Subject: [PATCH 2/3] refactor(tests): replace `@test` annotations with `#[Test]` attributes across the test suite for modern PHPUnit syntax --- tests/HasSpatialTest.php | 11 ++++++----- tests/PointTest.php | 18 ++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/tests/HasSpatialTest.php b/tests/HasSpatialTest.php index 8849fb5..f5ba743 100644 --- a/tests/HasSpatialTest.php +++ b/tests/HasSpatialTest.php @@ -2,12 +2,13 @@ namespace TarfinLabs\LaravelSpatial\Tests; +use PHPUnit\Framework\Attributes\Test; use TarfinLabs\LaravelSpatial\Tests\TestModels\Address; use TarfinLabs\LaravelSpatial\Types\Point; class HasSpatialTest extends TestCase { - /** @test */ + #[Test] public function it_generates_sql_query_for_selectDistanceTo_scope(): void { // Arrange @@ -24,7 +25,7 @@ public function it_generates_sql_query_for_selectDistanceTo_scope(): void ); } - /** @test */ + #[Test] public function it_generates_sql_query_for_withinDistanceTo_scope(): void { // 1. Arrange @@ -41,7 +42,7 @@ public function it_generates_sql_query_for_withinDistanceTo_scope(): void ); } - /** @test */ + #[Test] public function it_generates_sql_query_for_orderByDistanceTo_scope(): void { // 1. Arrange @@ -64,7 +65,7 @@ public function it_generates_sql_query_for_orderByDistanceTo_scope(): void ); } - /** @test */ + #[Test] public function it_generates_sql_query_for_location_casted_attributes(): void { // 1. Arrange @@ -78,7 +79,7 @@ public function it_generates_sql_query_for_location_casted_attributes(): void ); } - /** @test */ + #[Test] public function it_returns_location_casted_attributes(): void { // 1. Arrange diff --git a/tests/PointTest.php b/tests/PointTest.php index e5da194..7067b47 100644 --- a/tests/PointTest.php +++ b/tests/PointTest.php @@ -5,11 +5,12 @@ namespace TarfinLabs\LaravelSpatial\Tests; use Illuminate\Support\Facades\Config; +use PHPUnit\Framework\Attributes\Test; use TarfinLabs\LaravelSpatial\Types\Point; class PointTest extends TestCase { - /** @test */ + #[Test] public function it_sets_lat_lng_and_srid_in_constructor(): void { // 1. Arrange @@ -26,7 +27,7 @@ public function it_sets_lat_lng_and_srid_in_constructor(): void $this->assertSame(expected: $srid, actual: $point->getSrid()); } - /** @test */ + #[Test] public function it_returns_default_lat_lng_and_srid_if_they_are_not_given_in_the_constructor(): void { // 1. Act @@ -38,7 +39,7 @@ public function it_returns_default_lat_lng_and_srid_if_they_are_not_given_in_the $this->assertSame(expected: 4326, actual: $point->getSrid()); } - /** @test */ + #[Test] public function it_returns_default_srid_in_config_if_it_is_not_null(): void { // 1. Arrange @@ -53,7 +54,7 @@ public function it_returns_default_srid_in_config_if_it_is_not_null(): void $this->assertSame(expected: 4326, actual: $point->getSrid()); } - /** @test */ + #[Test] public function it_returns_point_as_wkt(): void { // 1. Arrange @@ -66,7 +67,7 @@ public function it_returns_point_as_wkt(): void $this->assertSame("POINT({$point->getLng()} {$point->getLat()})", $wkt); } - /** @test */ + #[Test] public function it_returns_point_as_pair(): void { // 1. Arrange @@ -79,10 +80,7 @@ public function it_returns_point_as_pair(): void $this->assertSame("{$point->getLng()} {$point->getLat()}", $pair); } - /** - * @test - * @see - */ + #[Test] public function it_returns_points_as_geometry(): void { // 1. Arrange @@ -95,7 +93,7 @@ public function it_returns_points_as_geometry(): void $this->assertSame("ST_GeomFromText('{$point->toWkt()}', {$point->getSrid()}, 'axis-order=long-lat')", $geometry); } - /** @test */ + #[Test] public function it_returns_points_as_array(): void { // 1. Arrange From 34175a5721756cb4028f8915a8e6353ed83b7525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Turan=20Karatu=C4=9F?= Date: Wed, 14 May 2025 17:01:56 +0300 Subject: [PATCH 3/3] docs(changelog): add changelog entries for 3.0.1 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93b1b91..fb8e5eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to `laravel-spatial` will be documented in this file +## 3.0.1 - 2025-05-14 +- Expression support added to `get()` method in `LocationCast`. +- Replaced `@test` annotations with `#[Test]` attributes across the test suite for modern PHPUnit syntax. + ## 3.0.0 - 2025-02-20 - Laravel 12 and PHP 8.4 support added. - Laravel 10 and below versions are not supported anymore.