diff --git a/Package.swift b/Package.swift index 3a66ef039..8085d7bc8 100644 --- a/Package.swift +++ b/Package.swift @@ -197,7 +197,6 @@ extension Array where Element == PackageDescription.SwiftSetting { result += [ .enableUpcomingFeature("ExistentialAny"), - .enableExperimentalFeature("SuppressedAssociatedTypes"), .enableExperimentalFeature("AccessLevelOnImport"), .enableUpcomingFeature("InternalImportsByDefault"), diff --git a/Sources/Overlays/_Testing_CoreGraphics/Attachments/_AttachableImageContainer.swift b/Sources/Overlays/_Testing_CoreGraphics/Attachments/_AttachableImageContainer.swift index 9db225826..90d1c0c70 100644 --- a/Sources/Overlays/_Testing_CoreGraphics/Attachments/_AttachableImageContainer.swift +++ b/Sources/Overlays/_Testing_CoreGraphics/Attachments/_AttachableImageContainer.swift @@ -32,7 +32,7 @@ import UniformTypeIdentifiers /// such a requirement, and all image types we care about are non-final /// classes. Thus, the compiler will steadfastly refuse to allow non-final /// classes to conform to the `Attachable` protocol. We could get around this -/// by changing the signature of `withUnsafeBufferPointer()` so that the +/// by changing the signature of `withUnsafeBytes()` so that the /// generic parameter to `Attachment` is not `Self`, but that would defeat /// much of the purpose of making `Attachment` generic in the first place. /// (And no, the language does not let us write `where T: Self` anywhere @@ -132,7 +132,7 @@ extension _AttachableImageContainer: AttachableContainer { image } - public func withUnsafeBufferPointer(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { + public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { let data = NSMutableData() // Convert the image to a CGImage. diff --git a/Sources/Overlays/_Testing_Foundation/Attachments/Attachable+Encodable+NSSecureCoding.swift b/Sources/Overlays/_Testing_Foundation/Attachments/Attachable+Encodable+NSSecureCoding.swift index 80c75b5e9..cd26c24cc 100644 --- a/Sources/Overlays/_Testing_Foundation/Attachments/Attachable+Encodable+NSSecureCoding.swift +++ b/Sources/Overlays/_Testing_Foundation/Attachments/Attachable+Encodable+NSSecureCoding.swift @@ -21,8 +21,8 @@ public import Foundation @_spi(Experimental) extension Attachable where Self: Encodable & NSSecureCoding { @_documentation(visibility: private) - public func withUnsafeBufferPointer(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { - try _Testing_Foundation.withUnsafeBufferPointer(encoding: self, for: attachment, body) + public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { + try _Testing_Foundation.withUnsafeBytes(encoding: self, for: attachment, body) } } #endif diff --git a/Sources/Overlays/_Testing_Foundation/Attachments/Attachable+Encodable.swift b/Sources/Overlays/_Testing_Foundation/Attachments/Attachable+Encodable.swift index cfae97ca7..812db0b70 100644 --- a/Sources/Overlays/_Testing_Foundation/Attachments/Attachable+Encodable.swift +++ b/Sources/Overlays/_Testing_Foundation/Attachments/Attachable+Encodable.swift @@ -12,9 +12,9 @@ @_spi(Experimental) public import Testing private import Foundation -/// A common implementation of ``withUnsafeBufferPointer(for:_:)`` that is -/// used when a type conforms to `Encodable`, whether or not it also conforms -/// to `NSSecureCoding`. +/// A common implementation of ``withUnsafeBytes(for:_:)`` that is used when a +/// type conforms to `Encodable`, whether or not it also conforms to +/// `NSSecureCoding`. /// /// - Parameters: /// - attachableValue: The value to encode. @@ -27,7 +27,7 @@ private import Foundation /// /// - Throws: Whatever is thrown by `body`, or any error that prevented the /// creation of the buffer. -func withUnsafeBufferPointer(encoding attachableValue: borrowing E, for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R where E: Attachable & Encodable { +func withUnsafeBytes(encoding attachableValue: borrowing E, for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R where E: Attachable & Encodable { let format = try EncodingFormat(for: attachment) let data: Data @@ -86,8 +86,8 @@ extension Attachable where Self: Encodable { /// _and_ [`NSSecureCoding`](https://developer.apple.com/documentation/foundation/nssecurecoding), /// the default implementation of this function uses the value's conformance /// to `Encodable`. - public func withUnsafeBufferPointer(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { - try _Testing_Foundation.withUnsafeBufferPointer(encoding: self, for: attachment, body) + public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { + try _Testing_Foundation.withUnsafeBytes(encoding: self, for: attachment, body) } } #endif diff --git a/Sources/Overlays/_Testing_Foundation/Attachments/Attachable+NSSecureCoding.swift b/Sources/Overlays/_Testing_Foundation/Attachments/Attachable+NSSecureCoding.swift index c6916ec39..c2cc28ea0 100644 --- a/Sources/Overlays/_Testing_Foundation/Attachments/Attachable+NSSecureCoding.swift +++ b/Sources/Overlays/_Testing_Foundation/Attachments/Attachable+NSSecureCoding.swift @@ -46,7 +46,7 @@ extension Attachable where Self: NSSecureCoding { /// _and_ [`NSSecureCoding`](https://developer.apple.com/documentation/foundation/nssecurecoding), /// the default implementation of this function uses the value's conformance /// to `Encodable`. - public func withUnsafeBufferPointer(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { + public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { let format = try EncodingFormat(for: attachment) var data = try NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding: true) diff --git a/Sources/Overlays/_Testing_Foundation/Attachments/Data+Attachable.swift b/Sources/Overlays/_Testing_Foundation/Attachments/Data+Attachable.swift index f931e5824..38233cd3c 100644 --- a/Sources/Overlays/_Testing_Foundation/Attachments/Data+Attachable.swift +++ b/Sources/Overlays/_Testing_Foundation/Attachments/Data+Attachable.swift @@ -14,7 +14,7 @@ public import Foundation @_spi(Experimental) extension Data: Attachable { - public func withUnsafeBufferPointer(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { + public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { try withUnsafeBytes(body) } } diff --git a/Sources/Overlays/_Testing_Foundation/Attachments/_AttachableURLContainer.swift b/Sources/Overlays/_Testing_Foundation/Attachments/_AttachableURLContainer.swift index 38f21d4d3..c7a223a51 100644 --- a/Sources/Overlays/_Testing_Foundation/Attachments/_AttachableURLContainer.swift +++ b/Sources/Overlays/_Testing_Foundation/Attachments/_AttachableURLContainer.swift @@ -36,7 +36,7 @@ extension _AttachableURLContainer: AttachableContainer { url } - public func withUnsafeBufferPointer(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { + public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { try data.withUnsafeBytes(body) } diff --git a/Sources/Testing/Attachments/Attachable.swift b/Sources/Testing/Attachments/Attachable.swift index 4a1d775a5..09a7e0b78 100644 --- a/Sources/Testing/Attachments/Attachable.swift +++ b/Sources/Testing/Attachments/Attachable.swift @@ -11,10 +11,11 @@ /// A protocol describing a type that can be attached to a test report or /// written to disk when a test is run. /// -/// To attach an attachable value to a test report or test run output, use it to -/// initialize a new instance of ``Attachment``, then call -/// ``Attachment/attach(sourceLocation:)``. An attachment can only be attached -/// once. +/// To attach an attachable value to a test, pass it to ``Attachment/record(_:named:sourceLocation:)``. +/// To further configure an attachable value before you attach it, use it to +/// initialize an instance of ``Attachment`` and set its properties before +/// passing it to ``Attachment/record(_:sourceLocation:)``. An attachable +/// value can only be attached to a test once. /// /// The testing library provides default conformances to this protocol for a /// variety of standard library types. Most user-defined types do not need to @@ -63,7 +64,7 @@ public protocol Attachable: ~Copyable { /// the buffer to contain an image in PNG format, JPEG format, etc., but it /// would not be idiomatic for the buffer to contain a textual description of /// the image. - borrowing func withUnsafeBufferPointer(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R + borrowing func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R /// Generate a preferred name for the given attachment. /// @@ -99,8 +100,8 @@ extension Attachable where Self: Collection, Element == UInt8 { count } - // We do not provide an implementation of withUnsafeBufferPointer(for:_:) here - // because there is no way in the standard library to statically detect if a + // We do not provide an implementation of withUnsafeBytes(for:_:) here because + // there is no way in the standard library to statically detect if a // collection can provide contiguous storage (_HasContiguousBytes is not API.) // If withContiguousStorageIfAvailable(_:) fails, we don't want to make a // (potentially expensive!) copy of the collection. @@ -120,28 +121,28 @@ extension Attachable where Self: StringProtocol { // developers can attach raw data when needed. @_spi(Experimental) extension Array: Attachable { - public func withUnsafeBufferPointer(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { + public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { try withUnsafeBytes(body) } } @_spi(Experimental) extension ContiguousArray: Attachable { - public func withUnsafeBufferPointer(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { + public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { try withUnsafeBytes(body) } } @_spi(Experimental) extension ArraySlice: Attachable { - public func withUnsafeBufferPointer(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { + public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { try withUnsafeBytes(body) } } @_spi(Experimental) extension String: Attachable { - public func withUnsafeBufferPointer(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { + public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { var selfCopy = self return try selfCopy.withUTF8 { utf8 in try body(UnsafeRawBufferPointer(utf8)) @@ -151,7 +152,7 @@ extension String: Attachable { @_spi(Experimental) extension Substring: Attachable { - public func withUnsafeBufferPointer(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { + public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { var selfCopy = self return try selfCopy.withUTF8 { utf8 in try body(UnsafeRawBufferPointer(utf8)) diff --git a/Sources/Testing/Attachments/AttachableContainer.swift b/Sources/Testing/Attachments/AttachableContainer.swift index aced49c0f..e4d716e9c 100644 --- a/Sources/Testing/Attachments/AttachableContainer.swift +++ b/Sources/Testing/Attachments/AttachableContainer.swift @@ -12,23 +12,19 @@ /// written to disk when a test is run and which contains another value that it /// stands in for. /// -/// To attach an attachable value to a test report or test run output, use it to -/// initialize a new instance of ``Attachment``, then call -/// ``Attachment/attach(sourceLocation:)``. An attachment can only be attached -/// once. +/// To attach an attachable value to a test, pass it to ``Attachment/record(_:named:sourceLocation:)``. +/// To further configure an attachable value before you attach it, use it to +/// initialize an instance of ``Attachment`` and set its properties before +/// passing it to ``Attachment/record(_:sourceLocation:)``. An attachable +/// value can only be attached to a test once. /// /// A type can conform to this protocol if it represents another type that /// cannot directly conform to ``Attachable``, such as a non-final class or a /// type declared in a third-party module. @_spi(Experimental) public protocol AttachableContainer: Attachable, ~Copyable { -#if hasFeature(SuppressedAssociatedTypes) - /// The type of the attachable value represented by this type. - associatedtype AttachableValue: ~Copyable -#else /// The type of the attachable value represented by this type. associatedtype AttachableValue -#endif /// The attachable value represented by this instance. var attachableValue: AttachableValue { get } diff --git a/Sources/Testing/Attachments/Attachment.swift b/Sources/Testing/Attachments/Attachment.swift index ef7ae5537..c7a4fc0c9 100644 --- a/Sources/Testing/Attachments/Attachment.swift +++ b/Sources/Testing/Attachments/Attachment.swift @@ -143,7 +143,7 @@ public struct AnyAttachable: AttachableContainer, Copyable, Sendable { attachableValue.estimatedAttachmentByteCount } - public func withUnsafeBufferPointer(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { + public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { func open(_ attachableValue: T, for attachment: borrowing Attachment) throws -> R where T: Attachable & Sendable & Copyable { let temporaryAttachment = Attachment( _attachableValue: attachableValue, @@ -151,7 +151,7 @@ public struct AnyAttachable: AttachableContainer, Copyable, Sendable { _preferredName: attachment._preferredName, sourceLocation: attachment.sourceLocation ) - return try temporaryAttachment.withUnsafeBufferPointer(body) + return try temporaryAttachment.withUnsafeBytes(body) } return try open(attachableValue, for: attachment) } @@ -220,25 +220,61 @@ extension Attachment where AttachableValue: AttachableContainer & ~Copyable { #if !SWT_NO_LAZY_ATTACHMENTS extension Attachment where AttachableValue: Sendable & Copyable { - /// Attach this instance to the current test. + /// Attach an attachment to the current test. /// /// - Parameters: + /// - attachment: The attachment to attach. /// - sourceLocation: The source location of the call to this function. /// + /// When attaching a value of a type that does not conform to both + /// [`Sendable`](https://developer.apple.com/documentation/swift/sendable) and + /// [`Copyable`](https://developer.apple.com/documentation/swift/copyable), + /// the testing library encodes it as data immediately. If the value cannot be + /// encoded and an error is thrown, that error is recorded as an issue in the + /// current test and the attachment is not written to the test report or to + /// disk. + /// /// An attachment can only be attached once. @_documentation(visibility: private) - public consuming func attach(sourceLocation: SourceLocation = #_sourceLocation) { - var attachmentCopy = Attachment(self) + public static func record(_ attachment: consuming Self, sourceLocation: SourceLocation = #_sourceLocation) { + var attachmentCopy = Attachment(attachment) attachmentCopy.sourceLocation = sourceLocation Event.post(.valueAttached(attachmentCopy)) } + + /// Attach a value to the current test. + /// + /// - Parameters: + /// - attachableValue: The value to attach. + /// - preferredName: The preferred name of the attachment when writing it to + /// a test report or to disk. If `nil`, the testing library attempts to + /// derive a reasonable filename for the attached value. + /// - sourceLocation: The source location of the call to this function. + /// + /// When attaching a value of a type that does not conform to both + /// [`Sendable`](https://developer.apple.com/documentation/swift/sendable) and + /// [`Copyable`](https://developer.apple.com/documentation/swift/copyable), + /// the testing library encodes it as data immediately. If the value cannot be + /// encoded and an error is thrown, that error is recorded as an issue in the + /// current test and the attachment is not written to the test report or to + /// disk. + /// + /// This function creates a new instance of ``Attachment`` and immediately + /// attaches it to the current test. + /// + /// An attachment can only be attached once. + @_documentation(visibility: private) + public static func record(_ attachableValue: consuming AttachableValue, named preferredName: String? = nil, sourceLocation: SourceLocation = #_sourceLocation) { + record(Self(attachableValue, named: preferredName), sourceLocation: sourceLocation) + } } #endif extension Attachment where AttachableValue: ~Copyable { - /// Attach this instance to the current test. + /// Attach an attachment to the current test. /// /// - Parameters: + /// - attachment: The attachment to attach. /// - sourceLocation: The source location of the call to this function. /// /// When attaching a value of a type that does not conform to both @@ -250,14 +286,14 @@ extension Attachment where AttachableValue: ~Copyable { /// disk. /// /// An attachment can only be attached once. - public consuming func attach(sourceLocation: SourceLocation = #_sourceLocation) { + public static func record(_ attachment: consuming Self, sourceLocation: SourceLocation = #_sourceLocation) { do { - let attachmentCopy = try withUnsafeBufferPointer { buffer in + let attachmentCopy = try attachment.withUnsafeBytes { buffer in let attachableContainer = AnyAttachable(attachableValue: Array(buffer)) return Attachment( _attachableValue: attachableContainer, - fileSystemPath: fileSystemPath, - _preferredName: preferredName, // invokes preferredName(for:basedOn:) + fileSystemPath: attachment.fileSystemPath, + _preferredName: attachment.preferredName, // invokes preferredName(for:basedOn:) sourceLocation: sourceLocation ) } @@ -267,6 +303,31 @@ extension Attachment where AttachableValue: ~Copyable { Issue(kind: .valueAttachmentFailed(error), comments: [], sourceContext: sourceContext).record() } } + + /// Attach a value to the current test. + /// + /// - Parameters: + /// - attachableValue: The value to attach. + /// - preferredName: The preferred name of the attachment when writing it to + /// a test report or to disk. If `nil`, the testing library attempts to + /// derive a reasonable filename for the attached value. + /// - sourceLocation: The source location of the call to this function. + /// + /// When attaching a value of a type that does not conform to both + /// [`Sendable`](https://developer.apple.com/documentation/swift/sendable) and + /// [`Copyable`](https://developer.apple.com/documentation/swift/copyable), + /// the testing library encodes it as data immediately. If the value cannot be + /// encoded and an error is thrown, that error is recorded as an issue in the + /// current test and the attachment is not written to the test report or to + /// disk. + /// + /// This function creates a new instance of ``Attachment`` and immediately + /// attaches it to the current test. + /// + /// An attachment can only be attached once. + public static func record(_ attachableValue: consuming AttachableValue, named preferredName: String? = nil, sourceLocation: SourceLocation = #_sourceLocation) { + record(Self(attachableValue, named: preferredName), sourceLocation: sourceLocation) + } } // MARK: - Getting the serialized form of an attachable value (generically) @@ -286,10 +347,10 @@ extension Attachment where AttachableValue: ~Copyable { /// /// The testing library uses this function when writing an attachment to a /// test report or to a file on disk. This function calls the - /// ``Attachable/withUnsafeBufferPointer(for:_:)`` function on this - /// attachment's ``attachableValue-2tnj5`` property. - @inlinable public borrowing func withUnsafeBufferPointer(_ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { - try attachableValue.withUnsafeBufferPointer(for: self, body) + /// ``Attachable/withUnsafeBytes(for:_:)`` function on this attachment's + /// ``attachableValue-2tnj5`` property. + @inlinable public borrowing func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { + try attachableValue.withUnsafeBytes(for: self, body) } } @@ -391,7 +452,7 @@ extension Attachment where AttachableValue: ~Copyable { // There should be no code path that leads to this call where the attachable // value is nil. - try withUnsafeBufferPointer { buffer in + try withUnsafeBytes { buffer in try file!.write(buffer) } diff --git a/Tests/TestingTests/AttachmentTests.swift b/Tests/TestingTests/AttachmentTests.swift index 5a36fd4b6..126633776 100644 --- a/Tests/TestingTests/AttachmentTests.swift +++ b/Tests/TestingTests/AttachmentTests.swift @@ -27,7 +27,7 @@ struct AttachmentTests { @Test func saveValue() { let attachableValue = MyAttachable(string: "") let attachment = Attachment(attachableValue, named: "AttachmentTests.saveValue.html") - attachment.attach() + Attachment.record(attachment) } @Test func description() { @@ -174,41 +174,41 @@ struct AttachmentTests { await Test { let attachment = Attachment(attachableValue, named: "loremipsum.html") - attachment.attach() + Attachment.record(attachment) }.run(configuration: configuration) } } #endif @Test func attachValue() async { - await confirmation("Attachment detected") { valueAttached in + await confirmation("Attachment detected", expectedCount: 2) { valueAttached in var configuration = Configuration() configuration.eventHandler = { event, _ in guard case let .valueAttached(attachment) = event.kind else { return } - #expect(attachment.preferredName == "loremipsum") #expect(attachment.sourceLocation.fileID == #fileID) valueAttached() } await Test { - let attachableValue = MyAttachable(string: "") - Attachment(attachableValue, named: "loremipsum").attach() + let attachableValue1 = MyAttachable(string: "") + Attachment.record(attachableValue1) + let attachableValue2 = MyAttachable(string: "") + Attachment.record(Attachment(attachableValue2)) }.run(configuration: configuration) } } @Test func attachSendableValue() async { - await confirmation("Attachment detected") { valueAttached in + await confirmation("Attachment detected", expectedCount: 2) { valueAttached in var configuration = Configuration() configuration.eventHandler = { event, _ in guard case let .valueAttached(attachment) = event.kind else { return } - #expect(attachment.preferredName == "loremipsum") #expect(attachment.attachableValue is MySendableAttachable) #expect(attachment.sourceLocation.fileID == #fileID) valueAttached() @@ -216,7 +216,8 @@ struct AttachmentTests { await Test { let attachableValue = MySendableAttachable(string: "") - Attachment(attachableValue, named: "loremipsum").attach() + Attachment.record(attachableValue) + Attachment.record(Attachment(attachableValue)) }.run(configuration: configuration) } } @@ -240,7 +241,7 @@ struct AttachmentTests { await Test { var attachableValue = MyAttachable(string: "") attachableValue.errorToThrow = MyError() - Attachment(attachableValue, named: "loremipsum").attach() + Attachment.record(Attachment(attachableValue, named: "loremipsum")) }.run(configuration: configuration) } } @@ -267,7 +268,7 @@ struct AttachmentTests { #expect(attachment.preferredName == temporaryFileName) #expect(throws: Never.self) { - try attachment.withUnsafeBufferPointer { buffer in + try attachment.withUnsafeBytes { buffer in #expect(buffer.count == data.count) } } @@ -276,7 +277,7 @@ struct AttachmentTests { await Test { let attachment = try await Attachment(contentsOf: temporaryURL) - attachment.attach() + Attachment.record(attachment) }.run(configuration: configuration) } } @@ -299,7 +300,7 @@ struct AttachmentTests { } #expect(attachment.preferredName == "\(temporaryDirectoryName).zip") - try! attachment.withUnsafeBufferPointer { buffer in + try! attachment.withUnsafeBytes { buffer in #expect(buffer.count > 32) #expect(buffer[0] == UInt8(ascii: "P")) #expect(buffer[1] == UInt8(ascii: "K")) @@ -312,7 +313,7 @@ struct AttachmentTests { await Test { let attachment = try await Attachment(contentsOf: temporaryURL) - attachment.attach() + Attachment.record(attachment) }.run(configuration: configuration) } } @@ -393,7 +394,7 @@ struct AttachmentTests { } func open(_ attachment: borrowing Attachment) throws where T: Attachable { - try attachment.attachableValue.withUnsafeBufferPointer(for: attachment) { bytes in + try attachment.attachableValue.withUnsafeBytes(for: attachment) { bytes in #expect(bytes.first == args.firstCharacter.asciiValue) let decodedStringValue = try args.decode(Data(bytes)) #expect(decodedStringValue == "stringly speaking") @@ -416,7 +417,7 @@ struct AttachmentTests { let attachableValue = MySecureCodingAttachable(string: "stringly speaking") let attachment = Attachment(attachableValue, named: "loremipsum.json") #expect(throws: CocoaError.self) { - try attachment.attachableValue.withUnsafeBufferPointer(for: attachment) { _ in } + try attachment.attachableValue.withUnsafeBytes(for: attachment) { _ in } } } @@ -425,7 +426,7 @@ struct AttachmentTests { let attachableValue = MySecureCodingAttachable(string: "stringly speaking") let attachment = Attachment(attachableValue, named: "loremipsum.gif") #expect(throws: CocoaError.self) { - try attachment.attachableValue.withUnsafeBufferPointer(for: attachment) { _ in } + try attachment.attachableValue.withUnsafeBytes(for: attachment) { _ in } } } #endif @@ -437,7 +438,7 @@ extension AttachmentTests { func test(_ value: some Attachable) throws { #expect(value.estimatedAttachmentByteCount == 6) let attachment = Attachment(value) - try attachment.withUnsafeBufferPointer { buffer in + try attachment.withUnsafeBytes { buffer in #expect(buffer.elementsEqual("abc123".utf8)) #expect(buffer.count == 6) } @@ -530,10 +531,10 @@ extension AttachmentTests { let image = try Self.cgImage.get() let attachment = Attachment(image, named: "diamond") #expect(attachment.attachableValue === image) - try attachment.attachableValue.withUnsafeBufferPointer(for: attachment) { buffer in + try attachment.attachableValue.withUnsafeBytes(for: attachment) { buffer in #expect(buffer.count > 32) } - attachment.attach() + Attachment.record(attachment) } @available(_uttypesAPI, *) @@ -542,7 +543,7 @@ extension AttachmentTests { let image = try Self.cgImage.get() let attachment = Attachment(image, named: "diamond", as: type, encodingQuality: quality) #expect(attachment.attachableValue === image) - try attachment.attachableValue.withUnsafeBufferPointer(for: attachment) { buffer in + try attachment.attachableValue.withUnsafeBytes(for: attachment) { buffer in #expect(buffer.count > 32) } if let ext = type?.preferredFilenameExtension { @@ -555,7 +556,7 @@ extension AttachmentTests { @Test func cannotAttachCGImageWithNonImageType() async { await #expect(exitsWith: .failure) { let attachment = Attachment(try Self.cgImage.get(), named: "diamond", as: .mp3) - try attachment.attachableValue.withUnsafeBufferPointer(for: attachment) { _ in } + try attachment.attachableValue.withUnsafeBytes(for: attachment) { _ in } } } #endif @@ -569,7 +570,7 @@ struct MyAttachable: Attachable, ~Copyable { var string: String var errorToThrow: (any Error)? - func withUnsafeBufferPointer(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { + func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { if let errorToThrow { throw errorToThrow } @@ -587,7 +588,7 @@ extension MyAttachable: Sendable {} struct MySendableAttachable: Attachable, Sendable { var string: String - func withUnsafeBufferPointer(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { + func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { #expect(attachment.attachableValue.string == string) var string = string return try string.withUTF8 { buffer in @@ -599,7 +600,7 @@ struct MySendableAttachable: Attachable, Sendable { struct MySendableAttachableWithDefaultByteCount: Attachable, Sendable { var string: String - func withUnsafeBufferPointer(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { + func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { var string = string return try string.withUTF8 { buffer in try body(.init(buffer)) diff --git a/cmake/modules/shared/CompilerSettings.cmake b/cmake/modules/shared/CompilerSettings.cmake index f526caae3..0da4216c5 100644 --- a/cmake/modules/shared/CompilerSettings.cmake +++ b/cmake/modules/shared/CompilerSettings.cmake @@ -13,8 +13,7 @@ add_compile_options( add_compile_options( "SHELL:$<$:-Xfrontend -require-explicit-sendable>") add_compile_options( - "SHELL:$<$:-Xfrontend -enable-experimental-feature -Xfrontend AccessLevelOnImport>" - "SHELL:$<$:-Xfrontend -enable-experimental-feature -Xfrontend SuppressedAssociatedTypes>") + "SHELL:$<$:-Xfrontend -enable-experimental-feature -Xfrontend AccessLevelOnImport>") add_compile_options( "SHELL:$<$:-Xfrontend -enable-upcoming-feature -Xfrontend ExistentialAny>" "SHELL:$<$:-Xfrontend -enable-upcoming-feature -Xfrontend InternalImportsByDefault>"