diff --git a/Sources/IssueReporting/ReportIfNil.swift b/Sources/IssueReporting/ReportIfNil.swift new file mode 100644 index 0000000..ba3e4b0 --- /dev/null +++ b/Sources/IssueReporting/ReportIfNil.swift @@ -0,0 +1,42 @@ +/// Evaluates a value and reports an issue if it is nil. +/// +/// - Parameters: +/// - value: The value to check for nil. +/// - message: A message describing the expectation. +/// - reporters: Issue reporters to notify if the value is nil. +/// - fileID: The source `#fileID` associated with the issue reporting. +/// - filePath: The source `#filePath` associated with the issue reporting. +/// - line: The source `#line` associated with the issue reporting. +/// - column: The source `#column` associated with the issue reporting. +/// - Returns: The optional value, unchanged. +@_transparent +public func reportIfNil( + _ value: T?, + message: @autoclosure () -> String = "Unexpected nil value", + to reporters: [any IssueReporter]? = nil, + fileID: StaticString = #fileID, + filePath: StaticString = #filePath, + line: UInt = #line, + column: UInt = #column +) -> T? { + + guard let value else { + withErrorReporting( + message(), + to: reporters, + fileID: fileID, + filePath: filePath, + line: line, + column: column + ) { + throw NilValueError() + } + return nil + } + + return value +} + +public struct NilValueError: Error { + public init() {} +} diff --git a/Tests/IssueReportingTests/ReportIfNilTests.swift b/Tests/IssueReportingTests/ReportIfNilTests.swift new file mode 100644 index 0000000..01aa1dc --- /dev/null +++ b/Tests/IssueReportingTests/ReportIfNilTests.swift @@ -0,0 +1,35 @@ +#if canImport(Testing) && !os(Windows) +import Testing +import IssueReporting + +@Suite +struct ReportIfNilTests { + + @Test + func reportsIssueForNilValueWithDefaultMessage() { + withKnownIssue { + _ = reportIfNil(Optional.none) + } matching: { issue in + issue.error is NilValueError && + issue.description == "Caught error: NilValueError(): Unexpected nil value" + } + } + + @Test + func reportsIssueForNilValueWithCustomMessage() { + withKnownIssue { + _ = reportIfNil(Optional.none, message: "Custom nil message") + } matching: { issue in + issue.error is NilValueError && + issue.description == "Caught error: NilValueError(): Custom nil message" + } + } + + @Test + func doesNotReportIssueForNonNilValue() { + let value: String? = "non-nil" + #expect(reportIfNil(value) == "non-nil") + } +} + +#endif