Skip to content

Commit bb47983

Browse files
authored
Merge pull request #182 from caugner/cannot-call-factory-in-laravel-8.x
Ensure factory() helper is gone in Laravel 8+
2 parents 7198bb4 + 72a06f2 commit bb47983

File tree

5 files changed

+110
-41
lines changed

5 files changed

+110
-41
lines changed

src/Plugin.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22
namespace Psalm\LaravelPlugin;
33

4+
use Illuminate\Foundation\Application;
45
use Psalm\LaravelPlugin\Handlers\Application\ContainerHandler;
56
use Psalm\LaravelPlugin\Handlers\Application\OffsetHandler;
67
use Psalm\LaravelPlugin\Handlers\Eloquent\ModelMethodHandler;
@@ -20,7 +21,9 @@
2021
use Psalm\Plugin\RegistrationInterface;
2122
use SimpleXMLElement;
2223
use Throwable;
24+
use function array_merge;
2325
use function dirname;
26+
use function explode;
2427
use function glob;
2528

2629
class Plugin implements PluginEntryPointInterface
@@ -39,9 +42,26 @@ public function __invoke(RegistrationInterface $registration, ?SimpleXMLElement
3942
$this->registerStubs($registration);
4043
}
4144

45+
protected function getCommonStubs(): array
46+
{
47+
return glob(dirname(__DIR__) . '/stubs/*.stubphp');
48+
}
49+
50+
protected function getStubsForVersion(string $version): array
51+
{
52+
[$majorVersion] = explode('.', $version);
53+
54+
return glob(dirname(__DIR__) . '/stubs/'.$majorVersion.'/*.stubphp');
55+
}
56+
4257
private function registerStubs(RegistrationInterface $registration): void
4358
{
44-
foreach (glob(dirname(__DIR__) . '/stubs/*.stubphp') as $stubFilePath) {
59+
$stubs = array_merge(
60+
$this->getCommonStubs(),
61+
$this->getStubsForVersion(Application::VERSION),
62+
);
63+
64+
foreach ($stubs as $stubFilePath) {
4565
$registration->addStubFile($stubFilePath);
4666
}
4767

stubs/6/helpers.stubphp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/**
4+
* @template TModel of \Illuminate\Database\Eloquent\Model
5+
* @template TNameOrCountOrNull of string|int|null
6+
* @template TCountOrNull of int|null
7+
*
8+
* @param class-string<TModel> $modelClassName
9+
* @param TNameOrCountOrNull $nameOrCount
10+
* @param TCountOrNull $count
11+
*
12+
* @return (
13+
TCountOrNull is int
14+
? Illuminate\Database\Eloquent\FactoryBuilder<TModel, TCountOrNull>
15+
: (
16+
TNameOrCountOrNull is int
17+
? Illuminate\Database\Eloquent\FactoryBuilder<TModel, TNameOrCountOrNull>
18+
: Illuminate\Database\Eloquent\FactoryBuilder<TModel, 1>
19+
)
20+
21+
)
22+
*/
23+
function factory(string $modelClassName, $nameOrCount = null, $count = null)
24+
{
25+
}

stubs/7/helpers.stubphp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/**
4+
* @template TModel of \Illuminate\Database\Eloquent\Model
5+
* @template TNameOrCountOrNull of string|int|null
6+
* @template TCountOrNull of int|null
7+
*
8+
* @param class-string<TModel> $modelClassName
9+
* @param TNameOrCountOrNull $nameOrCount
10+
* @param TCountOrNull $count
11+
*
12+
* @return (
13+
TCountOrNull is int
14+
? Illuminate\Database\Eloquent\FactoryBuilder<TModel, TCountOrNull>
15+
: (
16+
TNameOrCountOrNull is int
17+
? Illuminate\Database\Eloquent\FactoryBuilder<TModel, TNameOrCountOrNull>
18+
: Illuminate\Database\Eloquent\FactoryBuilder<TModel, 1>
19+
)
20+
21+
)
22+
*/
23+
function factory(string $modelClassName, $nameOrCount = null, $count = null)
24+
{
25+
}

stubs/helpers.stubphp

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,5 @@
11
<?php
22

3-
/**
4-
* @template TModel of \Illuminate\Database\Eloquent\Model
5-
* @template TNameOrCountOrNull of string|int|null
6-
* @template TCountOrNull of int|null
7-
*
8-
* @param class-string<TModel> $modelClassName
9-
* @param TNameOrCountOrNull $nameOrCount
10-
* @param TCountOrNull $count
11-
*
12-
* @return (
13-
TCountOrNull is int
14-
? Illuminate\Database\Eloquent\FactoryBuilder<TModel, TCountOrNull>
15-
: (
16-
TNameOrCountOrNull is int
17-
? Illuminate\Database\Eloquent\FactoryBuilder<TModel, TNameOrCountOrNull>
18-
: Illuminate\Database\Eloquent\FactoryBuilder<TModel, 1>
19-
)
20-
21-
)
22-
*/
23-
function factory(string $modelClassName, $nameOrCount = null, $count = null)
24-
{
25-
26-
}
27-
283
/**
294
* Return a new response from the application.
305
*

tests/acceptance/FactoryTypes.feature

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,32 @@ Feature: factory()
1515
</plugins>
1616
</psalm>
1717
"""
18-
19-
Scenario:
20-
Given I have the following code
18+
And I have the following code preamble
2119
"""
2220
<?php declare(strict_types=1);
2321
22+
use Illuminate\Database\Eloquent\Collection;
23+
use Illuminate\Database\Eloquent\FactoryBuilder;
2424
use Tests\Psalm\LaravelPlugin\Models\User;
25+
"""
2526

27+
Scenario: can use factory helper in Laravel 6.x and 7.x
28+
Given I have the "laravel/framework" package satisfying the "6.* || 7.*"
29+
And I have the following code
30+
"""
2631
class FactoryTest {
2732
/**
28-
* @return \Illuminate\Database\Eloquent\FactoryBuilder<User, 1>
29-
*/
30-
public function getFactory(): \Illuminate\Database\Eloquent\FactoryBuilder
33+
* @return FactoryBuilder<User, 1>
34+
*/
35+
public function getFactory(): FactoryBuilder
3136
{
3237
return factory(User::class);
3338
}
3439
3540
/**
36-
* @return \Illuminate\Database\Eloquent\FactoryBuilder<User, 2>
37-
*/
38-
public function getFactoryForTwo(): \Illuminate\Database\Eloquent\FactoryBuilder
41+
* @return FactoryBuilder<User, 2>
42+
*/
43+
public function getFactoryForTwo(): FactoryBuilder
3944
{
4045
return factory(User::class, 2);
4146
}
@@ -51,21 +56,40 @@ Feature: factory()
5156
}
5257
5358
/**
54-
* @return \Illuminate\Database\Eloquent\Collection<User>
55-
*/
56-
public function createUsers(): \Illuminate\Database\Eloquent\Collection
59+
* @return Collection<User>
60+
*/
61+
public function createUsers(): Collection
5762
{
5863
return factory(User::class, 2)->create();
5964
}
6065
6166
/**
62-
* @return \Illuminate\Database\Eloquent\Collection<User>
63-
*/
64-
public function createUsersWithNameAttribute(): \Illuminate\Database\Eloquent\Collection
67+
* @return Collection<User>
68+
*/
69+
public function createUsersWithNameAttribute(): Collection
6570
{
6671
return factory(User::class, 'new name', 2)->create();
6772
}
6873
}
6974
"""
7075
When I run Psalm
7176
Then I see no errors
77+
78+
Scenario: cannot use factory helper in Laravel 8.x and later
79+
Given I have the "laravel/framework" package satisfying the ">= 8.0"
80+
And I have the following code
81+
"""
82+
class FactoryTest {
83+
/**
84+
* @return FactoryBuilder<User, 1>
85+
*/
86+
public function getFactory(): FactoryBuilder
87+
{
88+
return factory(User::class);
89+
}
90+
}
91+
"""
92+
When I run Psalm
93+
Then I see these errors
94+
| Type | Message |
95+
| UndefinedFunction | Function factory does not exist |

0 commit comments

Comments
 (0)