1616use PHPUnit \Event \Tracer \Tracer as TracerInterface ;
1717use ReflectionClass ;
1818
19+ use function array_key_last ;
20+ use function array_map ;
21+ use function array_slice ;
22+ use function assert ;
23+ use function file ;
24+ use function file_put_contents ;
25+ use function implode ;
26+ use function is_array ;
27+ use function is_string ;
28+ use function json_encode ;
29+ use function preg_match ;
30+ use function str_replace ;
31+ use function str_starts_with ;
32+ use function substr ;
33+ use function trim ;
34+
35+ use const JSON_INVALID_UTF8_SUBSTITUTE ;
36+ use const JSON_PRETTY_PRINT ;
37+
1938final class Tracer implements TracerInterface
2039{
2140 /** Enable to add all events to result JSON */
22- private const DEBUG_ALL_EVENTS = false ;
41+ private const bool DEBUG_ALL_EVENTS = false ;
2342
2443 /** Enable to pretty print result JSON */
25- private const DEBUG_PRETTY_JSON = false ;
44+ private const bool DEBUG_PRETTY_JSON = false ;
2645
2746 /**
2847 * Represents the result of the test run for Exercism
48+ *
2949 * @see https://exercism.org/docs/building/tooling/test-runners/interface#h-top-level
30- * @var array{version: int, status: string, tests: list<Result>, messsage: string}
50+ *
51+ * @var array{version: int, status: string, tests: list<Result>, messsage?: string}
3152 */
3253 private array $ result = [
3354 'version ' => 3 ,
@@ -44,19 +65,18 @@ public function __construct(
4465
4566 public function trace (Event $ event ): void
4667 {
47- match (\get_class ( $ event) ) {
68+ match ($ event::class ) {
4869 Passed::class => $ this ->addTestPassed ($ event ),
4970 Failed::class => $ this ->addTestFailed ($ event ),
5071 Errored::class => $ this ->addTestErrored ($ event ),
5172 BeforeFirstTestMethodErrored::class => $ this ->addBeforeFirstTestMethodErrored ($ event ),
5273 PrintedUnexpectedOutput::class => $ this ->addTestOutput ($ event ),
53- default => self :: DEBUG_ALL_EVENTS
74+ default => self ::DEBUG_ALL_EVENTS // @phpstan-ignore ternary.alwaysFalse
5475 ? $ this ->addUnhandledEvent ($ event )
5576 : true
5677 ,
5778 };
5879
59-
6080 if ($ event instanceof Finished) {
6181 $ this ->saveResults ();
6282 }
@@ -73,8 +93,9 @@ private function addUnhandledEvent(Event $event): void
7393
7494 private function addTestPassed (Passed $ event ): void
7595 {
76- /** @var TestMethod */
96+ /** @var TestMethod $testMethod */
7797 $ testMethod = $ event ->test ();
98+ assert ($ testMethod instanceof TestMethod);
7899
79100 $ this ->result ['tests ' ][] = new Result (
80101 $ testMethod ->testDox ()->prettifiedMethodName (),
@@ -86,14 +107,15 @@ private function addTestPassed(Passed $event): void
86107
87108 private function addTestFailed (Failed $ event ): void
88109 {
89- /** @var TestMethod */
110+ /** @var TestMethod $testMethod */
90111 $ testMethod = $ event ->test ();
112+ assert ($ testMethod instanceof TestMethod);
91113
92- $ phpUnitMessage = \ trim ($ event ->throwable ()->asString ());
93- $ phpUnitMessage = \ str_replace (
114+ $ phpUnitMessage = trim ($ event ->throwable ()->asString ());
115+ $ phpUnitMessage = str_replace (
94116 $ this ->exerciseDir . '/ ' ,
95117 '' ,
96- $ phpUnitMessage
118+ $ phpUnitMessage,
97119 );
98120 $ phpUnitMessage = $ testMethod ->nameWithClass () . "\n" . $ phpUnitMessage ;
99121
@@ -109,14 +131,15 @@ private function addTestFailed(Failed $event): void
109131
110132 private function addTestErrored (Errored $ event ): void
111133 {
112- /** @var TestMethod */
134+ /** @var TestMethod $testMethod */
113135 $ testMethod = $ event ->test ();
136+ assert ($ testMethod instanceof TestMethod);
114137
115- $ phpUnitMessage = \ trim ($ event ->throwable ()->asString ());
116- $ phpUnitMessage = \ str_replace (
138+ $ phpUnitMessage = trim ($ event ->throwable ()->asString ());
139+ $ phpUnitMessage = str_replace (
117140 $ this ->exerciseDir . '/ ' ,
118141 '' ,
119- $ phpUnitMessage
142+ $ phpUnitMessage,
120143 );
121144 $ phpUnitMessage = $ testMethod ->nameWithClass () . "\n" . $ phpUnitMessage ;
122145
@@ -132,11 +155,11 @@ private function addTestErrored(Errored $event): void
132155
133156 private function addBeforeFirstTestMethodErrored (BeforeFirstTestMethodErrored $ event ): void
134157 {
135- $ phpUnitMessage = \ trim ($ event ->throwable ()->asString ());
136- $ phpUnitMessage = \ str_replace (
158+ $ phpUnitMessage = trim ($ event ->throwable ()->asString ());
159+ $ phpUnitMessage = str_replace (
137160 $ this ->exerciseDir . '/ ' ,
138161 '' ,
139- $ phpUnitMessage
162+ $ phpUnitMessage,
140163 );
141164
142165 $ this ->result ['status ' ] = 'error ' ;
@@ -147,8 +170,8 @@ private function addTestOutput(PrintedUnexpectedOutput $event): void
147170 {
148171 // This must rely on the sequence of events!
149172
150- /** @var Result */
151- $ lastTest = $ this ->result ['tests ' ][\ array_key_last ($ this ->result ['tests ' ])];
173+ /** @var Result $lastTest */
174+ $ lastTest = $ this ->result ['tests ' ][array_key_last ($ this ->result ['tests ' ])];
152175 $ lastTest ->setUserOutput ($ event ->output ());
153176 }
154177
@@ -161,12 +184,12 @@ private function saveResults(): void
161184 }
162185 }
163186
164- \ file_put_contents (
187+ file_put_contents (
165188 $ this ->outFileName ,
166- \ json_encode (
189+ json_encode (
167190 $ this ->result ,
168191 JSON_INVALID_UTF8_SUBSTITUTE
169- | (self ::DEBUG_PRETTY_JSON ? JSON_PRETTY_PRINT : 0 )
192+ | (self ::DEBUG_PRETTY_JSON ? JSON_PRETTY_PRINT : 0 ), // @phpstan-ignore ternary.alwaysFalse
170193 ) . "\n" ,
171194 );
172195 }
@@ -186,22 +209,22 @@ private function methodCode(TestMethod $testMethod): string
186209 $ start = $ reflectionMethod ->getStartLine () - 1 + 2 ;
187210 $ length = $ reflectionMethod ->getEndLine () - 1 - $ start ;
188211
189- $ codeLines = \array_slice (
190- \file ($ reflectionMethod ->getFileName ()),
191- $ start ,
192- $ length ,
193- );
212+ $ testFileName = $ reflectionMethod ->getFileName ();
213+ assert (is_string ($ testFileName ));
214+ $ testCodeLines = file ($ testFileName );
215+ assert (is_array ($ testCodeLines ));
216+
217+ $ codeLines = array_slice ($ testCodeLines , $ start , $ length );
194218
195219 // Unindent lines 2 levels of 4 spaces each (if possible)
196- $ codeLines = \array_map (
197- fn ($ line ) => \str_starts_with ($ line , ' ' )
198- ? \substr ($ line , 2 * 4 )
199- : $ line
200- ,
220+ $ codeLines = array_map (
221+ static fn ($ line ) => str_starts_with ($ line , ' ' )
222+ ? substr ($ line , 2 * 4 )
223+ : $ line ,
201224 $ codeLines ,
202225 );
203226
204- return \ implode ('' , $ codeLines );
227+ return implode ('' , $ codeLines );
205228 }
206229
207230 private function taskId (TestMethod $ testMethod ): int
@@ -213,8 +236,8 @@ private function taskId(TestMethod $testMethod): int
213236 return 0 ;
214237 }
215238
216- $ matches= [];
217- $ matchCount = \ preg_match ('/@task_id\s+(\d+)/ ' , $ docComment , $ matches );
239+ $ matches = [];
240+ $ matchCount = preg_match ('/@task_id\s+(\d+)/ ' , $ docComment , $ matches );
218241
219242 return $ matchCount >= 1 ? (int )$ matches [1 ] : 0 ;
220243 }
0 commit comments