Skip to content

Commit

Permalink
Merge pull request #2 from labrador-kennel/feature/async-event-v4
Browse files Browse the repository at this point in the history
Update to work with labrador-kennel/async-event v4
  • Loading branch information
cspray authored May 30, 2024
2 parents e9d9e11 + 99ebafa commit 2cbb9d9
Show file tree
Hide file tree
Showing 15 changed files with 806 additions and 843 deletions.
14 changes: 10 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,21 @@
"name": "labrador-kennel/async-event-autowire",
"description": "Allows labrador-kennel/async-event Listeners to be autowired into an EventEmitter.",
"license": ["MIT"],
"repositories": [
{
"type": "vcs",
"url": "https://github.com/cspray/phpunit-util"
}
],
"require": {
"php": "^8.1",
"php": "^8.2",
"cspray/annotated-container": "^2.0",
"labrador-kennel/async-event": "^3.0"
"labrador-kennel/async-event": "^4.0"
},
"require-dev": {
"amphp/phpunit-util": "^v3.0",
"amphp/phpunit-util": "dev-phpunit-10-support",
"php-di/php-di": "^7.0",
"phpunit/phpunit": "^9.6",
"phpunit/phpunit": "^10",
"roave/security-advisories": "dev-latest"
},
"autoload": {
Expand Down
1,375 changes: 729 additions & 646 deletions composer.lock

Large diffs are not rendered by default.

36 changes: 11 additions & 25 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,27 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.6/phpunit.xsd"
bootstrap="vendor/autoload.php"
cacheResultFile=".phpunit.cache/test-results"
executionOrder="depends,defects"
forceCoversAnnotation="true"
beStrictAboutCoversAnnotation="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
convertDeprecationsToExceptions="true"
failOnRisky="true"
failOnWarning="true"
verbose="true">
<testsuites>
<testsuite name="default">
<directory>tests</directory>
</testsuite>
</testsuites>

<coverage cacheDirectory=".phpunit.cache/code-coverage"
processUncoveredFiles="true">
<include>
<directory suffix=".php">src</directory>
</include>
</coverage>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" bootstrap="vendor/autoload.php" executionOrder="depends,defects" beStrictAboutOutputDuringTests="true" failOnRisky="true" failOnWarning="true" cacheDirectory=".phpunit.cache" requireCoverageMetadata="true" beStrictAboutCoverageMetadata="true">
<testsuites>
<testsuite name="default">
<directory>tests</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory suffix=".php">src</directory>
</include>
</source>
</phpunit>
9 changes: 2 additions & 7 deletions src/ListenerService.php → src/AutowiredListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,19 @@
use Attribute;

#[Attribute(Attribute::TARGET_CLASS)]
final class ListenerService implements ServiceAttribute {
final class AutowiredListener implements ServiceAttribute {

/**
* @param ListenerRemoval $listenerRemoval
* @param list<string> $profiles
* @param string|null $name
*/
public function __construct(
private readonly ListenerRemoval $listenerRemoval = ListenerRemoval::NeverRemove,
public readonly string $eventName,
private readonly array $profiles = [],
private readonly ?string $name = null
) {
}

public function getListenerRemoval() : ListenerRemoval {
return $this->listenerRemoval;
}

public function getProfiles() : array {
return $this->profiles;
}
Expand Down
12 changes: 4 additions & 8 deletions src/DefinitionProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,16 @@

use Cspray\AnnotatedContainer\StaticAnalysis\DefinitionProvider as AnnotatedContainerDefinitionProvider;
use Cspray\AnnotatedContainer\StaticAnalysis\DefinitionProviderContext;
use Labrador\AsyncEvent\AmpEventEmitter;
use Labrador\AsyncEvent\EventEmitter;
use Labrador\AsyncEvent\EventFactory;
use Labrador\AsyncEvent\StandardEventFactory;
use Labrador\AsyncEvent\AmpEmitter;
use Labrador\AsyncEvent\Emitter;
use function Cspray\AnnotatedContainer\service;
use function Cspray\Typiphy\objectType;

class DefinitionProvider implements AnnotatedContainerDefinitionProvider {

public function consume(DefinitionProviderContext $context) : void {
service($context, objectType(EventEmitter::class));
service($context, objectType(AmpEventEmitter::class));
service($context, objectType(EventFactory::class));
service($context, objectType(StandardEventFactory::class));
service($context, objectType(Emitter::class));
service($context, objectType(AmpEmitter::class));
}

}
8 changes: 0 additions & 8 deletions src/ListenerRemoval.php

This file was deleted.

48 changes: 7 additions & 41 deletions src/Observer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,56 +5,22 @@
use Cspray\AnnotatedContainer\AnnotatedContainer;
use Cspray\AnnotatedContainer\Bootstrap\ServiceGatherer;
use Cspray\AnnotatedContainer\Bootstrap\ServiceWiringObserver;
use Labrador\AsyncEvent\EventEmitter;
use Labrador\AsyncEvent\Emitter;
use Labrador\AsyncEvent\Listener;
use Labrador\AsyncEvent\ListenerProvider;
use Labrador\AsyncEvent\OneTimeListener;

final class Observer extends ServiceWiringObserver {

protected function wireServices(AnnotatedContainer $container, ServiceGatherer $gatherer) : void {
$emitter = $container->get(EventEmitter::class);
assert($emitter instanceof EventEmitter);
$emitter = $container->get(Emitter::class);
assert($emitter instanceof Emitter);

/** @var Listener $listener */
foreach ($gatherer->getServicesForType(Listener::class) as $listenerAndDefinition) {
$listener = $listenerAndDefinition->getService();
$autowire = $listenerAndDefinition->getDefinition()->getAttribute();
foreach ($gatherer->getServicesWithAttribute(AutowiredListener::class) as $fromServiceDefinition) {
$attribute = $fromServiceDefinition->getDefinition()->getAttribute();
assert($attribute instanceof AutowiredListener);

assert($listener instanceof Listener);

if ($autowire instanceof ListenerService &&
$autowire->getListenerRemoval() === ListenerRemoval::AfterOneEvent) {
$listener = new OneTimeListener($listener);
}

$emitter->register($listener);
$emitter->register($attribute->eventName, $fromServiceDefinition->getService());
}

unset($listenerAndDefinition);

foreach ($gatherer->getServicesForType(ListenerProvider::class) as $providerAndDefinition) {
$provider = $providerAndDefinition->getService();
$autowire = $providerAndDefinition->getDefinition()->getAttribute();

assert($provider instanceof ListenerProvider);

if ($autowire instanceof ListenerService &&
$autowire->getListenerRemoval() === ListenerRemoval::AfterOneEvent) {
$provider = new class($provider) implements ListenerProvider {

public function __construct(
private readonly ListenerProvider $provider
) {}

public function getListener() : Listener {
return new OneTimeListener($this->provider->getListener());
}

};
}

$emitter->register($provider);
}
}
}
8 changes: 4 additions & 4 deletions tests/DefinitionProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

use Cspray\AnnotatedContainer\Definition\ContainerDefinitionBuilder;
use Cspray\AnnotatedContainer\StaticAnalysis\DefinitionProviderContext;
use Labrador\AsyncEvent\AmpEmitter;
use Labrador\AsyncEvent\AmpEventEmitter;
use Labrador\AsyncEvent\Autowire\DefinitionProvider;
use Labrador\AsyncEvent\Emitter;
use Labrador\AsyncEvent\EventEmitter;
use Labrador\AsyncEvent\EventFactory;
use Labrador\AsyncEvent\StandardEventFactory;
Expand Down Expand Up @@ -50,10 +52,8 @@ private function doesContextHaveService(string $service) : bool {

public static function expectedServiceProvider() : array {
return [
EventEmitter::class => [EventEmitter::class],
AmpEventEmitter::class => [AmpEventEmitter::class],
EventFactory::class => [EventFactory::class],
StandardEventFactory::class => [StandardEventFactory::class],
Emitter::class => [Emitter::class],
AmpEmitter::class => [AmpEmitter::class],
];
}

Expand Down
27 changes: 7 additions & 20 deletions tests/ListenerServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,40 @@

namespace Labrador\AsyncEvent\Autowire\Tests;

use Labrador\AsyncEvent\Autowire\ListenerRemoval;
use Labrador\AsyncEvent\Autowire\ListenerService;
use Labrador\AsyncEvent\Autowire\AutowiredListener;
use PHPUnit\Framework\TestCase;

/**
* @covers \Labrador\AsyncEvent\Autowire\ListenerService
* @covers \Labrador\AsyncEvent\Autowire\AutowiredListener
*/
class ListenerServiceTest extends TestCase {

public function testListenerRemovalDefaultsToNeverRemoved() : void {
$subject = new ListenerService();

self::assertSame(ListenerRemoval::NeverRemove, $subject->getListenerRemoval());
}

public function testListenerRemovalRespectsPassedInValues() : void {
$subject = new ListenerService(ListenerRemoval::AfterOneEvent);

self::assertSame(ListenerRemoval::AfterOneEvent, $subject->getListenerRemoval());
}

public function testProfilesDefaultsToEmpty() : void {
$subject = new ListenerService();
$subject = new AutowiredListener('event-name');

self::assertSame([], $subject->getProfiles());
}

public function testProfilesRespectsProvidedValues() : void {
$subject = new ListenerService(profiles: ['foo', 'bar']);
$subject = new AutowiredListener('event-name', profiles: ['foo', 'bar']);

self::assertSame(['foo', 'bar'], $subject->getProfiles());
}

public function testNameDefaultsToNull() : void {
$subject = new ListenerService();
$subject = new AutowiredListener('event-name');

self::assertNull($subject->getName());
}

public function testNameRespectsProvidedValue() : void {
$subject = new ListenerService(name: 'my-listener');
$subject = new AutowiredListener('event-name', name: 'my-listener');

self::assertSame('my-listener', $subject->getName());
}

public function testIsPrimaryAlwaysFalse() : void {
$subject = new ListenerService();
$subject = new AutowiredListener('event-name');

self::assertFalse($subject->isPrimary());
}
Expand Down
26 changes: 17 additions & 9 deletions tests/ObserverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
use Amp\PHPUnit\AsyncTestCase;
use Cspray\AnnotatedContainer\AnnotatedContainer;
use Cspray\AnnotatedContainer\Bootstrap\Bootstrap;
use Labrador\AsyncEvent\AmpEmitter;
use Labrador\AsyncEvent\AmpEventEmitter;
use Labrador\AsyncEvent\Emitter;
use Labrador\AsyncEvent\Event;
use Labrador\AsyncEvent\EventEmitter;
use Labrador\AsyncEvent\StandardEvent;

Expand All @@ -21,25 +24,30 @@ private function getContainer() : AnnotatedContainer {
public function testEmitOneTime() : void {
$container = $this->getContainer();

$emitter = $container->get(EventEmitter::class);
$emitter = $container->get(Emitter::class);

self::assertInstanceOf(AmpEventEmitter::class, $emitter);
self::assertCount(5, $emitter->getListeners('something'));
self::assertInstanceOf(AmpEmitter::class, $emitter);
self::assertCount(3, $emitter->listeners('something'));
}

public function testOneTimeRemovalRespected() : void {
$container = $this->getContainer();

$emitter = $container->get(EventEmitter::class);
$emitter = $container->get(Emitter::class);

self::assertInstanceOf(AmpEventEmitter::class, $emitter);
self::assertInstanceOf(AmpEmitter::class, $emitter);

$first = $emitter->emit(new StandardEvent('something', new \stdClass()))->await();
$event = $this->getMockBuilder(Event::class)->getMock();
$event->expects($this->any())->method('name')->willReturn('something');
$event->expects($this->any())->method('payload')->willReturn(new \stdClass());
$event->expects($this->any())->method('triggeredAt')->willReturn(new \DateTimeImmutable());

$first = $emitter->emit($event)->await();
sort($first);
self::assertSame(['bar', 'baz', 'foo', 'qux', 'zee'], array_values($first));
self::assertSame(['bar', 'baz', 'foo'], array_values($first));

$second = $emitter->emit(new StandardEvent('something', new \stdClass()))->await();
$second = $emitter->emit($event)->await();
sort($second);
self::assertSame(['bar', 'foo', 'qux'], array_values($second));
self::assertSame(['bar', 'foo'], array_values($second));
}
}
11 changes: 4 additions & 7 deletions tests/Stub/BarListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,16 @@
namespace Labrador\AsyncEvent\Autowire\Tests\Stub;

use Amp\Future;
use Labrador\AsyncEvent\AbstractListener;
use Labrador\AsyncEvent\Autowire\ListenerService;
use Labrador\AsyncEvent\Autowire\AutowiredListener;
use Labrador\AsyncEvent\Event;
use Labrador\AsyncEvent\Listener;
use Labrador\CompositeFuture\CompositeFuture;

#[ListenerService]
class BarListener extends AbstractListener {
#[AutowiredListener('something')]
final class BarListener implements Listener {

public function handle(Event $event) : Future|CompositeFuture|null {
return Future::complete('bar');
}

public function canHandle(string $eventName) : bool {
return $eventName === 'something';
}
}
14 changes: 7 additions & 7 deletions tests/Stub/BazListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
namespace Labrador\AsyncEvent\Autowire\Tests\Stub;

use Amp\Future;
use Labrador\AsyncEvent\AbstractListener;
use Labrador\AsyncEvent\Autowire\ListenerRemoval;
use Labrador\AsyncEvent\Autowire\ListenerService;
use Labrador\AsyncEvent\Autowire\AutowiredListener;
use Labrador\AsyncEvent\Event;
use Labrador\AsyncEvent\Listener;
use Labrador\AsyncEvent\ListenerRemovableBasedOnHandleCount;
use Labrador\CompositeFuture\CompositeFuture;

#[ListenerService(ListenerRemoval::AfterOneEvent)]
class BazListener extends AbstractListener {
#[AutowiredListener('something')]
class BazListener implements Listener, ListenerRemovableBasedOnHandleCount {

public function handle(Event $event) : Future|CompositeFuture|null {
return Future::complete('baz');
}

public function canHandle(string $eventName) : bool {
return $eventName === 'something';
public function handleLimit() : int {
return 1;
}
}
Loading

0 comments on commit 2cbb9d9

Please sign in to comment.