Skip to content

Commit 63d4ef2

Browse files
authored
Merge pull request #1088 from stmontgomery/main-6.2-merge
Merge 'main' branch to 'release/6.2'
2 parents 9810afe + ef2df0c commit 63d4ef2

File tree

59 files changed

+1676
-368
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1676
-368
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

Documentation/ABI/TestContent.md

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,10 @@ or a third-party library are inadvertently loaded into the same process. If the
126126
value at `type` does not match the test content record's expected type, the
127127
accessor function must return `false` and must not modify `outValue`.
128128

129-
<!-- TODO: discuss this argument's value in Embedded Swift (no metatypes) -->
129+
When building for **Embedded Swift**, the value passed as `type` by Swift
130+
Testing is unspecified because type metadata pointers are not available in that
131+
environment.
132+
<!-- TODO: specify what they are instead (FQN type name C strings maybe?) -->
130133

131134
[^mightNotBeSwift]: Although this document primarily deals with Swift, the test
132135
content record section is generally language-agnostic. The use of languages
@@ -146,25 +149,12 @@ The fourth argument to this function, `reserved`, is reserved for future use.
146149
Accessor functions should assume it is `0` and must not access it.
147150

148151
The concrete Swift type of the value written to `outValue`, the type pointed to
149-
by `type`, and the value pointed to by `hint` depend on the kind of record:
152+
by `type`, and the value pointed to by `hint` depend on the kind of record.
150153

151-
- For test or suite declarations (kind `0x74657374`), the accessor produces a
152-
structure of type `Testing.Test.Generator` that the testing library can use
153-
to generate the corresponding test[^notAccessorSignature].
154-
155-
[^notAccessorSignature]: This level of indirection is necessary because
156-
loading a test or suite declaration is an asynchronous operation, but C
157-
functions cannot be `async`.
158-
159-
Test content records of this kind do not specify a type for `hint`. Always
160-
pass `nil`.
161-
162-
- For exit test declarations (kind `0x65786974`), the accessor produces a
163-
structure describing the exit test (of type `Testing.ExitTest`.)
164-
165-
Test content records of this kind accept a `hint` of type `Testing.ExitTest.ID`.
166-
They only produce a result if they represent an exit test declared with the
167-
same ID (or if `hint` is `nil`.)
154+
The record kinds defined by Swift Testing (kinds `0x74657374` and `0x65786974`)
155+
make use of the `DiscoverableAsTestContent` protocol in the `_TestDiscovery`
156+
module and do not publicly expose the types of their accessor functions'
157+
arguments. Do not call the accessor functions for these records directly.
168158

