Skip to content

Commit 4b07525

Browse files
authored
Merge pull request #1437 from swiftlang/automerge/merge-main-2025-12-04_17-10
2 parents 4ad4d5d + 62f4265 commit 4b07525

File tree

9 files changed

+217
-116
lines changed

9 files changed

+217
-116
lines changed

.github/workflows/automerge.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# In the first period after creating a new release branch, we often want to
2+
# continue including all changes from `main` into the release branch. This
3+
# workflow automatically creates a PR to merge main into the release branch on a
4+
# set schedule, and it can also be invoked manually.
5+
#
6+
# Later in the release cycle we generally stop this practice to avoid landing
7+
# risky changes. To disable the workflow when ready, follow the steps described
8+
# in https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-workflow-runs/disabling-and-enabling-a-workflow
9+
10+
name: Create PR to merge main into release branch
11+
12+
permissions:
13+
contents: read
14+
on:
15+
schedule:
16+
- cron: '0 9 * * MON'
17+
workflow_dispatch:
18+
jobs:
19+
create_merge_pr:
20+
name: Create PR to merge main into release branch
21+
uses: swiftlang/github-workflows/.github/workflows/create_automerge_pr.yml@main
22+
with:
23+
head_branch: main
24+
base_branch: release/6.3
25+
permissions:
26+
contents: write
27+
pull-requests: write
28+
# Ensure that we don't run this on a schedule in a fork
29+
if: (github.event_name == 'schedule' && github.repository == 'swiftlang/swift-testing') || (github.event_name != 'schedule')

