Skip to content

Commit

Permalink
build(rector) add rules to handle EventDispatcher versions
Browse files Browse the repository at this point in the history
  • Loading branch information
lucatume committed Oct 20, 2023
1 parent c38fde4 commit 91be0fa
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 19 deletions.
7 changes: 5 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@
"lucatume/codeception-snapshot-assertions": "^1.0.0",
"gumlet/php-image-resize": "^1.6",
"szepeviktor/phpstan-wordpress": "^1.3",
"phpstan/phpstan": "*",
"phpstan/extension-installer": "^1.3",
"phpstan/phpstan-symfony": "^1.3",
"squizlabs/php_codesniffer": "^3.7"
"squizlabs/php_codesniffer": "^3.7",
"rector/rector": "^0.18.5"
},
"autoload": {
"psr-4": {
Expand All @@ -63,7 +65,8 @@
},
"autoload-dev": {
"psr-4": {
"lucatume\\WPBrowser\\Tests\\": "tests/_support"
"lucatume\\WPBrowser\\Tests\\": "tests/_support",
"lucatume\\Rector\\": "config/rector/src"
}
},
"extra": {
Expand Down
10 changes: 9 additions & 1 deletion config/rector-35.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

declare( strict_types=1 );

use lucatume\Rector\SwapEventDispatcherEventNameParameters;
use Rector\Config\RectorConfig;
use Rector\Renaming\Rector\Name\RenameClassRector;
use Rector\Set\ValueObject\DowngradeLevelSetList;
use Rector\TypeDeclaration\Rector\ClassMethod\ArrayShapeFromConstantArrayReturnRector;
use Rector\TypeDeclaration\Rector\Closure\AddClosureReturnTypeRector;
Expand All @@ -14,5 +16,11 @@
dirname(__DIR__) . '/tests',
]);

$rectorConfig->sets([ DowngradeLevelSetList::DOWN_TO_PHP_71 ]);
$rectorConfig->ruleWithConfiguration(RenameClassRector::class,[
'Symfony\Contracts\EventDispatcher\Event' => 'Symfony\Component\EventDispatcher\Event'
]);

$rectorConfig->rule(SwapEventDispatcherEventNameParameters::class);

$rectorConfig->sets([ DowngradeLevelSetList::DOWN_TO_PHP_71 ]);
};
62 changes: 62 additions & 0 deletions config/rector/src/SwapEventDispatcherEventNameParameters.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

namespace lucatume\Rector;

use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use Rector\Core\Rector\AbstractRector;
use PHPStan\Type\ObjectType;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

class SwapEventDispatcherEventNameParameters extends AbstractRector
{

public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Swap the event and name parameters of the EventDispatcherInterface::dispatch method.',
[
new CodeSample(
'$eventDispatcher->dispatch($event, $eventName);',
'$eventDispatcher->dispatch($eventName, $event);'
)
]
);
}

public function getNodeTypes(): array
{
return [MethodCall::class];
}

/**
* @param MethodCall $node
*/
public function refactor(Node $node): ?Node
{
$methodCallName = $this->getName($node->name);
if ($methodCallName !== 'dispatch') {
return null;
}

if (!$this->isObjectType(
$node->var,
new ObjectType('Symfony\Component\EventDispatcher\EventDispatcherInterface')
)) {
return null;
}

$args = $node->args;

if (!($args[0] instanceof Node\Arg && $args[1] instanceof Node\Arg
&& $args[0]->value?->name === 'event'
&& $args[1]->value?->name === 'name')) {
return null;
}

$node->args = [$args[1], $args[0]];

return $node;
}
}
11 changes: 6 additions & 5 deletions src/Events/Dispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,13 @@ public static function addListener(string $eventName, callable $listener, int $p
*/
public static function dispatch(string $name, mixed $origin = null, array $context = []): ?object
{
if (class_exists(\Symfony\Contracts\EventDispatcher\Event::class)) {
$event = new Event($name, $context, $origin);
return self::getEventDispatcher()?->dispatch($event, $name);
$eventDispatcher = self::getEventDispatcher();

if (!$eventDispatcher) {
return null;
}

$event = new LegacyEvent($name, $context, $origin);
return self::getEventDispatcher()?->dispatch($name, $event); //@phpstan-ignore-line
$event = new Event($name, $context, $origin);
return $eventDispatcher->dispatch($event, $name);
}
}
17 changes: 6 additions & 11 deletions tests/unit/lucatume/WPBrowser/Events/DispatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,7 @@ function should_allow_listening_to_and_dispatching_events()
$callStack[] = 'first';
}, 100);

$eventClass = class_exists(\Symfony\Contracts\EventDispatcher\Event::class) ?
Event::class : LegacyEvent::class;

$this->assertInstanceOf($eventClass, Dispatcher::dispatch('TEST_EVENT'));
$this->assertInstanceOf(Event::class, Dispatcher::dispatch('TEST_EVENT'));

$this->assertEquals([
'first',
Expand All @@ -62,7 +59,7 @@ function should_allow_listening_to_and_dispatching_events()
$callStack[] = 'new first';
}, 200);

$this->assertInstanceOf($eventClass, Dispatcher::dispatch('TEST_EVENT'));
$this->assertInstanceOf(Event::class, Dispatcher::dispatch('TEST_EVENT'));

$this->assertEquals([
'new first',
Expand All @@ -75,7 +72,7 @@ function should_allow_listening_to_and_dispatching_events()
$removeThird();
$removeFirst();

$this->assertInstanceOf($eventClass, Dispatcher::dispatch('TEST_EVENT'));
$this->assertInstanceOf(Event::class, Dispatcher::dispatch('TEST_EVENT'));

$this->assertEquals([
'new first',
Expand Down Expand Up @@ -113,9 +110,7 @@ function should_return_a_purposely_built_dispatcher_when_the_codeception_instanc
$callStack[] = 'first';
}, 100);

$eventClass = class_exists(\Symfony\Contracts\EventDispatcher\Event::class) ?
Event::class : LegacyEvent::class;
$this->assertInstanceOf($eventClass, Dispatcher::dispatch('TEST_EVENT'));
$this->assertInstanceOf(Event::class, Dispatcher::dispatch('TEST_EVENT'));

$this->assertEquals([
'first',
Expand All @@ -128,7 +123,7 @@ function should_return_a_purposely_built_dispatcher_when_the_codeception_instanc
$callStack[] = 'new first';
}, 200);

$this->assertInstanceOf($eventClass, Dispatcher::dispatch('TEST_EVENT'));
$this->assertInstanceOf(Event::class, Dispatcher::dispatch('TEST_EVENT'));

$this->assertEquals([
'new first',
Expand All @@ -141,7 +136,7 @@ function should_return_a_purposely_built_dispatcher_when_the_codeception_instanc
$removeThird();
$removeFirst();

$this->assertInstanceOf($eventClass, Dispatcher::dispatch('TEST_EVENT'));
$this->assertInstanceOf(Event::class, Dispatcher::dispatch('TEST_EVENT'));

$this->assertEquals([
'new first',
Expand Down

0 comments on commit 91be0fa

Please sign in to comment.