Skip to content

Commit a3241f6

Browse files
committed
Adds a test to ensure an exception is thrown when attempting to use eager-loading on unsupported Laravel versions
1 parent d590cb5 commit a3241f6

File tree

4 files changed

+176
-0
lines changed

4 files changed

+176
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Parental\Exceptions;
4+
5+
use RuntimeException;
6+
7+
class EagerLoadingException extends RuntimeException
8+
{
9+
public static function throwOnUnsupportedLaravelVersions(): void
10+
{
11+
if (version_compare(app()->version(), '11.0.0', '<')) {
12+
throw new self('Eager loading on Parental models are only available in Laravel 11 and above.');
13+
}
14+
}
15+
}

src/HasChildren.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
88
use Illuminate\Database\Eloquent\Relations\HasMany;
99
use Illuminate\Support\Str;
10+
use Parental\Exceptions\EagerLoadingException;
1011
use UnitEnum;
1112

1213
/**
@@ -89,6 +90,8 @@ protected static function parentIsBooting(): bool
8990
*/
9091
public function scopeChildrenWith(EloquentBuilder $query, array $relations): void
9192
{
93+
EagerLoadingException::throwOnUnsupportedLaravelVersions();
94+
9295
$query->afterQuery(fn ($models) => $models->loadChildren($relations));
9396
}
9497

@@ -97,6 +100,8 @@ public function scopeChildrenWith(EloquentBuilder $query, array $relations): voi
97100
*/
98101
public function scopeChildrenWithCount(EloquentBuilder $query, array $relations): void
99102
{
103+
EagerLoadingException::throwOnUnsupportedLaravelVersions();
104+
100105
$query->afterQuery(fn ($models) => $models->loadChildrenCount($relations));
101106
}
102107