Sources/Overlays/_Testing_WinSDK/Attachments/AttachableImageFormat+CLSID.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,6 @@ extension AttachableImageFormat {
195195
/// @Metadata {
196196
/// @Available(Swift, introduced: 6.3)
197197
/// }
198-
#if compiler(>=6.3) && !SWT_FIXED_84466
199-
@_spi(_)
200-
#endif
201198
public var encoderCLSID: CLSID {
202199
kind.encoderCLSID
203200
}
@@ -223,9 +220,6 @@ extension AttachableImageFormat {
223220
/// @Metadata {
224221
/// @Available(Swift, introduced: 6.3)
225222
/// }
226-
#if compiler(>=6.3) && !SWT_FIXED_84466
227-
@_spi(_)
228-
#endif
229223
public init(encoderCLSID: CLSID, encodingQuality: Float = 1.0) {
230224
let encoderCLSID = CLSID.Wrapper(encoderCLSID)
231225
let kind: Kind = if encoderCLSID == CLSID.Wrapper(CLSID_WICPngEncoder) {

Sources/Testing/Attachments/Attachment.swift

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,6 @@ private import _TestingInternals
1919
/// record the attachment, call ``Attachment/record(_:sourceLocation:)``.
2020
/// Alternatively, pass your attachable value directly to ``Attachment/record(_:named:sourceLocation:)``.
2121
///
22-
/// By default, the testing library saves your attachments as soon as you call
23-
/// ``Attachment/record(_:sourceLocation:)`` or
24-
/// ``Attachment/record(_:named:sourceLocation:)``. You can access saved
25-
/// attachments after your tests finish running:
26-
///
27-
/// - When using Xcode, you can access attachments from the test report.
28-
/// - When using Visual Studio Code, the testing library saves attachments to
29-
/// `.build/attachments` by default. Visual Studio Code reports the paths to
30-
/// individual attachments in its Tests Results panel.
31-
/// - When using Swift Package Manager's `swift test` command, you can pass the
32-
/// `--attachments-path` option. The testing library saves attachments to the
33-
/// specified directory.
34-
///
3522
/// @Metadata {
3623
/// @Available(Swift, introduced: 6.2)
3724
/// @Available(Xcode, introduced: 26.0)
@@ -104,7 +91,8 @@ public struct Attachment<AttachableValue> where AttachableValue: Attachable & ~C
10491
///
10592
/// The value of this property is used when recording issues associated with
10693
/// the attachment.
107-
var sourceLocation: SourceLocation
94+
@_spi(ForToolsIntegrationOnly)
95+
public internal(set) var sourceLocation: SourceLocation
10896
}
10997

11098
extension Attachment: Sendable where AttachableValue: Sendable {}

Sources/Testing/Attachments/Images/AttachableAsImage.swift

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,9 @@
4545
/// Instead, the testing library provides additional initializers on [`Attachment`](https://developer.apple.com/documentation/testing/attachment)
4646
/// that take instances of such types and handle converting them to image data when needed.
4747
///
48-
/// You can attach instances of the following system-provided image types to a
49-
/// test:
50-
///
51-
/// | Platform | Supported Types |
52-
/// |-|-|
53-
/// | macOS | [`CGImage`](https://developer.apple.com/documentation/coregraphics/cgimage), [`CIImage`](https://developer.apple.com/documentation/coreimage/ciimage), [`NSImage`](https://developer.apple.com/documentation/appkit/nsimage) |
54-
/// | iOS, watchOS, tvOS, and visionOS | [`CGImage`](https://developer.apple.com/documentation/coregraphics/cgimage), [`CIImage`](https://developer.apple.com/documentation/coreimage/ciimage), [`UIImage`](https://developer.apple.com/documentation/uikit/uiimage) |
55-
/// | Windows | [`HBITMAP`](https://learn.microsoft.com/en-us/windows/win32/gdi/bitmaps), [`HICON`](https://learn.microsoft.com/en-us/windows/win32/menurc/icons), [`IWICBitmapSource`](https://learn.microsoft.com/en-us/windows/win32/api/wincodec/nn-wincodec-iwicbitmapsource) (including its subclasses declared by Windows Imaging Component) |
56-
///
57-
/// You do not generally need to add your own conformances to this protocol. If
58-
/// you have an image in another format that needs to be attached to a test,
59-
/// first convert it to an instance of one of the types above.
48+
/// You do not generally need to add your own conformances to this protocol. For
49+
/// a list of types that automatically conform to this protocol, see
50+
/// <doc:Attachments#Attach-images>.
6051
///
6152
/// @Metadata {
6253
/// @Available(Swift, introduced: 6.3)

Sources/Testing/Attachments/Images/AttachableImageFormat.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
/// instance of this type, the testing library infers which format to use based
1818
/// on the attachment's preferred name.
1919
///
20-
/// The PNG and JPEG image formats are always supported. The set of additional
21-
/// supported image formats is platform-specific:
20+
/// The testing library always supports the PNG and JPEG image formats. The set
21+
/// of additional supported image formats is platform-specific:
2222
///
2323
/// - On Apple platforms, you can use [`CGImageDestinationCopyTypeIdentifiers()`](https://developer.apple.com/documentation/imageio/cgimagedestinationcopytypeidentifiers())
2424
/// from the [Image I/O framework](https://developer.apple.com/documentation/imageio)

Sources/Testing/Attachments/Images/Attachment+AttachableAsImage.swift

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,6 @@ extension Attachment {
2929
/// This value is used when recording issues associated with the
3030
/// attachment.
3131
///
32-
/// You can attach instances of the following system-provided image types to a
33-
/// test:
34-
///
35-
/// | Platform | Supported Types |
36-
/// |-|-|
37-
/// | macOS | [`CGImage`](https://developer.apple.com/documentation/coregraphics/cgimage), [`CIImage`](https://developer.apple.com/documentation/coreimage/ciimage), [`NSImage`](https://developer.apple.com/documentation/appkit/nsimage) |
38-
/// | iOS, watchOS, tvOS, and visionOS | [`CGImage`](https://developer.apple.com/documentation/coregraphics/cgimage), [`CIImage`](https://developer.apple.com/documentation/coreimage/ciimage), [`UIImage`](https://developer.apple.com/documentation/uikit/uiimage) |
39-
/// | Windows | [`HBITMAP`](https://learn.microsoft.com/en-us/windows/win32/gdi/bitmaps), [`HICON`](https://learn.microsoft.com/en-us/windows/win32/menurc/icons), [`IWICBitmapSource`](https://learn.microsoft.com/en-us/windows/win32/api/wincodec/nn-wincodec-iwicbitmapsource) (including its subclasses declared by Windows Imaging Component) |
40-
///
4132
/// The testing library uses the image format specified by `imageFormat`. Pass
4233
/// `nil` to let the testing library decide which image format to use. If you
4334
/// pass `nil`, then the image format that the testing library uses depends on
@@ -70,22 +61,14 @@ extension Attachment {
7061
/// - sourceLocation: The source location of the call to this function.
7162
///
7263
/// This function creates a new instance of ``Attachment`` wrapping `image`
73-
/// and immediately attaches it to the current test. You can attach instances
74-
/// of the following system-provided image types to a test:
75-
///
76-
/// | Platform | Supported Types |
77-
/// |-|-|
78-
/// | macOS | [`CGImage`](https://developer.apple.com/documentation/coregraphics/cgimage), [`CIImage`](https://developer.apple.com/documentation/coreimage/ciimage), [`NSImage`](https://developer.apple.com/documentation/appkit/nsimage) |
79-
/// | iOS, watchOS, tvOS, and visionOS | [`CGImage`](https://developer.apple.com/documentation/coregraphics/cgimage), [`CIImage`](https://developer.apple.com/documentation/coreimage/ciimage), [`UIImage`](https://developer.apple.com/documentation/uikit/uiimage) |
80-
/// | Windows | [`HBITMAP`](https://learn.microsoft.com/en-us/windows/win32/gdi/bitmaps), [`HICON`](https://learn.microsoft.com/en-us/windows/win32/menurc/icons), [`IWICBitmapSource`](https://learn.microsoft.com/en-us/windows/win32/api/wincodec/nn-wincodec-iwicbitmapsource) (including its subclasses declared by Windows Imaging Component) |
81-
///
82-
/// The testing library uses the image format specified by `imageFormat`. Pass
83-
/// `nil` to let the testing library decide which image format to use. If you
84-
/// pass `nil`, then the image format that the testing library uses depends on
85-
/// the path extension you specify in `preferredName`, if any. If you do not
86-
/// specify a path extension, or if the path extension you specify doesn't
87-
/// correspond to an image format the operating system knows how to write, the
88-
/// testing library selects an appropriate image format for you.
64+
/// and immediately attaches it to the current test. The testing library uses
65+
/// the image format that `imageFormat` specifies. Pass `nil` to let the testing
66+
/// library select which image format to use. If you pass `nil`, the
67+
/// image format that the testing library uses depends on the path extension
68+
/// you specify in `preferredName`, if any. If you don't specify a path
69+
/// extension, or if the path extension you specify doesn't correspond to an
70+
/// image format the operating system knows how to write, the testing library
71+
/// selects an appropriate image format for you.
8972
///
9073
/// @Metadata {
9174
/// @Available(Swift, introduced: 6.3)

Sources/Testing/Attachments/Images/_AttachableImageWrapper.swift

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

1111
/// A wrapper type for images that can be indirectly attached to a test.
12-
///
13-
/// You can attach instances of the following system-provided image types to a
14-
/// test:
15-
///
16-
/// | Platform | Supported Types |
17-
/// |-|-|
18-
/// | macOS | [`CGImage`](https://developer.apple.com/documentation/coregraphics/cgimage), [`CIImage`](https://developer.apple.com/documentation/coreimage/ciimage), [`NSImage`](https://developer.apple.com/documentation/appkit/nsimage) |
19-
/// | iOS, watchOS, tvOS, and visionOS | [`CGImage`](https://developer.apple.com/documentation/coregraphics/cgimage), [`CIImage`](https://developer.apple.com/documentation/coreimage/ciimage), [`UIImage`](https://developer.apple.com/documentation/uikit/uiimage) |
20-
/// | Windows | [`HBITMAP`](https://learn.microsoft.com/en-us/windows/win32/gdi/bitmaps), [`HICON`](https://learn.microsoft.com/en-us/windows/win32/menurc/icons), [`IWICBitmapSource`](https://learn.microsoft.com/en-us/windows/win32/api/wincodec/nn-wincodec-iwicbitmapsource) (including its subclasses declared by Windows Imaging Component) |
2112
#if SWT_NO_IMAGE_ATTACHMENTS
2213
@_unavailableInEmbedded
2314
@available(*, unavailable, message: "Image attachments are not available on this platform.")

Sources/Testing/Testing.docc/Attachments.md

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,179 @@ Attach values to tests to help diagnose issues and gather feedback.
1717
Attach values such as strings and files to tests. Implement the ``Attachable``
1818
protocol to create your own attachable types.
1919

20+
### Attach data or strings
21+
22+
If your test produces encoded data that you want to save as an attachment, you
23+
can call ``Attachment/record(_:named:sourceLocation:)``.
24+
25+
```swift
26+
struct SalesReport { ... }
27+
28+
@Test func `sales report adds up`() async throws {
29+
let salesReport = await generateSalesReport()
30+
try salesReport.validate()
31+
let bytes: [UInt8] = try salesReport.convertToCSV()
32+
Attachment.record(bytes, named: "sales report.csv")
33+
}
34+
```
35+
36+
You can attach an instance of [`Array<UInt8>`](https://developer.apple.com/documentation/swift/array),
37+
[`ContiguousArray<UInt8>`](https://developer.apple.com/documentation/swift/contiguousarray),
38+
[`ArraySlice<UInt8>`](https://developer.apple.com/documentation/swift/arrayslice),
39+
or [`Data`](https://developer.apple.com/documentation/foundation/data) because
40+
these types automatically conform to ``Attachable``.
41+
42+
You can also attach an instance of [`String`](https://developer.apple.com/documentation/swift/string)
43+
or [`Substring`](https://developer.apple.com/documentation/swift/substring). The
44+
testing library treats attached strings as UTF-8 text
45+
files. If you want to save a string as an attachment using a different encoding,
46+
convert it to [`Data`](https://developer.apple.com/documentation/foundation/data)
47+
using [`data(using:allowLossyConversion:)`](https://developer.apple.com/documentation/swift/stringprotocol/data(using:allowlossyconversion:))
48+
and attach the resulting data instead of the original string.
49+
50+
### Attach encodable values
51+
52+
If you have a value you want to save as an attachment that conforms to either
53+
[`Encodable`](https://developer.apple.com/documentation/swift/encodable) or
54+
[`NSSecureCoding`](https://developer.apple.com/documentation/foundation/nssecurecoding),
55+
you can extend it to add conformance to ``Attachable``. When you import the
56+
[Foundation](https://developer.apple.com/documentation/foundation) module, the
57+
testing library automatically provides a default implementation of
58+
``Attachable`` to types that also conform to [`Encodable`](https://developer.apple.com/documentation/swift/encodable)
59+
or [`NSSecureCoding`](https://developer.apple.com/documentation/foundation/nssecurecoding).
60+
61+
```swift
62+
import Testing
63+
import Foundation
64+
65+
struct SalesReport { ... }
66+
extension SalesReport: Encodable, Attachable {}
67+
68+
@Test func `sales report adds up`() async throws {
69+
let salesReport = await generateSalesReport()
70+
try salesReport.validate()
71+
Attachment.record(salesReport, named: "sales report.json")
72+
}
73+
```
74+
75+
- Important: The testing library provides these default implementations only if
76+
your test target imports the [Foundation](https://developer.apple.com/documentation/foundation)
77+
module.
78+
79+
### Attach images
80+
81+
You can attach instances of the following system-provided image types to a test:
82+
83+
| Platform | Supported types |
84+
|-|-|
85+
| macOS | [`CGImage`](https://developer.apple.com/documentation/coregraphics/cgimage), [`CIImage`](https://developer.apple.com/documentation/coreimage/ciimage), [`NSImage`](https://developer.apple.com/documentation/appkit/nsimage) |
86+
| iOS, tvOS, and visionOS | [`CGImage`](https://developer.apple.com/documentation/coregraphics/cgimage), [`CIImage`](https://developer.apple.com/documentation/coreimage/ciimage), [`UIImage`](https://developer.apple.com/documentation/uikit/uiimage) |
87+
| watchOS | [`CGImage`](https://developer.apple.com/documentation/coregraphics/cgimage), [`UIImage`](https://developer.apple.com/documentation/uikit/uiimage) |
88+
| Windows | [`HBITMAP`](https://learn.microsoft.com/en-us/windows/win32/gdi/bitmaps), [`HICON`](https://learn.microsoft.com/en-us/windows/win32/menurc/icons), [`IWICBitmapSource`](https://learn.microsoft.com/en-us/windows/win32/api/wincodec/nn-wincodec-iwicbitmapsource) (including its subclasses declared by Windows Imaging Component) |
89+
90+
When you attach an image to a test, you can specify the image format to use in
91+
addition to a preferred name.
92+
93+
```swift
94+
struct SalesReport { ... }
95+
96+
@Test func `sales report adds up`() async throws {
97+
let salesReport = await generateSalesReport()
98+
let image = try salesReport.renderTrendsGraph()
99+
Attachment.record(image, named: "sales report", as: .png)
100+
}
101+
```
102+
103+
If you don't specify an image format when attaching an image to a test, the
104+
testing library selects the format to use based on the preferred name you pass.
105+
106+
### Attach other values
107+
108+
If you have a value that needs a custom encoded representation when you save it
109+
as an attachment, implement ``Attachable/withUnsafeBytes(for:_:)``. The
110+
implementation of this function calls its `body` argument and passes the encoded
111+
representation of `self` or, if a failure occurs, throws an error representing
112+
that failure.
113+
114+
```swift
115+
struct SalesReport { ... }
116+
117+
extension SalesReport: Attachable {
118+
borrowing func withUnsafeBytes<R>(
119+
for attachment: borrowing Attachment<Self>,
120+
_ body: (UnsafeRawBufferPointer) throws -> R
121+
) throws -> R {
122+
let bytes = try salesReport.convertToCSV() // might fail to convert to CSV
123+
try bytes.withUnsafeBytes { buffer in // rethrows any error from `body`
124+
try body(buffer)
125+
}
126+
}
127+
}
128+
```
129+
130+
If your type conforms to [`Sendable`](https://developer.apple.com/documentation/swift/sendable),
131+
the testing library avoids calling this function until it needs to save the
132+
attachment. If your type _doesn't_ conform to [`Sendable`](https://developer.apple.com/documentation/swift/sendable),
133+
the testing library calls this function as soon as you record the attachment.
134+
135+
#### Customize attachment behavior
136+
137+
If you can reliably estimate in advance how large the encoded representation
138+
will be, implement ``Attachable/estimatedAttachmentByteCount``. The testing
139+
library uses the value of this property as a hint to optimize memory and disk
140+
usage.
141+
142+
```swift
143+
extension SalesReport: Attachable {
144+
...
145+
146+
var estimatedAttachmentByteCount: Int? {
147+
return self.entries.count * 123
148+
}
149+
}
150+
```
151+
152+
You can also implement ``Attachable/preferredName(for:basedOn:)`` if you want to
153+
customize the name of the attachment when saving it.
154+
155+
```swift
156+
extension SalesReport: Attachable {
157+
...
158+
159+
borrowing func preferredName(
160+
for attachment: borrowing Attachment<Self>,
161+
basedOn suggestedName: String
162+
) -> String {
163+
if suggestedName.contains(".") {
164+
// The name already contains a path extension, so don't append another.
165+
return suggestedName
166+
}
167+
168+
// Append ".csv" to the name so the resulting file opens as a spreadsheet.
169+
return "\(suggestedName).csv"
170+
}
171+
}
172+
```
173+
174+
### Inspect attachments after a test run ends
175+
176+
By default, the testing library saves your attachments as soon as you call
177+
``Attachment/record(_:sourceLocation:)`` or
178+
``Attachment/record(_:named:sourceLocation:)``. You can access saved attachments
179+
after your tests finish running:
180+
181+
- When using Xcode, you can access attachments from the test report.
182+
- When using Visual Studio Code, the testing library saves attachments to
183+
`.build/attachments` by default. Visual Studio Code reports the paths to
184+
individual attachments in its Tests Results panel.
185+
- When using Swift Package Manager's `swift test` command, you can pass the
186+
`--attachments-path` option. The testing library saves attachments to the
187+
specified directory.
188+
189+
If you do not pass the `--attachments-path` option, the testing library does
190+
not save any attachments you record.
191+
192+
20193
## Topics
21194

22195
### Attaching values to tests

0 commit comments

Comments
 (0)