Skip to content

Commit 45384e5

Browse files
authored
Promote attachments to API (#973)
This PR promotes attachments to API and makes the appropriate changes to match what was approved in the review of [ST-0009](https://github.com/swiftlang/swift-evolution/blob/main/proposals/testing/0009-attachments.md). ### Checklist: - [x] Code and documentation should follow the style of the [Style Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md). - [x] If public symbols are renamed or modified, DocC references should be updated.
1 parent 756316c commit 45384e5

24 files changed

+265
-85
lines changed

Documentation/ABI/JSON.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,19 +188,24 @@ sufficient information to display the event in a human-readable format.
188188
"kind": <event-kind>,
189189
"instant": <instant>, ; when the event occurred
190190
["issue": <issue>,] ; the recorded issue (if "kind" is "issueRecorded")
191+
["attachment": <attachment>,] ; the attachment (if kind is "valueAttached")
191192
"messages": <array:message>,
192193
["testID": <test-id>,]
193194
}
194195
195196
<event-kind> ::= "runStarted" | "testStarted" | "testCaseStarted" |
196197
"issueRecorded" | "testCaseEnded" | "testEnded" | "testSkipped" |
197-
"runEnded" ; additional event kinds may be added in the future
198+
"runEnded" | "valueAttached"; additional event kinds may be added in the future
198199
199200
<issue> ::= {
200201
"isKnown": <bool>, ; is this a known issue or not?
201202
["sourceLocation": <source-location>,] ; where the issue occurred, if known
202203
}
203204
205+
<attachment> ::= {
206+
"path": <string>, ; the absolute path to the attachment on disk
207+
}
208+
204209
<message> ::= {
205210
"symbol": <message-symbol>,
206211
"text": <string>, ; the human-readable text of this message

Sources/Overlays/_Testing_CoreGraphics/Attachments/Attachment+AttachableAsCGImage.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ extension Attachment {
4242
contentType: (any Sendable)?,
4343
encodingQuality: Float,
4444
sourceLocation: SourceLocation
45-
) where AttachableValue == _AttachableImageContainer<T> {
46-
let imageContainer = _AttachableImageContainer(image: attachableValue, encodingQuality: encodingQuality, contentType: contentType)
47-
self.init(imageContainer, named: preferredName, sourceLocation: sourceLocation)
45+
) where AttachableValue == _AttachableImageWrapper<T> {
46+
let imageWrapper = _AttachableImageWrapper(image: attachableValue, encodingQuality: encodingQuality, contentType: contentType)
47+
self.init(imageWrapper, named: preferredName, sourceLocation: sourceLocation)
4848
}
4949

5050
/// Initialize an instance of this type that encloses the given image.
@@ -79,7 +79,7 @@ extension Attachment {
7979
as contentType: UTType?,
8080
encodingQuality: Float = 1.0,
8181
sourceLocation: SourceLocation = #_sourceLocation
82-
) where AttachableValue == _AttachableImageContainer<T> {
82+
) where AttachableValue == _AttachableImageWrapper<T> {
8383
self.init(attachableValue: attachableValue, named: preferredName, contentType: contentType, encodingQuality: encodingQuality, sourceLocation: sourceLocation)
8484
}
8585

@@ -109,7 +109,7 @@ extension Attachment {
109109
named preferredName: String? = nil,
110110
encodingQuality: Float = 1.0,
111111
sourceLocation: SourceLocation = #_sourceLocation
112-
) where AttachableValue == _AttachableImageContainer<T> {
112+
) where AttachableValue == _AttachableImageWrapper<T> {
113113
self.init(attachableValue: attachableValue, named: preferredName, contentType: nil, encodingQuality: encodingQuality, sourceLocation: sourceLocation)
114114
}
115115
}

Sources/Overlays/_Testing_CoreGraphics/Attachments/_AttachableImageContainer.swift renamed to Sources/Overlays/_Testing_CoreGraphics/Attachments/_AttachableImageWrapper.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//
1010

1111
#if SWT_TARGET_OS_APPLE && canImport(CoreGraphics)
12-
@_spi(Experimental) public import Testing
12+
public import Testing
1313
private import CoreGraphics
1414

1515
private import ImageIO
@@ -48,7 +48,7 @@ import UniformTypeIdentifiers
4848
///
4949
/// - [`CGImage`](https://developer.apple.com/documentation/coregraphics/cgimage)
5050
@_spi(Experimental)
51-
public struct _AttachableImageContainer<Image>: Sendable where Image: AttachableAsCGImage {
51+
public struct _AttachableImageWrapper<Image>: Sendable where Image: AttachableAsCGImage {
5252
/// The underlying image.
5353
///
5454
/// `CGImage` and `UIImage` are sendable, but `NSImage` is not. `NSImage`
@@ -127,8 +127,8 @@ public struct _AttachableImageContainer<Image>: Sendable where Image: Attachable
127127

128128
// MARK: -
129129

130-
extension _AttachableImageContainer: AttachableContainer {
131-
public var attachableValue: Image {
130+
extension _AttachableImageWrapper: AttachableWrapper {
131+
public var wrappedValue: Image {
132132
image
133133
}
134134

Sources/Overlays/_Testing_Foundation/Attachments/Attachable+Encodable+NSSecureCoding.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//
1010

1111
#if canImport(Foundation)
12-
@_spi(Experimental) public import Testing
12+
public import Testing
1313
public import Foundation
1414

1515
// This implementation is necessary to let the compiler disambiguate when a type
@@ -18,7 +18,9 @@ public import Foundation
1818
// (which explicitly document what happens when a type conforms to both
1919
// protocols.)
2020

21-
@_spi(Experimental)
21+
/// @Metadata {
22+
/// @Available(Swift, introduced: 6.2)
23+
/// }
2224
extension Attachable where Self: Encodable & NSSecureCoding {
2325
@_documentation(visibility: private)
2426
public func withUnsafeBytes<R>(for attachment: borrowing Attachment<Self>, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {

Sources/Overlays/_Testing_Foundation/Attachments/Attachable+Encodable.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//
1010

1111
#if canImport(Foundation)
12-
@_spi(Experimental) public import Testing
12+
public import Testing
1313
private import Foundation
1414

1515
/// A common implementation of ``withUnsafeBytes(for:_:)`` that is used when a
@@ -53,7 +53,10 @@ func withUnsafeBytes<E, R>(encoding attachableValue: borrowing E, for attachment
5353
// Implement the protocol requirements generically for any encodable value by
5454
// encoding to JSON. This lets developers provide trivial conformance to the
5555
// protocol for types that already support Codable.
56-
@_spi(Experimental)
56+
57+
/// @Metadata {
58+
/// @Available(Swift, introduced: 6.2)
59+
/// }
5760
extension Attachable where Self: Encodable {
5861
/// Encode this value into a buffer using either [`PropertyListEncoder`](https://developer.apple.com/documentation/foundation/propertylistencoder)
5962
/// or [`JSONEncoder`](https://developer.apple.com/documentation/foundation/jsonencoder),
@@ -86,6 +89,10 @@ extension Attachable where Self: Encodable {
8689
/// _and_ [`NSSecureCoding`](https://developer.apple.com/documentation/foundation/nssecurecoding),
8790
/// the default implementation of this function uses the value's conformance
8891
/// to `Encodable`.
92+
///
93+
/// @Metadata {
94+
/// @Available(Swift, introduced: 6.2)
95+
/// }
8996
public func withUnsafeBytes<R>(for attachment: borrowing Attachment<Self>, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
9097
try _Testing_Foundation.withUnsafeBytes(encoding: self, for: attachment, body)
9198
}

Sources/Overlays/_Testing_Foundation/Attachments/Attachable+NSSecureCoding.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@
99
//
1010

1111
#if canImport(Foundation)
12-
@_spi(Experimental) public import Testing
12+
public import Testing
1313
public import Foundation
1414

1515
// As with Encodable, implement the protocol requirements for
1616
// NSSecureCoding-conformant classes by default. The implementation uses
1717
// NSKeyedArchiver for encoding.
18-
@_spi(Experimental)
18+
19+
/// @Metadata {
20+
/// @Available(Swift, introduced: 6.2)
21+
/// }
1922
extension Attachable where Self: NSSecureCoding {
2023
/// Encode this object using [`NSKeyedArchiver`](https://developer.apple.com/documentation/foundation/nskeyedarchiver)
2124
/// into a buffer, then call a function and pass that buffer to it.
@@ -46,6 +49,10 @@ extension Attachable where Self: NSSecureCoding {
4649
/// _and_ [`NSSecureCoding`](https://developer.apple.com/documentation/foundation/nssecurecoding),
4750
/// the default implementation of this function uses the value's conformance
4851
/// to `Encodable`.
52+
///
53+
/// @Metadata {
54+
/// @Available(Swift, introduced: 6.2)
55+
/// }
4956
public func withUnsafeBytes<R>(for attachment: borrowing Attachment<Self>, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
5057
let format = try EncodingFormat(for: attachment)
5158

Sources/Overlays/_Testing_Foundation/Attachments/Attachment+URL.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//
1010

1111
#if canImport(Foundation)
12-
@_spi(Experimental) public import Testing
12+
public import Testing
1313
public import Foundation
1414

1515
#if !SWT_NO_PROCESS_SPAWNING && os(Windows)
@@ -32,8 +32,7 @@ extension URL {
3232
}
3333
}
3434

35-
@_spi(Experimental)
36-
extension Attachment where AttachableValue == _AttachableURLContainer {
35+
extension Attachment where AttachableValue == _AttachableURLWrapper {
3736
#if SWT_TARGET_OS_APPLE
3837
/// An operation queue to use for asynchronously reading data from disk.
3938
private static let _operationQueue = OperationQueue()
@@ -51,6 +50,10 @@ extension Attachment where AttachableValue == _AttachableURLContainer {
5150
/// attachment.
5251
///
5352
/// - Throws: Any error that occurs attempting to read from `url`.
53+
///
54+
/// @Metadata {
55+
/// @Available(Swift, introduced: 6.2)
56+
/// }
5457
public init(
5558
contentsOf url: URL,
5659
named preferredName: String? = nil,
@@ -91,8 +94,8 @@ extension Attachment where AttachableValue == _AttachableURLContainer {
9194
}
9295
#endif
9396

94-
let urlContainer = _AttachableURLContainer(url: url, data: data, isCompressedDirectory: isDirectory)
95-
self.init(urlContainer, named: preferredName, sourceLocation: sourceLocation)
97+
let urlWrapper = _AttachableURLWrapper(url: url, data: data, isCompressedDirectory: isDirectory)
98+
self.init(urlWrapper, named: preferredName, sourceLocation: sourceLocation)
9699
}
97100
}
98101

Sources/Overlays/_Testing_Foundation/Attachments/Data+Attachable.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,16 @@
99
//
1010

1111
#if canImport(Foundation)
12-
@_spi(Experimental) public import Testing
12+
public import Testing
1313
public import Foundation
1414

15-
@_spi(Experimental)
15+
/// @Metadata {
16+
/// @Available(Swift, introduced: 6.2)
17+
/// }
1618
extension Data: Attachable {
19+
/// @Metadata {
20+
/// @Available(Swift, introduced: 6.2)
21+
/// }
1722
public func withUnsafeBytes<R>(for attachment: borrowing Attachment<Self>, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
1823
try withUnsafeBytes(body)
1924
}

Sources/Overlays/_Testing_Foundation/Attachments/EncodingFormat.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//
1010

1111
#if canImport(Foundation)
12-
@_spi(Experimental) import Testing
12+
import Testing
1313
import Foundation
1414

1515
/// An enumeration describing the encoding formats we support for `Encodable`

Sources/Overlays/_Testing_Foundation/Attachments/_AttachableURLContainer.swift renamed to Sources/Overlays/_Testing_Foundation/Attachments/_AttachableURLWrapper.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,15 @@
99
//
1010

1111
#if canImport(Foundation)
12-
@_spi(Experimental) public import Testing
12+
public import Testing
1313
public import Foundation
1414

1515
/// A wrapper type representing file system objects and URLs that can be
1616
/// attached indirectly.
1717
///
1818
/// You do not need to use this type directly. Instead, initialize an instance
1919
/// of ``Attachment`` using a file URL.
20-
@_spi(Experimental)
21-
public struct _AttachableURLContainer: Sendable {
20+
public struct _AttachableURLWrapper: Sendable {
2221
/// The underlying URL.
2322
var url: URL
2423

@@ -31,8 +30,8 @@ public struct _AttachableURLContainer: Sendable {
3130

3231
// MARK: -
3332

34-
extension _AttachableURLContainer: AttachableContainer {
35-
public var attachableValue: URL {
33+
extension _AttachableURLWrapper: AttachableWrapper {
34+
public var wrappedValue: URL {
3635
url
3736
}
3837

0 commit comments

Comments
 (0)