Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 66 additions & 22 deletions Sources/IssueReporting/Internal/SwiftTesting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,49 @@ func _recordIssue(
guard let function = function(for: "$s25IssueReportingTestSupport07_recordA0ypyF")
else {
#if DEBUG && canImport(Darwin)
guard
let record = unsafeBitCast(
symbol: "$s7Testing5IssueV6record_14sourceLocationAcA7CommentVSg_AA06SourceE0VtFZ",
in: "Testing",
to: (@convention(thin) (Any?, SourceLocation) -> Issue).self
#if compiler(>=6.2)
guard
let record = unsafeBitCast(
symbol: """
$s7Testing5IssueV6record_8severity14sourceLocationAcA7CommentVSg_AC8SeverityOAA06Sour\
ceF0VtFZ
""",
in: "Testing",
to: (@convention(thin) (Any?, Any, SourceLocation) -> Issue).self
)
else { return }

var comment: Any?
if let message {
var c = UnsafeMutablePointer<Comment>.allocate(capacity: 1).pointee
c.rawValue = message
comment = c
}
_ = record(
comment,
Issue.Severity.error, // TODO: Support other severities?
SourceLocation(fileID: fileID, _filePath: filePath, line: line, column: column)
)
else { return }
#else
guard
let record = unsafeBitCast(
symbol: "$s7Testing5IssueV6record_14sourceLocationAcA7CommentVSg_AA06SourceE0VtFZ",
in: "Testing",
to: (@convention(thin) (Any?, SourceLocation) -> Issue).self
)
else { return }

var comment: Any?
if let message {
var c = UnsafeMutablePointer<Comment>.allocate(capacity: 1).pointee
c.rawValue = message
comment = c
}
_ = record(
comment,
SourceLocation(fileID: fileID, _filePath: filePath, line: line, column: column)
)
var comment: Any?
if let message {
var c = UnsafeMutablePointer<Comment>.allocate(capacity: 1).pointee
c.rawValue = message
comment = c
}
_ = record(
comment,
SourceLocation(fileID: fileID, _filePath: filePath, line: line, column: column)
)
#endif
#else
printError(
"""
Expand Down Expand Up @@ -188,7 +213,7 @@ func _withKnownIssue(
let withKnownIssue = unsafeBitCast(
symbol: """
$s7Testing14withKnownIssue_14isIntermittent9isolation14sourceLocation_yAA7CommentVSg_\
SbScA_pSgYiAA06SourceI0VyyYaKXEtYaF
SbScA_pSgYiAA06SourceI0VyyYaKXEtYaFTu
""",
in: "Testing",
to: (@convention(thin) (
Expand Down Expand Up @@ -350,7 +375,9 @@ func _currentTest() -> _Test? {
var value: __Expression
}
indirect case functionCall(
value: __Expression?, functionName: String, arguments: [FunctionCallArgument]
value: __Expression?,
functionName: String,
arguments: [FunctionCallArgument]
)
indirect case propertyAccess(value: __Expression, keyPath: __Expression)
indirect case negation(_ expression: __Expression, isParenthetical: Bool)
Expand Down Expand Up @@ -407,17 +434,34 @@ func _currentTest() -> _Test? {
enum Kind: Sendable {
case unconditional
indirect case expectationFailed(_ expectation: Expectation)
indirect case confirmationMiscounted(actual: Int, expected: Int)
indirect case confirmationOutOfRange(actual: Int, expected: any ExpectedCount)
#if compiler(>=6.2)
indirect case confirmationMiscounted(actual: Int, expected: any RangeExpression & Sendable)
#else
indirect case confirmationMiscounted(actual: Int, expected: Int)
indirect case confirmationOutOfRange(actual: Int, expected: any ExpectedCount)
#endif
indirect case errorCaught(_ error: any Error)
indirect case timeLimitExceeded(timeLimitComponents: (seconds: Int64, attoseconds: Int64))
case knownIssueNotRecorded
case apiMisused
case system
}
var kind: Kind
#if compiler(>=6.2)
enum Severity: Sendable {
case warning
case error
}
var severity: Severity
#endif
var comments: [Comment]
var sourceContext: SourceContext
#if compiler(>=6.2)
struct KnownIssueContext: Sendable {
public var comment: Comment?
}
var knownIssueContext: KnownIssueContext? = nil
#endif
}

private struct SourceContext: Sendable {
Expand Down Expand Up @@ -523,7 +567,7 @@ func _currentTest() -> _Test? {
> = LockIsolated([:])
var fullyQualifiedNameComponents: [String] {
switch _kind {
case let .type(type):
case .type(let type):
if let cachedResult = Self
._fullyQualifiedNameComponentsCache.withLock({ $0[ObjectIdentifier(type)] })
{
Expand All @@ -541,7 +585,7 @@ func _currentTest() -> _Test? {
}
return result

case let .nameOnly(fullyQualifiedComponents, _, _):
case .nameOnly(let fullyQualifiedComponents, _, _):
return fullyQualifiedComponents
}
}
Expand Down
5 changes: 5 additions & 0 deletions Tests/IssueReportingTests/Support.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#if compiler(>=6.2)
let issueDescriptionSuffix = " (error)"
#else
let issueDescriptionSuffix = ""
#endif
18 changes: 9 additions & 9 deletions Tests/IssueReportingTests/SwiftTestingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
withKnownIssue {
reportIssue()
} matching: { issue in
issue.description == "Issue recorded"
issue.description == "Issue recorded\(issueDescriptionSuffix)"
}
}

Expand All @@ -26,23 +26,23 @@
withKnownIssue {
reportIssue(Failure())
} matching: { issue in
issue.description == "Caught error: Failure()"
issue.description == "Caught error: Failure()\(issueDescriptionSuffix)"
}
}

@Test func reportIssue_CustomMessage() {
withKnownIssue {
reportIssue("Something went wrong")
} matching: { issue in
issue.description == "Issue recorded: Something went wrong"
issue.description == "Issue recorded\(issueDescriptionSuffix): Something went wrong"
}
}

@Test func reportError_CustomMessage() {
withKnownIssue {
reportIssue(Failure(), "Something went wrong")
} matching: { issue in
issue.description == "Caught error: Failure(): Something went wrong"
issue.description == "Caught error: Failure()\(issueDescriptionSuffix): Something went wrong"
}
}

Expand Down Expand Up @@ -74,7 +74,7 @@
withExpectedIssue {
}
} matching: { issue in
issue.description == "Known issue was not recorded"
issue.description == "Known issue was not recorded\(issueDescriptionSuffix)"
}
}

Expand All @@ -84,7 +84,7 @@
await Task.yield()
}
} matching: { issue in
issue.description == "Known issue was not recorded"
issue.description == "Known issue was not recorded\(issueDescriptionSuffix)"
}
}

Expand All @@ -93,7 +93,7 @@
withExpectedIssue("This didn't fail") {
}
} matching: { issue in
issue.description == "Known issue was not recorded: This didn't fail"
issue.description == "Known issue was not recorded\(issueDescriptionSuffix): This didn't fail"
}
}

Expand All @@ -103,7 +103,7 @@
await Task.yield()
}
} matching: { issue in
issue.description == "Known issue was not recorded: This didn't fail"
issue.description == "Known issue was not recorded\(issueDescriptionSuffix): This didn't fail"
}
}

Expand All @@ -126,7 +126,7 @@
} matching: { issue in
let expectedReportingLine = #line - 4
return issue.sourceLocation?.line == expectedReportingLine
&& issue.description == "Issue recorded: Something went wrong"
&& issue.description == "Issue recorded\(issueDescriptionSuffix): Something went wrong"
}
}

Expand Down
18 changes: 9 additions & 9 deletions Tests/IssueReportingTests/UnimplementedTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
model.callback(42)
} matching: { issue in
issue.description == """
Issue recorded: Unimplemented …
Issue recorded\(issueDescriptionSuffix): Unimplemented …

Defined in 'Model' at:
IssueReportingTests/UnimplementedTests.swift:\(model.line)
Expand All @@ -37,7 +37,7 @@
model.callback()
} matching: { issue in
issue.description == """
Issue recorded: Unimplemented …
Issue recorded\(issueDescriptionSuffix): Unimplemented …

Defined in 'Model' at:
IssueReportingTests/UnimplementedTests.swift:\(model.line)
Expand All @@ -59,7 +59,7 @@
_ = model.callback()
} matching: { issue in
issue.description == """
Issue recorded: Unimplemented …
Issue recorded\(issueDescriptionSuffix): Unimplemented …

Defined in 'Model' at:
IssueReportingTests/UnimplementedTests.swift:\(model.line)
Expand All @@ -81,7 +81,7 @@
_ = try model.callback()
} matching: { issue in
issue.description == """
Issue recorded: Unimplemented …
Issue recorded\(issueDescriptionSuffix): Unimplemented …

Defined in 'Model' at:
IssueReportingTests/UnimplementedTests.swift:\(model.line)
Expand All @@ -90,7 +90,7 @@
()
"""
|| issue.description == """
Caught error: UnimplementedFailure(description: "")
Caught error: UnimplementedFailure(description: "")\(issueDescriptionSuffix)
"""
}
}
Expand All @@ -107,7 +107,7 @@
_ = try model.callback()
} matching: { issue in
issue.description == """
Issue recorded: Unimplemented …
Issue recorded\(issueDescriptionSuffix): Unimplemented …

Defined in 'Model' at:
IssueReportingTests/UnimplementedTests.swift:\(model.line)
Expand All @@ -118,7 +118,7 @@
}
} matching: { issue in
issue.description == """
Caught error: UnimplementedFailure(description: "")
Caught error: UnimplementedFailure(description: "")\(issueDescriptionSuffix)
"""
}
}
Expand All @@ -136,7 +136,7 @@
_ = try model.callback()
} matching: { issue in
issue.description == """
Issue recorded: Unimplemented …
Issue recorded\(issueDescriptionSuffix): Unimplemented …

Defined in 'Model' at:
IssueReportingTests/UnimplementedTests.swift:\(model.line)
Expand All @@ -147,7 +147,7 @@
}
} matching: { issue in
issue.description == """
Caught error: UnimplementedFailure(description: "")
Caught error: UnimplementedFailure(description: "")\(issueDescriptionSuffix)
"""
}
}
Expand Down
26 changes: 14 additions & 12 deletions Tests/IssueReportingTests/WithErrorReportingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
throw SomeError()
}
} matching: { issue in
issue.description == "Caught error: SomeError()"
issue.description == "Caught error: SomeError()\(issueDescriptionSuffix)"
}

withKnownIssue {
withErrorReporting("Failed") {
throw SomeError()
}
} matching: { issue in
issue.description == "Caught error: SomeError(): Failed"
issue.description == "Caught error: SomeError()\(issueDescriptionSuffix): Failed"
}
}

Expand All @@ -28,28 +28,30 @@
throw SomeError()
}
} matching: { issue in
issue.description == "Caught error: SomeError()"
issue.description == "Caught error: SomeError()\(issueDescriptionSuffix)"
}

await withKnownIssue {
await withErrorReporting("Failed") { () async throws in
throw SomeError()
}
} matching: { issue in
issue.description == "Caught error: SomeError(): Failed"
issue.description == "Caught error: SomeError()\(issueDescriptionSuffix): Failed"
}
}

@MainActor
@Test func isolation() async {
await withKnownIssue {
await withErrorReporting { () async throws in
throw SomeError()
#if compiler(<6.2)
@MainActor
@Test func isolation() async {
await withKnownIssue {
await withErrorReporting { () async throws in
throw SomeError()
}
} matching: { issue in
issue.description == "Caught error: SomeError()"
}
} matching: { issue in
issue.description == "Caught error: SomeError()"
}
}
#endif
}

private struct SomeError: Error {}
Expand Down