Skip to content

Commit

Permalink
Merge pull request #189 from caugner/run-artisan-make-in-laravel-test
Browse files Browse the repository at this point in the history
test(laravel): run make:* commands
  • Loading branch information
mr-feek authored Jul 19, 2021
2 parents 723221a + 8d29e5b commit 183c230
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 3 deletions.
75 changes: 72 additions & 3 deletions src/Handlers/SuppressHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use Psalm\Storage\PropertyStorage;
use function array_intersect;
use function in_array;
use function strpos;
use function strtolower;

class SuppressHandler implements AfterClassLikeVisitInterface
{
Expand Down Expand Up @@ -39,13 +41,39 @@ class SuppressHandler implements AfterClassLikeVisitInterface
],
];

/**
* @var array<string, list<class-string>>
*/
private const BY_NAMESPACE = [
'PropertyNotSetInConstructor' => [
'App\Jobs',
],
'PossiblyUnusedMethod' => [
'App\Events',
'App\Jobs',
],
];

/**
* @var array<string, array<class-string, list<string>>>
*/
private const BY_NAMESPACE_METHOD = [
'PossiblyUnusedMethod' => [
'App\Events' => ['broadcastOn'],
'App\Jobs' => ['handle'],
'App\Mail' => ['__construct', 'build'],
'App\Notifications' => ['__construct', 'via', 'toMail', 'toArray'],
]
];

/**
* @var array<string, list<class-string>>
*/
private const BY_PARENT_CLASS = [
'PropertyNotSetInConstructor' => [
'Illuminate\Console\Command',
'Illuminate\Foundation\Http\FormRequest',
'Illuminate\Mail\Mailable',
'Illuminate\Notifications\Notification',
],
];
Expand All @@ -59,6 +87,15 @@ class SuppressHandler implements AfterClassLikeVisitInterface
],
];

/**
* @var array<string, array<class-string, list<string>>>
*/
private const BY_USED_TRAITS = [
'PropertyNotSetInConstructor' => [
'Illuminate\Queue\InteractsWithQueue',
]
];

public static function afterClassLikeVisit(AfterClassLikeVisitEvent $event)
{
$class = $event->getStorage();
Expand All @@ -71,7 +108,31 @@ public static function afterClassLikeVisit(AfterClassLikeVisitEvent $event)

foreach (self::BY_CLASS_METHOD as $issue => $method_by_class) {
foreach ($method_by_class[$class->name] ?? [] as $method_name) {
self::suppress($issue, $class->methods[$method_name] ?? null);
/** @psalm-suppress RedundantCast */
self::suppress($issue, $class->methods[strtolower($method_name)] ?? null);
}
}

foreach (self::BY_NAMESPACE as $issue => $namespaces) {
foreach ($namespaces as $namespace) {
if (0 !== strpos($class->name, "$namespace\\")) {
continue;
}

self::suppress($issue, $class);
break;
}
}

foreach (self::BY_NAMESPACE_METHOD as $issue => $methods_by_namespaces) {
foreach ($methods_by_namespaces as $namespace => $method_names) {
if (0 !== strpos($class->name, "$namespace\\")) {
continue;
}

foreach ($method_names as $method_name) {
self::suppress($issue, $class->methods[strtolower($method_name)] ?? null);
}
}
}

Expand All @@ -83,8 +144,8 @@ public static function afterClassLikeVisit(AfterClassLikeVisitEvent $event)
self::suppress($issue, $class);
}

foreach (self::BY_PARENT_CLASS_PROPERTY as $issue => $methods_by_parent_class) {
foreach ($methods_by_parent_class as $parent_class => $property_names) {
foreach (self::BY_PARENT_CLASS_PROPERTY as $issue => $properties_by_parent_class) {
foreach ($properties_by_parent_class as $parent_class => $property_names) {
if (!in_array($parent_class, $class->parent_classes)) {
continue;
}
Expand All @@ -94,6 +155,14 @@ public static function afterClassLikeVisit(AfterClassLikeVisitEvent $event)
}
}
}

foreach (self::BY_USED_TRAITS as $issue => $used_traits) {
if (!array_intersect($class->used_traits, $used_traits)) {
continue;
}

self::suppress($issue, $class);
}
}

