Skip to content

Commit 49fecfe

Browse files
committed
fix: improve psalm for fluent interface
1 parent e20fce6 commit 49fecfe

File tree

4 files changed

+97
-1
lines changed

4 files changed

+97
-1
lines changed

src/Utils/Test/src/Fluent/SpanAssertion.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ public function withAttributes(array $attributes): self
231231
*
232232
* @psalm-suppress PossiblyUnusedMethod
233233
*
234-
* @param int|Constraint $code The expected status code
234+
* @param string|Constraint $code The expected status code
235235
* @param string|Constraint|null $description The expected status description
236236
* @throws TraceAssertionFailedException
237237
* @return self
@@ -509,6 +509,21 @@ public function hasChild($name): SpanAssertion
509509
return new SpanAssertion($matchingSpan, $this->traceAssertion, $this, $this->expectedStructure, $this->actualStructure);
510510
}
511511

512+
/**
513+
* Assert that the span has a root span with the given name.
514+
* This is a convenience method that delegates to the trace assertion.
515+
*
516+
* @psalm-suppress PossiblyUnusedMethod
517+
*
518+
* @param string|Constraint $name The expected name of the root span
519+
* @throws TraceAssertionFailedException
520+
* @return SpanAssertion
521+
*/
522+
public function hasRootSpan($name): SpanAssertion
523+
{
524+
return $this->traceAssertion->hasRootSpan($name);
525+
}
526+
512527
/**
513528
* Assert that the span has the expected number of children.
514529
*

src/Utils/Test/src/Fluent/SpanEventAssertion.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ public function withAttributes(array $attributes): self
155155
/**
156156
* Return to the parent span assertion.
157157
*
158+
* @psalm-suppress UnusedMethodCall
158159
* @return SpanAssertion
159160
*/
160161
public function end(): SpanAssertion

src/Utils/Test/src/Fluent/TraceAssertion.php

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,74 @@ public function hasRootSpan($name): SpanAssertion
139139
return new SpanAssertion($matchingSpan, $this, null, $this->expectedStructure, $this->actualStructure);
140140
}
141141

142+
/**
143+
* Assert that the trace has a child span with the expected name.
144+
*
145+
* @param string|Constraint $name The expected child span name
146+
* @throws TraceAssertionFailedException
147+
* @return SpanAssertion
148+
*/
149+
public function hasChild($name): SpanAssertion
150+
{
151+
// Find the matching span
152+
$matchingSpan = null;
153+
154+
if ($name instanceof Constraint) {
155+
foreach ($this->spans as $span) {
156+
try {
157+
Assert::assertThat(
158+
$span->getName(),
159+
$name,
160+
'Span name does not match constraint'
161+
);
162+
$matchingSpan = $span;
163+
164+
break;
165+
} catch (AssertionFailedError $e) {
166+
// This span doesn't match the constraint, skip it
167+
continue;
168+
}
169+
}
170+
} else {
171+
foreach ($this->spans as $span) {
172+
if ($span->getName() === $name) {
173+
$matchingSpan = $span;
174+
175+
break;
176+
}
177+
}
178+
}
179+
180+
if (!$matchingSpan) {
181+
// Record the actual result
182+
$this->actualStructure[] = [
183+
'type' => 'missing_child_span',
184+
'expected_name' => $name instanceof Constraint ? 'constraint' : $name,
185+
'available_spans' => array_map(function ($span) {
186+
return $span->getName();
187+
}, $this->spans),
188+
];
189+
190+
throw new TraceAssertionFailedException(
191+
sprintf(
192+
'No span matching name "%s" found',
193+
$name instanceof Constraint ? 'constraint' : $name
194+
),
195+
$this->expectedStructure,
196+
$this->actualStructure
197+
);
198+
}
199+
200+
// Record the actual result
201+
$this->actualStructure[] = [
202+
'type' => 'child_span',
203+
'name' => $matchingSpan->getName(),
204+
'span' => $matchingSpan,
205+
];
206+
207+
return new SpanAssertion($matchingSpan, $this, null, $this->expectedStructure, $this->actualStructure);
208+
}
209+
142210
/**
143211
* Assert that the trace has the expected number of root spans.
144212
*
@@ -219,6 +287,17 @@ public function isStrict(): bool
219287
return $this->strict;
220288
}
221289

290+
/**
291+
* Return the trace assertion itself.
292+
* This method is used to maintain a consistent fluent interface.
293+
*
294+
* @return self
295+
*/
296+
public function end(): self
297+
{
298+
return $this;
299+
}
300+
222301
/**
223302
* Converts spans to an array if they are in a different format.
224303
*

src/Utils/Test/tests/Unit/TraceAssertionFailedExceptionTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ public function test_trace_assertion_failed_exception_provides_visual_diff_for_m
146146

147147
/**
148148
* Test that the TraceAssertionFailedException provides a visual diff when a span event is missing.
149+
* @psalm-suppress UnusedMethodCall
149150
*/
150151
public function test_trace_assertion_failed_exception_provides_visual_diff_for_missing_event(): void
151152
{

0 commit comments

Comments
 (0)