Skip to content

Commit

Permalink
feat(Testing): AssertEventListeners: Prevent other listeners to be fired
Browse files Browse the repository at this point in the history
  • Loading branch information
pionl committed Jun 23, 2023
1 parent 3ed5fdb commit b35f53d
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
23 changes: 20 additions & 3 deletions src/Testing/Concerns/AssertEventListeners.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,35 @@ public function assertEventListeners(

$asserts = [];

/**
* The goal is to prevent other listeners from being called, so we will remove all listeners for the event and
* validate if the desired listeners were registered. Then we will re-register the listener we want and call the
* event again to validate the results.
*
* @var Dispatcher $events
*/
$events = $app->make(Dispatcher::class);
$currentListenersMap = array_flip($events->getRawListeners()[$event::class] ?? []);
$events->forget($event::class);

foreach ($contractMap as $contract => $assert) {
if ($shouldBuildResults) {
$expectedListenerResults[] = null;
}

// Listener must be registered for the event, if not we will fail
Assert::assertArrayHasKey(
$contract,
$currentListenersMap,
sprintf('Listener not %s registered for event: %s', $contract, $event::class)
);

$asserts[] = $assert;

$app->bind(abstract: $contract, concrete: static fn () => $assert);
}

/** @var Dispatcher $events */
$events = $app->make(Dispatcher::class);
$events->listen($event::class, $contract);
}

if ($disableWildcard) {
$events->forget('*');
Expand Down
2 changes: 2 additions & 0 deletions tests/Feature/Testing/Concerns/AssertEventListenersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public function testAssertEventListeners(): void
$events = $app->get(Dispatcher::class);
$events->listen(TestEvent::class, TestListenerContract::class);
$events->listen(TestEvent::class, TestListenerCallsContract::class);
// Should not be called - it will be un-registered.
$events->listen(TestEvent::class, TestListenerCallsContractAssert::class);

$event = new TestEvent();
$this->assertEventListeners(
Expand Down

0 comments on commit b35f53d

Please sign in to comment.