169159
> [!WARNING]
170160
> Calling code should use [`withUnsafeTemporaryAllocation(of:capacity:_:)`](https://developer.apple.com/documentation/swift/withunsafetemporaryallocation(of:capacity:_:))
@@ -271,7 +261,8 @@ extension FoodTruckDiagnostic: DiscoverableAsTestContent {
271261
```
272262

273263
If you customize `TestContentContext`, be aware that the type you specify must
274-
have the same stride and alignment as `UInt`.
264+
have the same stride as `UInt` and must have an alignment less than or equal to
265+
that of `UInt`.
275266

276267
When you are done configuring your type's protocol conformance, you can then
277268
enumerate all test content records matching it as instances of

Package.swift

Lines changed: 116 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
// swift-tools-version: 6.0
1+
// swift-tools-version: 6.1
22

33
//
44
// This source file is part of the Swift.org open source project
55
//
6-
// Copyright (c) 2023 Apple Inc. and the Swift project authors
6+
// Copyright (c) 2023–2025 Apple Inc. and the Swift project authors
77
// Licensed under Apache License v2.0 with Runtime Library Exception
88
//
99
// See https://swift.org/LICENSE.txt for license information
@@ -20,17 +20,49 @@ let git = Context.gitInformation
2020
/// distribution as a package dependency.
2121
let buildingForDevelopment = (git?.currentTag == nil)
2222

23+
/// Whether or not this package is being built for Embedded Swift.
24+
///
25+
/// This value is `true` if `SWT_EMBEDDED` is set in the environment to `true`
26+
/// when `swift build` is invoked. This inference is experimental and is subject
27+
/// to change in the future.
28+
///
29+
/// - Bug: There is currently no way for us to tell if we are being asked to
30+
/// build for an Embedded Swift target at the package manifest level.
31+
/// ([swift-syntax-#8431](https://github.com/swiftlang/swift-package-manager/issues/8431))
32+
let buildingForEmbedded: Bool = {
33+
guard let envvar = Context.environment["SWT_EMBEDDED"] else {
34+
return false
35+
}
36+
return Bool(envvar) ?? ((Int(envvar) ?? 0) != 0)
37+
}()
38+
2339
let package = Package(
2440
name: "swift-testing",
2541

26-
platforms: [
27-
.macOS(.v10_15),
28-
.iOS(.v13),
29-
.watchOS(.v6),
30-
.tvOS(.v13),
31-
.macCatalyst(.v13),
32-
.visionOS(.v1),
33-
],
42+
platforms: {
43+
if !buildingForEmbedded {
44+
[
45+
.macOS(.v10_15),
46+
.iOS(.v13),
47+
.watchOS(.v6),
48+
.tvOS(.v13),
49+
.macCatalyst(.v13),
50+
.visionOS(.v1),
51+
]
52+
} else {
53+
// Open-source main-branch toolchains (currently required to build this
54+
// package for Embedded Swift) have higher Apple platform deployment
55+
// targets than we would otherwise require.
56+
[
57+
.macOS(.v14),
58+
.iOS(.v18),
59+
.watchOS(.v10),
60+
.tvOS(.v18),
61+
.macCatalyst(.v18),
62+
.visionOS(.v1),
63+
]
64+
}
65+
}(),
3466

3567
products: {
3668
var result = [Product]()
@@ -63,8 +95,15 @@ let package = Package(
6395
return result
6496
}(),
6597

98+
traits: [
99+
.trait(
100+
name: "ExperimentalExitTestValueCapture",
101+
description: "Enable experimental support for capturing values in exit tests"
102+
),
103+
],
104+
66105
dependencies: [
67-
.package(url: "https://github.com/swiftlang/swift-syntax.git", from: "601.0.0-latest"),
106+
.package(url: "https://github.com/swiftlang/swift-syntax.git", from: "602.0.0-latest"),
68107
],
69108

70109
targets: [
@@ -132,7 +171,7 @@ let package = Package(
132171
dependencies: ["_TestingInternals",],
133172
exclude: ["CMakeLists.txt"],
134173
cxxSettings: .packageSettings,
135-
swiftSettings: .packageSettings
174+
swiftSettings: .packageSettings + .enableLibraryEvolution()
136175
),
137176

138177
// Cross-import overlays (not supported by Swift Package Manager)
@@ -185,6 +224,32 @@ package.targets.append(contentsOf: [
185224
])
186225
#endif
187226

227+
extension BuildSettingCondition {
228+
/// Creates a build setting condition that evaluates to `true` for Embedded
229+
/// Swift.
230+
///
231+
/// - Parameters:
232+
/// - nonEmbeddedCondition: The value to return if the target is not
233+
/// Embedded Swift. If `nil`, the build condition evaluates to `false`.
234+
///
235+
/// - Returns: A build setting condition that evaluates to `true` for Embedded
236+
/// Swift or is equal to `nonEmbeddedCondition` for non-Embedded Swift.
237+
static func whenEmbedded(or nonEmbeddedCondition: @autoclosure () -> Self? = nil) -> Self? {
238+
if !buildingForEmbedded {
239+
if let nonEmbeddedCondition = nonEmbeddedCondition() {
240+
nonEmbeddedCondition
241+
} else {
242+
// The caller did not supply a fallback. Specify a non-existent platform
243+
// to ensure this condition never matches.
244+
.when(platforms: [.custom("DoesNotExist")])
245+
}
246+
} else {
247+
// Enable unconditionally because the target is Embedded Swift.
248+
nil
249+
}
250+
}
251+
}
252+
188253
extension Array where Element == PackageDescription.SwiftSetting {
189254
/// Settings intended to be applied to every Swift target in this package.
190255
/// Analogous to project-level build settings in an Xcode project.
@@ -195,6 +260,10 @@ extension Array where Element == PackageDescription.SwiftSetting {
195260
result.append(.unsafeFlags(["-require-explicit-sendable"]))
196261
}
197262

263+
if buildingForEmbedded {
264+
result.append(.enableExperimentalFeature("Embedded"))
265+
}
266+
198267
result += [
199268
.enableUpcomingFeature("ExistentialAny"),
200269

@@ -208,19 +277,41 @@ extension Array where Element == PackageDescription.SwiftSetting {
208277
// proposal via Swift Evolution.
209278
.enableExperimentalFeature("SymbolLinkageMarkers"),
210279

280+
// This setting is no longer needed when building with a 6.2 or later
281+
// toolchain now that SE-0458 has been accepted and implemented, but it is
282+
// needed in order to preserve support for building with 6.1 development
283+
// snapshot toolchains. (Production 6.1 toolchains can build the testing
284+
// library even without this setting since this experimental feature is
285+
// _suppressible_.) This setting can be removed once the minimum supported
286+
// toolchain for building the testing library is ≥ 6.2. It is not needed
287+
// in the CMake settings since that is expected to build using a
288+
// new-enough toolchain.
289+
.enableExperimentalFeature("AllowUnsafeAttribute"),
290+
211291
// When building as a package, the macro plugin always builds as an
212292
// executable rather than a library.
213293
.define("SWT_NO_LIBRARY_MACRO_PLUGINS"),
214294

215295
.define("SWT_TARGET_OS_APPLE", .when(platforms: [.macOS, .iOS, .macCatalyst, .watchOS, .tvOS, .visionOS])),
216296

217-
.define("SWT_NO_EXIT_TESTS", .when(platforms: [.iOS, .watchOS, .tvOS, .visionOS, .wasi, .android])),
218-
.define("SWT_NO_PROCESS_SPAWNING", .when(platforms: [.iOS, .watchOS, .tvOS, .visionOS, .wasi, .android])),
219-
.define("SWT_NO_SNAPSHOT_TYPES", .when(platforms: [.linux, .custom("freebsd"), .openbsd, .windows, .wasi, .android])),
220-
.define("SWT_NO_DYNAMIC_LINKING", .when(platforms: [.wasi])),
221-
.define("SWT_NO_PIPES", .when(platforms: [.wasi])),
297+
.define("SWT_NO_EXIT_TESTS", .whenEmbedded(or: .when(platforms: [.iOS, .watchOS, .tvOS, .visionOS, .wasi, .android]))),
298+
.define("SWT_NO_PROCESS_SPAWNING", .whenEmbedded(or: .when(platforms: [.iOS, .watchOS, .tvOS, .visionOS, .wasi, .android]))),
299+
.define("SWT_NO_SNAPSHOT_TYPES", .whenEmbedded(or: .when(platforms: [.linux, .custom("freebsd"), .openbsd, .windows, .wasi, .android]))),
300+
.define("SWT_NO_DYNAMIC_LINKING", .whenEmbedded(or: .when(platforms: [.wasi]))),
301+
.define("SWT_NO_PIPES", .whenEmbedded(or: .when(platforms: [.wasi]))),
302+
303+
.define("SWT_NO_LEGACY_TEST_DISCOVERY", .whenEmbedded()),
304+
.define("SWT_NO_LIBDISPATCH", .whenEmbedded()),
222305
]
223306

307+
// Unconditionally enable 'ExperimentalExitTestValueCapture' when building
308+
// for development.
309+
if buildingForDevelopment {
310+
result += [
311+
.define("ExperimentalExitTestValueCapture")
312+
]
313+
}
314+
224315
return result
225316
}
226317

@@ -271,11 +362,14 @@ extension Array where Element == PackageDescription.CXXSetting {
271362
var result = Self()
272363

273364
result += [
274-
.define("SWT_NO_EXIT_TESTS", .when(platforms: [.iOS, .watchOS, .tvOS, .visionOS, .wasi, .android])),
275-
.define("SWT_NO_PROCESS_SPAWNING", .when(platforms: [.iOS, .watchOS, .tvOS, .visionOS, .wasi, .android])),
276-
.define("SWT_NO_SNAPSHOT_TYPES", .when(platforms: [.linux, .custom("freebsd"), .openbsd, .windows, .wasi, .android])),
277-
.define("SWT_NO_DYNAMIC_LINKING", .when(platforms: [.wasi])),
278-
.define("SWT_NO_PIPES", .when(platforms: [.wasi])),
365+
.define("SWT_NO_EXIT_TESTS", .whenEmbedded(or: .when(platforms: [.iOS, .watchOS, .tvOS, .visionOS, .wasi, .android]))),
366+
.define("SWT_NO_PROCESS_SPAWNING", .whenEmbedded(or: .when(platforms: [.iOS, .watchOS, .tvOS, .visionOS, .wasi, .android]))),
367+
.define("SWT_NO_SNAPSHOT_TYPES", .whenEmbedded(or: .when(platforms: [.linux, .custom("freebsd"), .openbsd, .windows, .wasi, .android]))),
368+
.define("SWT_NO_DYNAMIC_LINKING", .whenEmbedded(or: .when(platforms: [.wasi]))),
369+
.define("SWT_NO_PIPES", .whenEmbedded(or: .when(platforms: [.wasi]))),
370+
371+
.define("SWT_NO_LEGACY_TEST_DISCOVERY", .whenEmbedded()),
372+
.define("SWT_NO_LIBDISPATCH", .whenEmbedded()),
279373
]
280374

281375
// Capture the testing library's version as a C++ string constant.

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,15 @@ very best ideas, from anywhere, can help shape the future of testing in Swift.
9393
The table below describes the current level of support that Swift Testing has
9494
for various platforms:
9595

96-
| **Platform** | **CI Status (6.0)** | **CI Status (main)** | **Support Status** |
96+
| **Platform** | **CI Status (6.1)** | **CI Status (main)** | **Support Status** |
9797
|---|:-:|:-:|---|
98-
| **macOS** | [![Build Status](https://ci.swift.org/buildStatus/icon?job=swift-testing-main-swift-6.0-macos)](https://ci.swift.org/job/swift-testing-main-swift-6.0-macos/) | [![Build Status](https://ci.swift.org/buildStatus/icon?job=swift-testing-main-swift-main-macos)](https://ci.swift.org/view/Swift%20Packages/job/swift-testing-main-swift-main-macos/) | Supported |
98+
| **macOS** | [![Build Status](https://ci.swift.org/buildStatus/icon?job=swift-testing-main-swift-6.1-macos)](https://ci.swift.org/job/swift-testing-main-swift-6.1-macos/) | [![Build Status](https://ci.swift.org/buildStatus/icon?job=swift-testing-main-swift-main-macos)](https://ci.swift.org/view/Swift%20Packages/job/swift-testing-main-swift-main-macos/) | Supported |
9999
| **iOS** | | | Supported |
100100
| **watchOS** | | | Supported |
101101
| **tvOS** | | | Supported |
102102
| **visionOS** | | | Supported |
103-
| **Ubuntu 22.04** | [![Build Status](https://ci.swift.org/buildStatus/icon?job=swift-testing-main-swift-6.0-linux)](https://ci.swift.org/job/swift-testing-main-swift-6.0-linux/) | [![Build Status](https://ci.swift.org/buildStatus/icon?job=swift-testing-main-swift-main-linux)](https://ci.swift.org/view/Swift%20Packages/job/swift-testing-main-swift-main-linux/) | Supported |
104-
| **Windows** | | [![Build Status](https://ci-external.swift.org/buildStatus/icon?job=swift-testing-main-swift-main-windows)](https://ci-external.swift.org/job/swift-testing-main-swift-main-windows/) | Supported |
103+
| **Ubuntu 22.04** | [![Build Status](https://ci.swift.org/buildStatus/icon?job=swift-testing-main-swift-6.1-linux)](https://ci.swift.org/job/swift-testing-main-swift-6.1-linux/) | [![Build Status](https://ci.swift.org/buildStatus/icon?job=swift-testing-main-swift-main-linux)](https://ci.swift.org/view/Swift%20Packages/job/swift-testing-main-swift-main-linux/) | Supported |
104+
| **Windows** | [![Build Status](https://ci.swift.org/buildStatus/icon?job=swift-testing-main-swift-6.1-windows)](https://ci-external.swift.org/view/all/job/swift-testing-main-swift-6.1-windows/) | [![Build Status](https://ci-external.swift.org/buildStatus/icon?job=swift-testing-main-swift-main-windows)](https://ci-external.swift.org/job/swift-testing-main-swift-main-windows/) | Supported |
105105
| **Wasm** | | | Experimental |
106106

107107
### Works with XCTest

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 {

0 commit comments

Comments
 (0)