mirror of
https://github.com/barryvdh/laravel-ide-helper.git
synced 2026-08-17 17:47:13 +00:00
Fix PHPDoc placement before PHP 8 class attributes and add regression tests (#1769)
* Initial plan * Add tests for PHP class attribute placement and fix whitespace in regex Co-authored-by: barryvdh <[email protected]> * Add advanced edge case tests: final+nested-brackets and multiple attributes Co-authored-by: barryvdh <[email protected]> * Add PHP 8.5 test for closures inside attribute arguments Co-authored-by: barryvdh <[email protected]> * composer fix-style --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: barryvdh <[email protected]> Co-authored-by: laravel-ide-helper <[email protected]>
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
.phpunit.result.cache
|
.phpunit.result.cache
|
||||||
|
/auth.json
|
||||||
/build
|
/build
|
||||||
/.idea
|
/.idea
|
||||||
/.php-cs-fixer.cache
|
/.php-cs-fixer.cache
|
||||||
|
|||||||
@@ -1206,7 +1206,7 @@ class ModelsCommand extends Command
|
|||||||
// declaration, insert the docblock before the first attribute so that
|
// declaration, insert the docblock before the first attribute so that
|
||||||
// the resulting order is: docblock → attributes → class.
|
// the resulting order is: docblock → attributes → class.
|
||||||
$before = substr($contents, 0, $pos);
|
$before = substr($contents, 0, $pos);
|
||||||
if (preg_match('/(\s*(?:#\[.+?\]\s*)+)$/s', $before, $matches)) {
|
if (preg_match('/((?:#\[.+?\]\s*)+)$/s', $before, $matches)) {
|
||||||
$pos -= strlen($matches[1]);
|
$pos -= strlen($matches[1]);
|
||||||
$replace = "{$modelDocComment}\n";
|
$replace = "{$modelDocComment}\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PhpAttributesBeforeClass\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
// Tests: final class + attribute with nested array argument (e.g. ObservedBy([...]))
|
||||||
|
#[ObservedByStub([StubObserver::class])]
|
||||||
|
final class FinalWithNested extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'simples';
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PhpAttributesBeforeClass\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
// Tests: multiple consecutive PHP 8 attributes before the class declaration
|
||||||
|
#[\AllowDynamicProperties]
|
||||||
|
#[SecondAttribute]
|
||||||
|
class MultipleAttributes extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'simples';
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PhpAttributesBeforeClass\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
#[\AllowDynamicProperties]
|
||||||
|
class Simple extends Model
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PhpAttributesBeforeClass;
|
||||||
|
|
||||||
|
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
|
||||||
|
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
|
||||||
|
|
||||||
|
class Test extends AbstractModelsCommand
|
||||||
|
{
|
||||||
|
public function test(): void
|
||||||
|
{
|
||||||
|
$command = $this->app->make(ModelsCommand::class);
|
||||||
|
|
||||||
|
$tester = $this->runCommand($command, [
|
||||||
|
'--write' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertSame(0, $tester->getStatusCode());
|
||||||
|
$this->assertStringContainsString('Written new phpDocBlock to', $tester->getDisplay());
|
||||||
|
$this->assertMatchesMockedSnapshot();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PhpAttributesBeforeClass\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
// Tests: final class + attribute with nested array argument (e.g. ObservedBy([...]))
|
||||||
|
/**
|
||||||
|
* @property int $id
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|FinalWithNested newModelQuery()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|FinalWithNested newQuery()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|FinalWithNested query()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|FinalWithNested whereId($value)
|
||||||
|
* @mixin \Eloquent
|
||||||
|
*/
|
||||||
|
#[ObservedByStub([StubObserver::class])]
|
||||||
|
final class FinalWithNested extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'simples';
|
||||||
|
}
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PhpAttributesBeforeClass\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
// Tests: multiple consecutive PHP 8 attributes before the class declaration
|
||||||
|
/**
|
||||||
|
* @property int $id
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|MultipleAttributes newModelQuery()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|MultipleAttributes newQuery()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|MultipleAttributes query()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|MultipleAttributes whereId($value)
|
||||||
|
* @mixin \Eloquent
|
||||||
|
*/
|
||||||
|
#[\AllowDynamicProperties]
|
||||||
|
#[SecondAttribute]
|
||||||
|
class MultipleAttributes extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'simples';
|
||||||
|
}
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PhpAttributesBeforeClass\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property int $id
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|Simple newModelQuery()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|Simple newQuery()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|Simple query()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|Simple whereId($value)
|
||||||
|
* @mixin \Eloquent
|
||||||
|
*/
|
||||||
|
#[\AllowDynamicProperties]
|
||||||
|
class Simple extends Model
|
||||||
|
{
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PhpAttributesClosureInAttribute\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
// Tests: closure expression inside an attribute argument (PHP 8.5+)
|
||||||
|
#[SomeClosureAttr(fn () => true)]
|
||||||
|
class ClosureInAttribute extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'simples';
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PhpAttributesClosureInAttribute;
|
||||||
|
|
||||||
|
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
|
||||||
|
use Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\AbstractModelsCommand;
|
||||||
|
|
||||||
|
class Test extends AbstractModelsCommand
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @requires PHP 8.5
|
||||||
|
*/
|
||||||
|
public function test(): void
|
||||||
|
{
|
||||||
|
$command = $this->app->make(ModelsCommand::class);
|
||||||
|
|
||||||
|
$tester = $this->runCommand($command, [
|
||||||
|
'--write' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertSame(0, $tester->getStatusCode());
|
||||||
|
$this->assertStringContainsString('Written new phpDocBlock to', $tester->getDisplay());
|
||||||
|
$this->assertMatchesMockedSnapshot();
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Barryvdh\LaravelIdeHelper\Tests\Console\ModelsCommand\PhpAttributesClosureInAttribute\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
// Tests: closure expression inside an attribute argument (PHP 8.5+)
|
||||||
|
/**
|
||||||
|
* @property int $id
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|ClosureInAttribute newModelQuery()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|ClosureInAttribute newQuery()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|ClosureInAttribute query()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder<static>|ClosureInAttribute whereId($value)
|
||||||
|
* @mixin \Eloquent
|
||||||
|
*/
|
||||||
|
#[SomeClosureAttr(fn() => true)]
|
||||||
|
class ClosureInAttribute extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'simples';
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user