Merge pull request #182 from caugner/cannot-call-factory-in-laravel-8.x

Ensure factory() helper is gone in Laravel 8+
This commit is contained in:
feek 2021-07-13 12:27:05 -04:00 committed by GitHub
commit bb47983d73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 110 additions and 41 deletions

View File

@ -1,6 +1,7 @@
<?php
namespace Psalm\LaravelPlugin;
use Illuminate\Foundation\Application;
use Psalm\LaravelPlugin\Handlers\Application\ContainerHandler;
use Psalm\LaravelPlugin\Handlers\Application\OffsetHandler;
use Psalm\LaravelPlugin\Handlers\Eloquent\ModelMethodHandler;
@ -20,7 +21,9 @@ use Psalm\Plugin\PluginEntryPointInterface;
use Psalm\Plugin\RegistrationInterface;
use SimpleXMLElement;
use Throwable;
use function array_merge;
use function dirname;
use function explode;
use function glob;
class Plugin implements PluginEntryPointInterface
@ -39,9 +42,26 @@ class Plugin implements PluginEntryPointInterface
$this->registerStubs($registration);
}
protected function getCommonStubs(): array
{
return glob(dirname(__DIR__) . '/stubs/*.stubphp');
}
protected function getStubsForVersion(string $version): array
{
[$majorVersion] = explode('.', $version);
return glob(dirname(__DIR__) . '/stubs/'.$majorVersion.'/*.stubphp');
}
private function registerStubs(RegistrationInterface $registration): void
{
foreach (glob(dirname(__DIR__) . '/stubs/*.stubphp') as $stubFilePath) {
$stubs = array_merge(
$this->getCommonStubs(),
$this->getStubsForVersion(Application::VERSION),
);
foreach ($stubs as $stubFilePath) {
$registration->addStubFile($stubFilePath);
}

25
stubs/6/helpers.stubphp Normal file
View File

@ -0,0 +1,25 @@
<?php
/**
* @template TModel of \Illuminate\Database\Eloquent\Model
* @template TNameOrCountOrNull of string|int|null
* @template TCountOrNull of int|null
*
* @param class-string<TModel> $modelClassName
* @param TNameOrCountOrNull $nameOrCount
* @param TCountOrNull $count
*
* @return (
TCountOrNull is int
? Illuminate\Database\Eloquent\FactoryBuilder<TModel, TCountOrNull>
: (
TNameOrCountOrNull is int
? Illuminate\Database\Eloquent\FactoryBuilder<TModel, TNameOrCountOrNull>
: Illuminate\Database\Eloquent\FactoryBuilder<TModel, 1>
)
)
*/
function factory(string $modelClassName, $nameOrCount = null, $count = null)
{
}

25
stubs/7/helpers.stubphp Normal file
View File

@ -0,0 +1,25 @@
<?php
/**
* @template TModel of \Illuminate\Database\Eloquent\Model
* @template TNameOrCountOrNull of string|int|null
* @template TCountOrNull of int|null
*
* @param class-string<TModel> $modelClassName
* @param TNameOrCountOrNull $nameOrCount
* @param TCountOrNull $count
*
* @return (
TCountOrNull is int
? Illuminate\Database\Eloquent\FactoryBuilder<TModel, TCountOrNull>
: (
TNameOrCountOrNull is int
? Illuminate\Database\Eloquent\FactoryBuilder<TModel, TNameOrCountOrNull>
: Illuminate\Database\Eloquent\FactoryBuilder<TModel, 1>
)
)
*/
function factory(string $modelClassName, $nameOrCount = null, $count = null)
{
}

View File

@ -1,30 +1,5 @@
<?php
/**
* @template TModel of \Illuminate\Database\Eloquent\Model
* @template TNameOrCountOrNull of string|int|null
* @template TCountOrNull of int|null
*
* @param class-string<TModel> $modelClassName
* @param TNameOrCountOrNull $nameOrCount
* @param TCountOrNull $count
*
* @return (
TCountOrNull is int
? Illuminate\Database\Eloquent\FactoryBuilder<TModel, TCountOrNull>
: (
TNameOrCountOrNull is int
? Illuminate\Database\Eloquent\FactoryBuilder<TModel, TNameOrCountOrNull>
: Illuminate\Database\Eloquent\FactoryBuilder<TModel, 1>
)
)
*/
function factory(string $modelClassName, $nameOrCount = null, $count = null)
{
}
/**
* Return a new response from the application.
*

View File

@ -15,27 +15,32 @@ Feature: factory()
</plugins>
</psalm>
"""
Scenario:
Given I have the following code
And I have the following code preamble
"""
<?php declare(strict_types=1);
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\FactoryBuilder;
use Tests\Psalm\LaravelPlugin\Models\User;
"""
Scenario: can use factory helper in Laravel 6.x and 7.x
Given I have the "laravel/framework" package satisfying the "6.* || 7.*"
And I have the following code
"""
class FactoryTest {
/**
* @return \Illuminate\Database\Eloquent\FactoryBuilder<User, 1>
*/
public function getFactory(): \Illuminate\Database\Eloquent\FactoryBuilder
* @return FactoryBuilder<User, 1>
*/
public function getFactory(): FactoryBuilder
{
return factory(User::class);
}
/**
* @return \Illuminate\Database\Eloquent\FactoryBuilder<User, 2>
*/
public function getFactoryForTwo(): \Illuminate\Database\Eloquent\FactoryBuilder
* @return FactoryBuilder<User, 2>
*/
public function getFactoryForTwo(): FactoryBuilder
{
return factory(User::class, 2);
}
@ -51,17 +56,17 @@ Feature: factory()
}
/**
* @return \Illuminate\Database\Eloquent\Collection<User>
*/
public function createUsers(): \Illuminate\Database\Eloquent\Collection
* @return Collection<User>
*/
public function createUsers(): Collection
{
return factory(User::class, 2)->create();
}
/**
* @return \Illuminate\Database\Eloquent\Collection<User>
*/
public function createUsersWithNameAttribute(): \Illuminate\Database\Eloquent\Collection
* @return Collection<User>
*/
public function createUsersWithNameAttribute(): Collection
{
return factory(User::class, 'new name', 2)->create();
}
@ -69,3 +74,22 @@ Feature: factory()
"""
When I run Psalm
Then I see no errors
Scenario: cannot use factory helper in Laravel 8.x and later
Given I have the "laravel/framework" package satisfying the ">= 8.0"
And I have the following code
"""
class FactoryTest {
/**
* @return FactoryBuilder<User, 1>
*/
public function getFactory(): FactoryBuilder
{
return factory(User::class);
}
}
"""
When I run Psalm
Then I see these errors
| Type | Message |
| UndefinedFunction | Function factory does not exist |