Skip to content

Commit 78f6ced

Browse files
authored
Promote Darwin image attachments to API. (#1274)
This PR promotes image attachments on Apple platforms to API (pending approval of ST-0014). ### 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 a8a3fcb commit 78f6ced

26 files changed

+237
-48
lines changed

Sources/Overlays/CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
# This source file is part of the Swift.org open source project
22
#
3-
# Copyright (c) 2024 Apple Inc. and the Swift project authors
3+
# Copyright (c) 2024–2025 Apple Inc. and the Swift project authors
44
# Licensed under Apache License v2.0 with Runtime Library Exception
55
#
66
# See http://swift.org/LICENSE.txt for license information
77
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
88

9+
add_subdirectory(_Testing_AppKit)
10+
add_subdirectory(_Testing_CoreGraphics)
11+
add_subdirectory(_Testing_CoreImage)
912
add_subdirectory(_Testing_Foundation)
13+
add_subdirectory(_Testing_UIKit)

Sources/Overlays/_Testing_AppKit/Attachments/NSImage+AttachableAsCGImage.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// This source file is part of the Swift.org open source project
33
//
4-
// Copyright (c) 2024 Apple Inc. and the Swift project authors
4+
// Copyright (c) 2024–2025 Apple Inc. and the Swift project authors
55
// Licensed under Apache License v2.0 with Runtime Library Exception
66
//
77
// See https://swift.org/LICENSE.txt for license information
@@ -10,7 +10,7 @@
1010

1111
#if SWT_TARGET_OS_APPLE && canImport(AppKit)
1212
public import AppKit
13-
@_spi(Experimental) public import _Testing_CoreGraphics
13+
public import _Testing_CoreGraphics
1414

1515
extension NSImageRep {
1616
/// AppKit's bundle.
@@ -33,8 +33,13 @@ extension NSImageRep {
3333

3434
// MARK: -
3535

36-
@_spi(Experimental)
36+
/// @Metadata {
37+
/// @Available(Swift, introduced: 6.3)
38+
/// }
3739
extension NSImage: AttachableAsCGImage {
40+
/// @Metadata {
41+
/// @Available(Swift, introduced: 6.3)
42+
/// }
3843
public var attachableCGImage: CGImage {
3944
get throws {
4045
let ctm = AffineTransform(scale: _attachmentScaleFactor) as NSAffineTransform
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# This source file is part of the Swift.org open source project
2+
#
3+
# Copyright (c) 2024–2025 Apple Inc. and the Swift project authors
4+
# Licensed under Apache License v2.0 with Runtime Library Exception
5+
#
6+
# See http://swift.org/LICENSE.txt for license information
7+
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
8+
9+
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
10+
add_library(_Testing_AppKit
11+
Attachments/NSImage+AttachableAsCGImage.swift
12+
ReexportTesting.swift)
13+
14+
target_link_libraries(_Testing_AppKit PUBLIC
15+
Testing
16+
_Testing_CoreGraphics)
17+
18+
target_compile_options(_Testing_AppKit PRIVATE
19+
-enable-library-evolution
20+
-emit-module-interface -emit-module-interface-path $<TARGET_PROPERTY:_Testing_AppKit,Swift_MODULE_DIRECTORY>/_Testing_AppKit.swiftinterface)
21+
22+
_swift_testing_install_target(_Testing_AppKit)
23+
endif()
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
//
22
// This source file is part of the Swift.org open source project
33
//
4-
// Copyright (c) 2024 Apple Inc. and the Swift project authors
4+
// Copyright (c) 2024–2025 Apple Inc. and the Swift project authors
55
// Licensed under Apache License v2.0 with Runtime Library Exception
66
//
77
// See https://swift.org/LICENSE.txt for license information
88
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
99
//
1010

11-
@_exported @_spi(Experimental) @_spi(ForToolsIntegrationOnly) public import Testing
12-
@_exported @_spi(Experimental) @_spi(ForToolsIntegrationOnly) public import _Testing_CoreGraphics
11+
@_exported public import Testing
12+
@_exported public import _Testing_CoreGraphics

Sources/Overlays/_Testing_CoreGraphics/Attachments/AttachableAsCGImage.swift

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// This source file is part of the Swift.org open source project
33
//
4-
// Copyright (c) 2024 Apple Inc. and the Swift project authors
4+
// Copyright (c) 2024–2025 Apple Inc. and the Swift project authors
55
// Licensed under Apache License v2.0 with Runtime Library Exception
66
//
77
// See https://swift.org/LICENSE.txt for license information
@@ -13,12 +13,12 @@ public import CoreGraphics
1313
private import ImageIO
1414

1515
/// A protocol describing images that can be converted to instances of
16-
/// ``Testing/Attachment``.
16+
/// [`Attachment`](https://developer.apple.com/documentation/testing/attachment).
1717
///
1818
/// Instances of types conforming to this protocol do not themselves conform to
19-
/// ``Testing/Attachable``. Instead, the testing library provides additional
20-
/// initializers on ``Testing/Attachment`` that take instances of such types and
21-
/// handle converting them to image data when needed.
19+
/// [`Attachable`](https://developer.apple.com/documentation/testing/attachable).
20+
/// Instead, the testing library provides additional initializers on [`Attachment`](https://developer.apple.com/documentation/testing/attachment)
21+
/// that take instances of such types and handle converting them to image data when needed.
2222
///
2323
/// You can attach instances of the following system-provided image types to a
2424
/// test:
@@ -27,17 +27,26 @@ private import ImageIO
2727
/// |-|-|
2828
/// | 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) |
2929
/// | 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) |
30+
/// @Comment {
3031
/// | 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) |
32+
/// }
3133
///
3234
/// You do not generally need to add your own conformances to this protocol. If
3335
/// you have an image in another format that needs to be attached to a test,
3436
/// first convert it to an instance of one of the types above.
35-
@_spi(Experimental)
37+
///
38+
/// @Metadata {
39+
/// @Available(Swift, introduced: 6.3)
40+
/// }
3641
@available(_uttypesAPI, *)
3742
public protocol AttachableAsCGImage: SendableMetatype {
3843
/// An instance of `CGImage` representing this image.
3944
///
4045
/// - Throws: Any error that prevents the creation of an image.
46+
///
47+
/// @Metadata {
48+
/// @Available(Swift, introduced: 6.3)
49+
/// }
4150
var attachableCGImage: CGImage { get throws }
4251

4352
/// The orientation of the image.

Sources/Overlays/_Testing_CoreGraphics/Attachments/AttachableImageFormat+UTType.swift

Lines changed: 9 additions & 1 deletion
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

1414
public import UniformTypeIdentifiers
1515

@@ -64,6 +64,10 @@ extension AttachableImageFormat {
6464
/// The content type corresponding to this image format.
6565
///
6666
/// The value of this property always conforms to [`UTType.image`](https://developer.apple.com/documentation/uniformtypeidentifiers/uttype-swift.struct/image).
67+
///
68+
/// @Metadata {
69+
/// @Available(Swift, introduced: 6.3)
70+
/// }
6771
public var contentType: UTType {
6872
switch kind {
6973
case .png:
@@ -89,6 +93,10 @@ extension AttachableImageFormat {
8993
///
9094
/// If `contentType` does not conform to [`UTType.image`](https://developer.apple.com/documentation/uniformtypeidentifiers/uttype-swift.struct/image),
9195
/// the result is undefined.
96+
///
97+
/// @Metadata {
98+
/// @Available(Swift, introduced: 6.3)
99+
/// }
92100
public init(_ contentType: UTType, encodingQuality: Float = 1.0) {
93101
precondition(
94102
contentType.conforms(to: .image),

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
//
22
// This source file is part of the Swift.org open source project
33
//
4-
// Copyright (c) 2024 Apple Inc. and the Swift project authors
4+
// Copyright (c) 2024–2025 Apple Inc. and the Swift project authors
55
// Licensed under Apache License v2.0 with Runtime Library Exception
66
//
77
// See https://swift.org/LICENSE.txt for license information
88
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
99
//
1010

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

14-
@_spi(Experimental)
1514
@available(_uttypesAPI, *)
1615
extension Attachment {
1716
/// Initialize an instance of this type that encloses the given image.
@@ -33,7 +32,9 @@ extension Attachment {
3332
/// |-|-|
3433
/// | 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) |
3534
/// | 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) |
35+
/// @Comment {
3636
/// | 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) |
37+
/// }
3738
///
3839
/// The testing library uses the image format specified by `imageFormat`. Pass
3940
/// `nil` to let the testing library decide which image format to use. If you
@@ -42,6 +43,10 @@ extension Attachment {
4243
/// specify a path extension, or if the path extension you specify doesn't
4344
/// correspond to an image format the operating system knows how to write, the
4445
/// testing library selects an appropriate image format for you.
46+
///
47+
/// @Metadata {
48+
/// @Available(Swift, introduced: 6.3)
49+
/// }
4550
public init<T>(
4651
_ image: T,
4752
named preferredName: String? = nil,
@@ -74,7 +79,9 @@ extension Attachment {
7479
/// |-|-|
7580
/// | 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) |
7681
/// | 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) |
82+
/// @Comment {
7783
/// | 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) |
84+
/// }
7885
///
7986
/// The testing library uses the image format specified by `imageFormat`. Pass
8087
/// `nil` to let the testing library decide which image format to use. If you
@@ -83,8 +90,12 @@ extension Attachment {
8390
/// specify a path extension, or if the path extension you specify doesn't
8491
/// correspond to an image format the operating system knows how to write, the
8592
/// testing library selects an appropriate image format for you.
93+
///
94+
/// @Metadata {
95+
/// @Available(Swift, introduced: 6.3)
96+
/// }
8697
public static func record<T>(
87-
_ image: consuming T,
98+
_ image: T,
8899
named preferredName: String? = nil,
89100
as imageFormat: AttachableImageFormat? = nil,
90101
sourceLocation: SourceLocation = #_sourceLocation

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// This source file is part of the Swift.org open source project
33
//
4-
// Copyright (c) 2024 Apple Inc. and the Swift project authors
4+
// Copyright (c) 2024–2025 Apple Inc. and the Swift project authors
55
// Licensed under Apache License v2.0 with Runtime Library Exception
66
//
77
// See https://swift.org/LICENSE.txt for license information
@@ -11,8 +11,13 @@
1111
#if SWT_TARGET_OS_APPLE && canImport(CoreGraphics)
1212
public import CoreGraphics
1313

14-
@_spi(Experimental)
14+
/// @Metadata {
15+
/// @Available(Swift, introduced: 6.3)
16+
/// }
1517
extension CGImage: AttachableAsCGImage {
18+
/// @Metadata {
19+
/// @Available(Swift, introduced: 6.3)
20+
/// }
1621
public var attachableCGImage: CGImage {
1722
self
1823
}

Sources/Overlays/_Testing_CoreGraphics/Attachments/_AttachableImageWrapper+AttachableWrapper.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
//
22
// This source file is part of the Swift.org open source project
33
//
4-
// Copyright (c) 2024 Apple Inc. and the Swift project authors
4+
// Copyright (c) 2024–2025 Apple Inc. and the Swift project authors
55
// Licensed under Apache License v2.0 with Runtime Library Exception
66
//
77
// See https://swift.org/LICENSE.txt for license information
88
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
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
@@ -39,7 +39,6 @@ private import UniformTypeIdentifiers
3939
/// useful.)
4040

4141
@available(_uttypesAPI, *)
42-
@_spi(Experimental)
4342
extension _AttachableImageWrapper: Attachable, AttachableWrapper where Image: AttachableAsCGImage {
4443
public func withUnsafeBytes<R>(for attachment: borrowing Attachment<_AttachableImageWrapper>, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
4544
let data = NSMutableData()
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# This source file is part of the Swift.org open source project
2+
#
3+
# Copyright (c) 2024–2025 Apple Inc. and the Swift project authors
4+
# Licensed under Apache License v2.0 with Runtime Library Exception
5+
#
6+
# See http://swift.org/LICENSE.txt for license information
7+
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
8+
9+
if(APPLE)
10+
add_library(_Testing_CoreGraphics
11+
Attachments/_AttachableImageWrapper+AttachableWrapper.swift
12+
Attachments/AttachableAsCGImage.swift
13+
Attachments/AttachableImageFormat+UTType.swift
14+
Attachments/Attachment+AttachableAsCGImage.swift
15+
Attachments/CGImage+AttachableAsCGImage.swift
16+
ReexportTesting.swift)
17+
18+
target_link_libraries(_Testing_CoreGraphics PUBLIC
19+
Testing)
20+
21+
target_compile_options(_Testing_CoreGraphics PRIVATE
22+
-enable-library-evolution
23+
-emit-module-interface -emit-module-interface-path $<TARGET_PROPERTY:_Testing_CoreGraphics,Swift_MODULE_DIRECTORY>/_Testing_CoreGraphics.swiftinterface)
24+
25+
_swift_testing_install_target(_Testing_CoreGraphics)
26+
endif()

0 commit comments

Comments
 (0)