diff --git a/Sources/Testing/Attachments/Attachable.swift b/Sources/Testing/Attachments/Attachable.swift index 8e2c06420..8c3476657 100644 --- a/Sources/Testing/Attachments/Attachable.swift +++ b/Sources/Testing/Attachments/Attachable.swift @@ -103,17 +103,37 @@ public protocol Attachable: ~Copyable { // MARK: - Default implementations +/// @Metadata { +/// @Available(Swift, introduced: 6.2) +/// @Available(Xcode, introduced: 26.0) +/// } extension Attachable where Self: ~Copyable { + /// @Metadata { + /// @Available(Swift, introduced: 6.2) + /// @Available(Xcode, introduced: 26.0) + /// } public var estimatedAttachmentByteCount: Int? { nil } + /// @Metadata { + /// @Available(Swift, introduced: 6.2) + /// @Available(Xcode, introduced: 26.0) + /// } public borrowing func preferredName(for attachment: borrowing Attachment, basedOn suggestedName: String) -> String { suggestedName } } +/// @Metadata { +/// @Available(Swift, introduced: 6.2) +/// @Available(Xcode, introduced: 26.0) +/// } extension Attachable where Self: Collection, Element == UInt8 { + /// @Metadata { + /// @Available(Swift, introduced: 6.2) + /// @Available(Xcode, introduced: 26.0) + /// } public var estimatedAttachmentByteCount: Int? { count } @@ -125,37 +145,88 @@ extension Attachable where Self: Collection, Element == UInt8 { // (potentially expensive!) copy of the collection. } +/// @Metadata { +/// @Available(Swift, introduced: 6.2) +/// @Available(Xcode, introduced: 26.0) +/// } extension Attachable where Self: StringProtocol { + /// @Metadata { + /// @Available(Swift, introduced: 6.2) + /// @Available(Xcode, introduced: 26.0) + /// } public var estimatedAttachmentByteCount: Int? { // NOTE: utf8.count may be O(n) for foreign strings. // SEE: https://github.com/swiftlang/swift/blob/main/stdlib/public/core/StringUTF8View.swift utf8.count } + + /// @Metadata { + /// @Available(Swift, introduced: 6.2) + /// @Available(Xcode, introduced: 26.0) + /// } + public borrowing func preferredName(for attachment: borrowing Attachment, basedOn suggestedName: String) -> String { + if suggestedName.contains(".") { + return suggestedName + } + return "\(suggestedName).txt" + } } // MARK: - Default conformances // Implement the protocol requirements for byte arrays and buffers so that // developers can attach raw data when needed. +/// @Metadata { +/// @Available(Swift, introduced: 6.2) +/// @Available(Xcode, introduced: 26.0) +/// } extension Array: Attachable { + /// @Metadata { + /// @Available(Swift, introduced: 6.2) + /// @Available(Xcode, introduced: 26.0) + /// } public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { try withUnsafeBytes(body) } } +/// @Metadata { +/// @Available(Swift, introduced: 6.2) +/// @Available(Xcode, introduced: 26.0) +/// } extension ContiguousArray: Attachable { + /// @Metadata { + /// @Available(Swift, introduced: 6.2) + /// @Available(Xcode, introduced: 26.0) + /// } public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { try withUnsafeBytes(body) } } +/// @Metadata { +/// @Available(Swift, introduced: 6.2) +/// @Available(Xcode, introduced: 26.0) +/// } extension ArraySlice: Attachable { + /// @Metadata { + /// @Available(Swift, introduced: 6.2) + /// @Available(Xcode, introduced: 26.0) + /// } public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { try withUnsafeBytes(body) } } +/// @Metadata { +/// @Available(Swift, introduced: 6.2) +/// @Available(Xcode, introduced: 26.0) +/// } extension String: Attachable { + /// @Metadata { + /// @Available(Swift, introduced: 6.2) + /// @Available(Xcode, introduced: 26.0) + /// } public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { var selfCopy = self return try selfCopy.withUTF8 { utf8 in @@ -164,7 +235,15 @@ extension String: Attachable { } } +/// @Metadata { +/// @Available(Swift, introduced: 6.2) +/// @Available(Xcode, introduced: 26.0) +/// } extension Substring: Attachable { + /// @Metadata { + /// @Available(Swift, introduced: 6.2) + /// @Available(Xcode, introduced: 26.0) + /// } public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { var selfCopy = self return try selfCopy.withUTF8 { utf8 in diff --git a/Tests/TestingTests/AttachmentTests.swift b/Tests/TestingTests/AttachmentTests.swift index 623ead084..854ecd133 100644 --- a/Tests/TestingTests/AttachmentTests.swift +++ b/Tests/TestingTests/AttachmentTests.swift @@ -62,6 +62,14 @@ struct AttachmentTests { } #endif + @Test func preferredNameOfStringAttachment() { + let attachment1 = Attachment("", named: "abc123") + #expect(attachment1.preferredName == "abc123.txt") + + let attachment2 = Attachment("", named: "abc123.html") + #expect(attachment2.preferredName == "abc123.html") + } + #if !SWT_NO_FILE_IO func compare(_ attachableValue: borrowing MySendableAttachable, toContentsOfFileAtPath filePath: String) throws { let file = try FileHandle(forReadingAtPath: filePath) diff --git a/Tests/TestingTests/Traits/AttachmentSavingTraitTests.swift b/Tests/TestingTests/Traits/AttachmentSavingTraitTests.swift index 1ea63eeda..47edd8b25 100644 --- a/Tests/TestingTests/Traits/AttachmentSavingTraitTests.swift +++ b/Tests/TestingTests/Traits/AttachmentSavingTraitTests.swift @@ -130,27 +130,27 @@ extension `AttachmentSavingTrait tests` { @Suite(.hidden, currentAttachmentSavingTrait) struct FixtureSuite { @Test(.hidden) func `Records an attachment (passing)`() { - Attachment.record("", named: "PASSING TEST") + Attachment.record([], named: "PASSING TEST") } @Test(.hidden) func `Records an attachment (warning)`() { - Attachment.record("", named: "PASSING TEST") + Attachment.record([], named: "PASSING TEST") Issue.record("", severity: .warning) } @Test(.hidden) func `Records an attachment (failing)`() { - Attachment.record("", named: "FAILING TEST") + Attachment.record([], named: "FAILING TEST") Issue.record("") } @Test(.hidden, arguments: 0 ..< 5) func `Records an attachment (passing, parameterized)`(i: Int) async { - Attachment.record("\(i)", named: "PASSING TEST") + Attachment.record([UInt8(i)], named: "PASSING TEST") } @Test(.hidden, arguments: 0 ..< 7) // intentionally different count func `Records an attachment (failing, parameterized)`(i: Int) async { - Attachment.record("\(i)", named: "FAILING TEST") + Attachment.record([UInt8(i)], named: "FAILING TEST") Issue.record("\(i)") } }