Skip to content

Commit a7dbfad

Browse files
Implement missing events for errors in hook methods
1 parent cdaeb14 commit a7dbfad

28 files changed

+1138
-6
lines changed

ChangeLog-10.5.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes of the PHPUnit 10.5 release series are documented in this fi
44

55
## [10.5.41] - 2025-MM-DD
66

7+
### Added
8+
9+
* `Test\AfterLastTestMethodErrored`, `Test\AfterTestMethodErrored`, `Test\BeforeTestMethodErrored`, `Test\PostConditionErrored`, and `Test\PreConditionErrored` events
10+
711
### Fixed
812

913
* [#6095](https://github.com/sebastianbergmann/phpunit/issues/6095): Expectation is not counted correctly when a doubled method is called more often than is expected

src/Event/Emitter/DispatchingEmitter.php

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,24 @@ public function testBeforeTestMethodCalled(string $testClassName, ClassMethod $c
401401
);
402402
}
403403

404+
/**
405+
* @psalm-param class-string $testClassName
406+
*
407+
* @throws InvalidArgumentException
408+
* @throws UnknownEventTypeException
409+
*/
410+
public function testBeforeTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void
411+
{
412+
$this->dispatcher->dispatch(
413+
new Test\BeforeTestMethodErrored(
414+
$this->telemetryInfo(),
415+
$testClassName,
416+
$calledMethod,
417+
$throwable,
418+
),
419+
);
420+
}
421+
404422
/**
405423
* @psalm-param class-string $testClassName
406424
*
@@ -435,6 +453,24 @@ public function testPreConditionCalled(string $testClassName, ClassMethod $calle
435453
);
436454
}
437455

456+
/**
457+
* @psalm-param class-string $testClassName
458+
*
459+
* @throws InvalidArgumentException
460+
* @throws UnknownEventTypeException
461+
*/
462+
public function testPreConditionErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void
463+
{
464+
$this->dispatcher->dispatch(
465+
new Test\PreConditionErrored(
466+
$this->telemetryInfo(),
467+
$testClassName,
468+
$calledMethod,
469+
$throwable,
470+
),
471+
);
472+
}
473+
438474
/**
439475
* @psalm-param class-string $testClassName
440476
*
@@ -1023,6 +1059,24 @@ public function testPostConditionCalled(string $testClassName, ClassMethod $call
10231059
);
10241060
}
10251061

1062+
/**
1063+
* @psalm-param class-string $testClassName
1064+
*
1065+
* @throws InvalidArgumentException
1066+
* @throws UnknownEventTypeException
1067+
*/
1068+
public function testPostConditionErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void
1069+
{
1070+
$this->dispatcher->dispatch(
1071+
new Test\PostConditionErrored(
1072+
$this->telemetryInfo(),
1073+
$testClassName,
1074+
$calledMethod,
1075+
$throwable,
1076+
),
1077+
);
1078+
}
1079+
10261080
/**
10271081
* @psalm-param class-string $testClassName
10281082
*
@@ -1057,6 +1111,24 @@ public function testAfterTestMethodCalled(string $testClassName, ClassMethod $ca
10571111
);
10581112
}
10591113

1114+
/**
1115+
* @psalm-param class-string $testClassName
1116+
*
1117+
* @throws InvalidArgumentException
1118+
* @throws UnknownEventTypeException
1119+
*/
1120+
public function testAfterTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void
1121+
{
1122+
$this->dispatcher->dispatch(
1123+
new Test\AfterTestMethodErrored(
1124+
$this->telemetryInfo(),
1125+
$testClassName,
1126+
$calledMethod,
1127+
$throwable,
1128+
),
1129+
);
1130+
}
1131+
10601132
/**
10611133
* @psalm-param class-string $testClassName
10621134
*
@@ -1091,6 +1163,24 @@ public function testAfterLastTestMethodCalled(string $testClassName, ClassMethod
10911163
);
10921164
}
10931165

1166+
/**
1167+
* @psalm-param class-string $testClassName
1168+
*
1169+
* @throws InvalidArgumentException
1170+
* @throws UnknownEventTypeException
1171+
*/
1172+
public function testAfterLastTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void
1173+
{
1174+
$this->dispatcher->dispatch(
1175+
new Test\AfterLastTestMethodErrored(
1176+
$this->telemetryInfo(),
1177+
$testClassName,
1178+
$calledMethod,
1179+
$throwable,
1180+
),
1181+
);
1182+
}
1183+
10941184
/**
10951185
* @psalm-param class-string $testClassName
10961186
*

src/Event/Emitter/Emitter.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ public function testBeforeFirstTestMethodFinished(string $testClassName, ClassMe
9595
*/
9696
public function testBeforeTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void;
9797

