@@ -299,6 +299,29 @@ final class SpanTests: XCTestCase {
299299 XCTAssertFalse ( span. isRoot)
300300 }
301301
302+ func testOverlapsInterval( ) {
303+ let traceId = Identifiers . generateTraceId ( )
304+ let t = ContinuousClock . now
305+
306+ func makeSpan( start: Duration , end: Duration ) -> Span {
307+ Span ( name: " test " , startTime: t + start, endTime: t + end, traceId: traceId, parentId: nil )
308+ }
309+
310+ let span = makeSpan ( start: . seconds( 2 ) , end: . seconds( 4 ) )
311+
312+ // Overlapping cases
313+ XCTAssertTrue ( span. overlapsInterval ( t + . seconds( 1 ) , endInterval: t + . seconds( 5 ) ) , " interval encompasses span " )
314+ XCTAssertTrue ( span. overlapsInterval ( t + . seconds( 3 ) , endInterval: t + . seconds( 3 ) ) , " span encompasses interval " )
315+ XCTAssertTrue ( span. overlapsInterval ( t + . seconds( 1 ) , endInterval: t + . seconds( 3 ) ) , " overlap at start " )
316+ XCTAssertTrue ( span. overlapsInterval ( t + . seconds( 3 ) , endInterval: t + . seconds( 5 ) ) , " overlap at end " )
317+ XCTAssertTrue ( span. overlapsInterval ( t + . seconds( 2 ) , endInterval: t + . seconds( 4 ) ) , " exact match " )
318+ XCTAssertTrue ( span. overlapsInterval ( t + . seconds( 4 ) , endInterval: t + . seconds( 5 ) ) , " shared endpoint " )
319+
320+ // Non-overlapping cases
321+ XCTAssertFalse ( span. overlapsInterval ( t + . seconds( 0 ) , endInterval: t + . seconds( 1 ) ) , " entirely before " )
322+ XCTAssertFalse ( span. overlapsInterval ( t + . seconds( 5 ) , endInterval: t + . seconds( 6 ) ) , " entirely after " )
323+ }
324+
302325 func testSpanSubscript( ) {
303326 let span = tracer. startSpan ( name: " test " )
304327 span [ " key1 " ] = " value1 "
0 commit comments