/**
Expand Down
71 changes: 71 additions & 0 deletions tests/laravel-test-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="4.8.1@f73f2299dbc59a3e6c4d66cff4605176e728ee69">
<file src="app/Broadcasting/ExampleChannel.php">
<InvalidReturnType occurrences="1">
<code>array|bool</code>
</InvalidReturnType>
<UnusedClass occurrences="1">
<code>ExampleChannel</code>
</UnusedClass>
</file>
<file src="app/Casts/ExampleCast.php">
<UnusedClass occurrences="1">
<code>ExampleCast</code>
</UnusedClass>
</file>
<file src="app/Console/Commands/ExampleCommand.php">
<UnusedClass occurrences="1">
<code>ExampleCommand</code>
</UnusedClass>
</file>
<file src="app/Exceptions/ExampleException.php">
<UnusedClass occurrences="1">
<code>ExampleException</code>
</UnusedClass>
</file>
<file src="app/Exceptions/Handler.php">
<NonInvariantDocblockPropertyType occurrences="2">
<code>$dontFlash</code>
Expand All @@ -9,16 +32,56 @@
<code>$e</code>
</UnusedClosureParam>
</file>
<file src="app/Http/Controllers/ExampleController.php">
<UnusedClass occurrences="1">
<code>ExampleController</code>
</UnusedClass>
</file>
<file src="app/Http/Middleware/ExampleMiddleware.php">
<UnusedClass occurrences="1">
<code>ExampleMiddleware</code>
</UnusedClass>
</file>
<file src="app/Http/Middleware/TrustProxies.php">
<NonInvariantDocblockPropertyType occurrences="1">
<code>$headers</code>
</NonInvariantDocblockPropertyType>
</file>
<file src="app/Http/Requests/ExampleRequest.php">
<UnusedClass occurrences="1">
<code>ExampleRequest</code>
</UnusedClass>
</file>
<file src="app/Http/Resources/ExampleResource.php">
<UnusedClass occurrences="1">
<code>ExampleResource</code>
</UnusedClass>
</file>
<file src="app/Listeners/ExampleListener.php">
<UnusedClass occurrences="1">
<code>ExampleListener</code>
</UnusedClass>
</file>
<file src="app/Models/User.php">
<NonInvariantDocblockPropertyType occurrences="1">
<code>$fillable</code>
</NonInvariantDocblockPropertyType>
</file>
<file src="app/Observers/ExampleObserver.php">
<UnusedClass occurrences="1">
<code>ExampleObserver</code>
</UnusedClass>
</file>
<file src="app/Policies/ExamplePolicy.php">
<UnusedClass occurrences="1">
<code>ExamplePolicy</code>
</UnusedClass>
</file>
<file src="app/Providers/ExampleProvider.php">
<UnusedClass occurrences="1">
<code>ExampleProvider</code>
</UnusedClass>
</file>
<file src="app/Providers/RouteServiceProvider.php">
<MixedArgument occurrences="1">
<code>optional($request-&gt;user())-&gt;id ?: $request-&gt;ip()</code>
Expand All @@ -30,4 +93,12 @@
<code>optional($request-&gt;user())-&gt;id ?: $request-&gt;ip()</code>
</PossiblyNullArgument>
</file>
<file src="app/Rules/ExampleRule.php">
<InvalidReturnType occurrences="1">
<code>bool</code>
</InvalidReturnType>
<UnusedClass occurrences="1">
<code>ExampleRule</code>
</UnusedClass>
</file>
</files>
23 changes: 23 additions & 0 deletions tests/laravel-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,29 @@ echo "Installing Laravel"
composer create-project --quiet --prefer-dist "laravel/laravel" ../laravel
cd ../laravel/

echo "Preparing Laravel"
./artisan make:cast ExampleCast
./artisan make:channel ExampleChannel
./artisan make:command ExampleCommand
./artisan make:controller ExampleController
./artisan make:event ExampleEvent
./artisan make:exception ExampleException
./artisan make:factory ExampleFactory
./artisan make:job ExampleJob
./artisan make:listener ExampleListener
./artisan make:mail ExampleMail
./artisan make:middleware ExampleMiddleware
./artisan make:model Example
./artisan make:notification ExampleNotification
./artisan make:observer ExampleObserver
./artisan make:policy ExamplePolicy
./artisan make:provider ExampleProvider
./artisan make:request ExampleRequest
./artisan make:resource ExampleResource
./artisan make:rule ExampleRule
./artisan make:seeder ExampleSeeder
./artisan make:test ExampleTest

echo "Adding package from source"
sed -e 's|"type": "project",|&"repositories": [ { "type": "path", "url": "../psalm-plugin-laravel" } ],|' -i composer.json
COMPOSER_MEMORY_LIMIT=-1 composer require --dev "psalm/plugin-laravel:*"
Expand Down

0 comments on commit 183c230

Please sign in to comment.