98+
/**
99+
* @psalm-param class-string $testClassName
100+
*/
101+
public function testBeforeTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void;
102+
98103
/**
99104
* @psalm-param class-string $testClassName
100105
*/
@@ -105,6 +110,11 @@ public function testBeforeTestMethodFinished(string $testClassName, ClassMethod
105110
*/
106111
public function testPreConditionCalled(string $testClassName, ClassMethod $calledMethod): void;
107112

113+
/**
114+
* @psalm-param class-string $testClassName
115+
*/
116+
public function testPreConditionErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void;
117+
108118
/**
109119
* @psalm-param class-string $testClassName
110120
*/
@@ -267,6 +277,11 @@ public function testFinished(Code\Test $test, int $numberOfAssertionsPerformed):
267277
*/
268278
public function testPostConditionCalled(string $testClassName, ClassMethod $calledMethod): void;
269279

280+
/**
281+
* @psalm-param class-string $testClassName
282+
*/
283+
public function testPostConditionErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void;
284+
270285
/**
271286
* @psalm-param class-string $testClassName
272287
*/
@@ -277,6 +292,11 @@ public function testPostConditionFinished(string $testClassName, ClassMethod ...
277292
*/
278293
public function testAfterTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void;
279294

295+
/**
296+
* @psalm-param class-string $testClassName
297+
*/
298+
public function testAfterTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void;
299+
280300
/**
281301
* @psalm-param class-string $testClassName
282302
*/
@@ -287,6 +307,11 @@ public function testAfterTestMethodFinished(string $testClassName, ClassMethod .
287307
*/
288308
public function testAfterLastTestMethodCalled(string $testClassName, ClassMethod $calledMethod): void;
289309

310+
/**
311+
* @psalm-param class-string $testClassName
312+
*/
313+
public function testAfterLastTestMethodErrored(string $testClassName, ClassMethod $calledMethod, Throwable $throwable): void;
314+
290315
/**
291316
* @psalm-param class-string $testClassName
292317
*/
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace PHPUnit\Event\Test;
11+
12+
use const PHP_EOL;
13+
use function sprintf;
14+
use PHPUnit\Event\Code;
15+
use PHPUnit\Event\Code\Throwable;
16+
use PHPUnit\Event\Event;
17+
use PHPUnit\Event\Telemetry;
18+
19+
/**
20+
* @psalm-immutable
21+
*
22+
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
23+
*/
24+
final class AfterLastTestMethodErrored implements Event
25+
{
26+
private readonly Telemetry\Info $telemetryInfo;
27+
28+
/**
29+
* @psalm-var class-string
30+
*/
31+
private readonly string $testClassName;
32+
private readonly Code\ClassMethod $calledMethod;
33+
private readonly Throwable $throwable;
34+
35+
/**
36+
* @psalm-param class-string $testClassName
37+
*/
38+
public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod, Throwable $throwable)
39+
{
40+
$this->telemetryInfo = $telemetryInfo;
41+
$this->testClassName = $testClassName;
42+
$this->calledMethod = $calledMethod;
43+
$this->throwable = $throwable;
44+
}
45+
46+
public function telemetryInfo(): Telemetry\Info
47+
{
48+
return $this->telemetryInfo;
49+
}
50+
51+
/**
52+
* @psalm-return class-string
53+
*/
54+
public function testClassName(): string
55+
{
56+
return $this->testClassName;
57+
}
58+
59+
public function calledMethod(): Code\ClassMethod
60+
{
61+
return $this->calledMethod;
62+
}
63+
64+
public function throwable(): Throwable
65+
{
66+
return $this->throwable;
67+
}
68+
69+
public function asString(): string
70+
{
71+
$message = $this->throwable->message();
72+
73+
if (!empty($message)) {
74+
$message = PHP_EOL . $message;
75+
}
76+
77+
return sprintf(
78+
'After Last Test Method Errored (%s::%s)%s',
79+
$this->calledMethod->className(),
80+
$this->calledMethod->methodName(),
81+
$message,
82+
);
83+
}
84+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace PHPUnit\Event\Test;
11+
12+
use PHPUnit\Event\Subscriber;
13+
14+
/**
15+
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
16+
*/
17+
interface AfterLastTestMethodErroredSubscriber extends Subscriber
18+
{
19+
public function notify(AfterLastTestMethodErrored $event): void;
20+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace PHPUnit\Event\Test;
11+
12+
use const PHP_EOL;
13+
use function sprintf;
14+
use PHPUnit\Event\Code;
15+
use PHPUnit\Event\Code\Throwable;
16+
use PHPUnit\Event\Event;
17+
use PHPUnit\Event\Telemetry;
18+
19+
/**
20+
* @psalm-immutable
21+
*
22+
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
23+
*/
24+
final class AfterTestMethodErrored implements Event
25+
{
26+
private readonly Telemetry\Info $telemetryInfo;
27+
28+
/**
29+
* @psalm-var class-string
30+
*/
31+
private readonly string $testClassName;
32+
private readonly Code\ClassMethod $calledMethod;
33+
private readonly Throwable $throwable;
34+
35+
/**
36+
* @psalm-param class-string $testClassName
37+
*/
38+
public function __construct(Telemetry\Info $telemetryInfo, string $testClassName, Code\ClassMethod $calledMethod, Throwable $throwable)
39+
{
40+
$this->telemetryInfo = $telemetryInfo;
41+
$this->testClassName = $testClassName;
42+
$this->calledMethod = $calledMethod;
43+
$this->throwable = $throwable;
44+
}
45+
46+
public function telemetryInfo(): Telemetry\Info
47+
{
48+
return $this->telemetryInfo;
49+
}
50+
51+
/**
52+
* @psalm-return class-string
53+
*/
54+
public function testClassName(): string
55+
{
56+
return $this->testClassName;
57+
}
58+
59+
public function calledMethod(): Code\ClassMethod
60+
{
61+
return $this->calledMethod;
62+
}
63+
64+
public function throwable(): Throwable
65+
{
66+
return $this->throwable;
67+
}
68+
69+
public function asString(): string
70+
{
71+
$message = $this->throwable->message();
72+
73+
if (!empty($message)) {
74+
$message = PHP_EOL . $message;
75+
}
76+
77+
return sprintf(
78+
'After Test Method Errored (%s::%s)%s',
79+
$this->calledMethod->className(),
80+
$this->calledMethod->methodName(),
81+
$message,
82+
);
83+
}
84+
}

0 commit comments

Comments
 (0)