@@ -314,6 +319,8 @@ public function become(string $class): object
314319
*/
315320
public function loadChildren(array $relations): static
316321
{
322+
EagerLoadingException::throwOnUnsupportedLaravelVersions();
323+
317324
$this->load($relations[get_class($this)] ?? []);
318325

319326
return $this;
@@ -324,6 +331,8 @@ public function loadChildren(array $relations): static
324331
*/
325332
public function loadChildrenCount(array $relations): static
326333
{
334+
EagerLoadingException::throwOnUnsupportedLaravelVersions();
335+
327336
$this->loadCount($relations[get_class($this)] ?? []);
328337

329338
return $this;

src/Providers/ParentalServiceProvider.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Illuminate\Database\Eloquent\Collection;
66
use Illuminate\Database\Eloquent\Model;
77
use Illuminate\Support\ServiceProvider;
8+
use Parental\Exceptions\EagerLoadingException;
89

910
class ParentalServiceProvider extends ServiceProvider
1011
{
@@ -16,6 +17,8 @@ public function boot(): void
1617
private function bindEagerLoadingMacros(): void
1718
{
1819
Collection::macro('loadChildren', function (array $childrenRelationsMap) {
20+
EagerLoadingException::throwOnUnsupportedLaravelVersions();
21+
1922
/** @var \Illuminate\Database\Eloquent\Collection $this */
2023
$this->groupBy(fn (Model $model) => get_class($model))
2124
->each(fn ($models, string $className) => Collection::make($models)->load($childrenRelationsMap[$className] ?? []));
@@ -24,6 +27,8 @@ private function bindEagerLoadingMacros(): void
2427
});
2528

2629
Collection::macro('loadChildrenCount', function (array $childrenRelationsMap) {
30+
EagerLoadingException::throwOnUnsupportedLaravelVersions();
31+
2732
/** @var \Illuminate\Database\Eloquent\Collection $this */
2833
$this->groupBy(fn (Model $model) => get_class($model))
2934
->each(fn ($models, string $className) => Collection::make($models)->loadCount($childrenRelationsMap[$className] ?? []));
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
<?php
2+
3+
namespace Parental\Tests\Features;
4+
5+
use Parental\Tests\Models\Message;
6+
use Parental\Tests\Models\TextMessage;
7+
use Parental\Tests\Models\Video;
8+
use Parental\Tests\Models\VideoMessage;
9+
use Parental\Tests\TestCase;
10+
use RuntimeException;
11+
12+
class EagerLoadingOnOlderLaravelTest extends TestCase
13+
{
14+
protected function setUp(): void
15+
{
16+
parent::setUp();
17+
18+
if (version_compare(app()->version(), '11.0.0', '>=')) {
19+
$this->markTestSkipped('Eager loading macros should work on Laravel 11 and above, so skipping these tests.');
20+
}
21+
}
22+
23+
public static function eagerLoadingScenarios(): array
24+
{
25+
return [
26+
'eager loading children on model' => [
27+
function () {
28+
$text = TextMessage::create();
29+
$text->images()->create(['url' => 'https://example.com/image1.jpg']);
30+
31+
$text->loadChildren([
32+
TextMessage::class => ['images'],
33+
VideoMessage::class => ['video'],
34+
]);
35+
},
36+
],
37+
'eager loading children count on model' => [
38+
function () {
39+
$text = TextMessage::create();
40+
$text->images()->create(['url' => 'https://example.com/image1.jpg']);
41+
42+
$text->loadChildrenCount([
43+
TextMessage::class => ['images'],
44+
VideoMessage::class => ['video'],
45+
]);
46+
},
47+
],
48+
'eager load children on collection' => [
49+
function () {
50+
$text = TextMessage::create();
51+
$text->images()->create(['url' => 'https://example.com/image1.jpg']);
52+
53+
$video = Video::create(['url' => 'https://example.com/video1.mp4']);
54+
VideoMessage::create(['video_id' => $video->getKey()]);
55+
56+
Message::all()->loadChildren([
57+
TextMessage::class => ['images'],
58+
VideoMessage::class => ['video'],
59+
]);
60+
},
61+
],
62+
'eager load children count on collection' => [
63+
function () {
64+
$text = TextMessage::create();
65+
$text->images()->create(['url' => 'https://example.com/image1.jpg']);
66+
67+
$video = Video::create(['url' => 'https://example.com/video1.mp4']);
68+
VideoMessage::create(['video_id' => $video->getKey()]);
69+
70+
Message::all()->loadChildrenCount([
71+
TextMessage::class => ['images'],
72+
VideoMessage::class => ['video'],
73+
]);
74+
},
75+
],
76+
'eager load children on paginator' => [
77+
function () {
78+
$text = TextMessage::create();
79+
$text->images()->create(['url' => 'https://example.com/image1.jpg']);
80+
81+
$video = Video::create(['url' => 'https://example.com/video1.mp4']);
82+
VideoMessage::create(['video_id' => $video->getKey()]);
83+
84+
Message::paginate()->loadChildren([
85+
TextMessage::class => ['images'],
86+
VideoMessage::class => ['video'],
87+
]);
88+
},
89+
],
90+
'eager load children count on paginator' => [
91+
function () {
92+
$text = TextMessage::create();
93+
$text->images()->create(['url' => 'https://example.com/image1.jpg']);
94+
95+
$video = Video::create(['url' => 'https://example.com/video1.mp4']);
96+
VideoMessage::create(['video_id' => $video->getKey()]);
97+
98+
Message::paginate()->loadChildrenCount([
99+
TextMessage::class => ['images'],
100+
VideoMessage::class => ['video'],
101+
]);
102+
},
103+
],
104+
'eager loading children on query builder' => [
105+
function () {
106+
$text = TextMessage::create();
107+
$text->images()->create(['url' => 'https://example.com/image1.jpg']);
108+
109+
$video = Video::create(['url' => 'https://example.com/video1.mp4']);
110+
VideoMessage::create(['video_id' => $video->getKey()]);
111+
112+
Message::query()->childrenWith([
113+
TextMessage::class => ['images'],
114+
VideoMessage::class => ['video'],
115+
])->get();
116+
},
117+
],
118+
'eager loading children count on query builder' => [
119+
function () {
120+
$text = TextMessage::create();
121+
$text->images()->create(['url' => 'https://example.com/image1.jpg']);
122+
123+
$video = Video::create(['url' => 'https://example.com/video1.mp4']);
124+
VideoMessage::create(['video_id' => $video->getKey()]);
125+
126+
Message::query()->childrenWithCount([
127+
TextMessage::class => ['images'],
128+
VideoMessage::class => ['video'],
129+
])->get();
130+
},
131+
],
132+
];
133+
}
134+
135+
/**
136+
* @test
137+
*
138+
* @dataProvider eagerLoadingScenarios
139+
*/
140+
public function throws_exception_when_eager_loading_on_older_laravel_versions($scenario): void
141+
{
142+
$this->expectException(RuntimeException::class);
143+
$this->expectExceptionMessage('Eager loading on Parental models are only available in Laravel 11 and above.');
144+
145+
$scenario();
146+
}
147+
}

0 commit comments

Comments
 (0)