Skip to content

Commit 19c86fc

Browse files
Update event assertions (#168)
* Add event dispatch assertions, event listener call assertions (deprecate existing ones) * fix wrong method call * Remove duplicated methods, fix PHPCS warnings * Restore lost deprecation warnings, reorder methods to keep in line with upstream * Update seeEventListenerCalled/dontSeeEventListenerCalled to support check with event --------- Co-authored-by: TavoNiievez <ganieves@outlook.com>
1 parent cb13340 commit 19c86fc

File tree

1 file changed

+89
-10
lines changed

1 file changed

+89
-10
lines changed

src/Codeception/Module/Symfony/EventsAssertionsTrait.php

Lines changed: 89 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Symfony\Component\HttpKernel\DataCollector\EventDataCollector;
88
use Symfony\Component\VarDumper\Cloner\Data;
9+
910
use function is_array;
1011
use function is_object;
1112

@@ -53,11 +54,14 @@ public function dontSeeOrphanEvent(array|object|string $expected = null): void
5354
* ```
5455
*
5556
* @param object|string|string[] $expected
56-
* @deprecated Use `dontSeeEventListenerIsCalled()` instead.
57+
* @deprecated Use `dontSeeEventListenerIsCalled` instead.
5758
*/
5859
public function dontSeeEventTriggered(array|object|string $expected): void
5960
{
60-
trigger_error('dontSeeEventTriggered is deprecated, please use dontSeeEventListenerIsCalled instead', E_USER_DEPRECATED);
61+
trigger_error(
62+
'dontSeeEventTriggered is deprecated, please use dontSeeEventListenerIsCalled instead',
63+
E_USER_DEPRECATED
64+
);
6165
$this->dontSeeEventListenerIsCalled($expected);
6266
}
6367

@@ -69,18 +73,28 @@ public function dontSeeEventTriggered(array|object|string $expected): void
6973
* $I->dontSeeEventListenerIsCalled('App\MyEventListener');
7074
* $I->dontSeeEventListenerIsCalled(new App\Events\MyEventListener());
7175
* $I->dontSeeEventListenerIsCalled(['App\MyEventListener', 'App\MyOtherEventListener']);
76+
* $I->dontSeeEventListenerIsCalled('App\MyEventListener', 'my.event);
77+
* $I->dontSeeEventListenerIsCalled(new App\Events\MyEventListener(), new MyEvent());
78+
* $I->dontSeeEventListenerIsCalled('App\MyEventListener', ['my.event', 'my.other.event']);
7279
* ```
7380
*
7481
* @param object|string|string[] $expected
7582
*/
76-
public function dontSeeEventListenerIsCalled(array|object|string $expected): void
77-
{
83+
public function dontSeeEventListenerIsCalled(
84+
array|object|string $expected,
85+
array|object|string $withEvents = []
86+
): void {
7887
$eventCollector = $this->grabEventCollector(__FUNCTION__);
7988

8089
$data = $eventCollector->getCalledListeners();
8190
$expected = is_array($expected) ? $expected : [$expected];
91+
$withEvents = is_array($withEvents) ? $withEvents : [$withEvents];
92+
93+
if (!empty($withEvents) && count($expected) > 1) {
94+
$this->fail('You cannot check for events when using multiple listeners. Make multiple assertions instead.');
95+
}
8296

83-
$this->assertEventNotTriggered($data, $expected);
97+
$this->assertListenerCalled($data, $expected, $withEvents, true);
8498
}
8599

86100
/**
@@ -120,11 +134,14 @@ public function seeOrphanEvent(array|object|string $expected): void
120134
* ```
121135
*
122136
* @param object|string|string[] $expected
123-
* @deprecated Use `seeEventListenerIsCalled()` instead.
137+
* @deprecated Use `seeEventListenerIsCalled` instead.
124138
*/
125139
public function seeEventTriggered(array|object|string $expected): void
126140
{
127-
trigger_error('seeEventTriggered is deprecated, please use seeEventListenerIsCalled instead', E_USER_DEPRECATED);
141+
trigger_error(
142+
'seeEventTriggered is deprecated, please use seeEventListenerIsCalled instead',
143+
E_USER_DEPRECATED
144+
);
128145
$this->seeEventListenerIsCalled($expected);
129146
}
130147

@@ -136,18 +153,28 @@ public function seeEventTriggered(array|object|string $expected): void
136153
* $I->seeEventListenerIsCalled('App\MyEventListener');
137154
* $I->seeEventListenerIsCalled(new App\Events\MyEventListener());
138155
* $I->seeEventListenerIsCalled(['App\MyEventListener', 'App\MyOtherEventListener']);
156+
* $I->seeEventListenerIsCalled('App\MyEventListener', 'my.event);
157+
* $I->seeEventListenerIsCalled(new App\Events\MyEventListener(), new MyEvent());
158+
* $I->seeEventListenerIsCalled('App\MyEventListener', ['my.event', 'my.other.event']);
139159
* ```
140160
*
141161
* @param object|string|string[] $expected
142162
*/
143-
public function seeEventListenerIsCalled(array|object|string $expected): void
144-
{
163+
public function seeEventListenerIsCalled(
164+
array|object|string $expected,
165+
array|object|string $withEvents = []
166+
): void {
145167
$eventCollector = $this->grabEventCollector(__FUNCTION__);
146168

147169
$data = $eventCollector->getCalledListeners();
148170
$expected = is_array($expected) ? $expected : [$expected];
171+
$withEvents = is_array($withEvents) ? $withEvents : [$withEvents];
149172

150-
$this->assertEventTriggered($data, $expected);
173+
if (!empty($withEvents) && count($expected) > 1) {
174+
$this->fail('You cannot check for events when using multiple listeners. Make multiple assertions instead.');
175+
}
176+
177+
$this->assertListenerCalled($data, $expected, $withEvents);
151178
}
152179

153180
protected function assertEventNotTriggered(Data $data, array $expected): void
@@ -180,6 +207,39 @@ protected function assertEventTriggered(Data $data, array $expected): void
180207
}
181208
}
182209

210+
protected function assertListenerCalled(
211+
Data $data,
212+
array $expectedListeners,
213+
array $withEvents,
214+
bool $invertAssertion = false
215+
): void {
216+
$assertTrue = !$invertAssertion;
217+
218+
if ($assertTrue && $data->count() === 0) {
219+
$this->fail('No event listener was called');
220+
}
221+
222+
$actual = $data->getValue(true);
223+
$expectedEvents = empty($withEvents) ? [null] : $withEvents;
224+
225+
foreach ($expectedListeners as $expectedListener) {
226+
$expectedListener = is_object($expectedListener) ? $expectedListener::class : $expectedListener;
227+
228+
foreach ($expectedEvents as $expectedEvent) {
229+
$message = "The '{$expectedListener}' listener was called"
230+
. ($expectedEvent ? " for the '{$expectedEvent}' event" : '');
231+
232+
$condition = $this->listenerWasCalled($actual, $expectedListener, $expectedEvent);
233+
234+
if ($assertTrue) {
235+
$this->assertTrue($condition, $message);
236+
} else {
237+
$this->assertFalse($condition, $message);
238+
}
239+
}
240+
}
241+
}
242+
183243
protected function eventWasTriggered(array $actual, string $expectedEvent): bool
184244
{
185245
$triggered = false;
@@ -195,9 +255,28 @@ protected function eventWasTriggered(array $actual, string $expectedEvent): bool
195255
}
196256
}
197257
}
258+
198259
return $triggered;
199260
}
200261

262+
protected function listenerWasCalled(array $actual, string $expectedListener, string|null $expectedEvent): bool
263+
{
264+
$called = false;
265+
266+
foreach ($actual as $actualEvent) {
267+
// Called Listeners
268+
if (is_array($actualEvent) && str_starts_with($actualEvent['pretty'], $expectedListener)) {
269+
if ($expectedEvent === null) {
270+
$called = true;
271+
} elseif ($actualEvent['event'] === $expectedEvent) {
272+
$called = true;
273+
}
274+
}
275+
}
276+
277+
return $called;
278+
}
279+
201280
protected function grabEventCollector(string $function): EventDataCollector
202281
{
203282
return $this->grabCollector('events', $function);

0 commit comments

Comments
 (0)