diff --git a/Sources/Testing/Issues/Issue+Recording.swift b/Sources/Testing/Issues/Issue+Recording.swift index b79e94269..b03217280 100644 --- a/Sources/Testing/Issues/Issue+Recording.swift +++ b/Sources/Testing/Issues/Issue+Recording.swift @@ -92,6 +92,34 @@ extension Issue { let issue = Issue(kind: .unconditional, severity: severity, comments: Array(comment), sourceContext: sourceContext) return issue.record() } + + /// Record an issue when a running test fails unexpectedly. + /// + /// - Parameters: + /// - comment: A comment describing the expectation. + /// - severity: The severity of the issue. + /// - sourceLocation: The source location to which the issue should be + /// attributed. + /// - kind: The kind of the issue. + /// + /// - Returns: The issue that was recorded. + /// + /// Use this function if, while running a test, an issue occurs that cannot be + /// represented as an expectation (using the ``expect(_:_:sourceLocation:)`` + /// or ``require(_:_:sourceLocation:)-5l63q`` macros.) + @_spi(Experimental) + @_spi(ForToolsIntegrationOnly) + @discardableResult public static func record( + kind: Kind = .unconditional, + comment: Comment? = nil, + severity: Severity = .error, + sourceLocation: SourceLocation = #_sourceLocation + ) -> Self { + let sourceContext = SourceContext(backtrace: .current(), sourceLocation: sourceLocation) + let issue = Issue(kind: kind, severity: severity, comments: Array(comment), sourceContext: sourceContext) + return issue.record() + } + } // MARK: - Recording issues for errors diff --git a/Tests/TestingTests/IssueTests.swift b/Tests/TestingTests/IssueTests.swift index cc0a7acf5..5c861f13a 100644 --- a/Tests/TestingTests/IssueTests.swift +++ b/Tests/TestingTests/IssueTests.swift @@ -985,6 +985,25 @@ final class IssueTests: XCTestCase { await fulfillment(of: [errorCaught, apiMisused, expectationFailed], timeout: 0.0) } + + func testIssueRecordKinds() async throws { + var configuration = Configuration() + let apiMisused = expectation(description: "API misused") + configuration.eventHandler = { event, _ in + guard case let .issueRecorded(issue) = event.kind else { + return + } + if case .apiMisused = issue.kind { + apiMisused.fulfill() + } + + } + await Test { + Issue.record(kind: .apiMisused, comment: "My comment") + }.run(configuration: configuration) + + await fulfillment(of: [apiMisused], timeout: 0.0) + } @__testing(semantics: "nomacrowarnings") func testErrorCheckingWithRequire_ResultValueIsNever_VariousSyntaxes() throws {