Skip to content

Make Test.Attachment generic. #814

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
573a5c1
Make `Test.Attachment` generic.
grynspan Nov 6, 2024
a40bc31
Add accessors through withUnsafeBufferPointer since the type-erased a…
grynspan Nov 8, 2024
7df01e9
Work around rdar://137614425 (again)
grynspan Nov 8, 2024
2a10020
Work around a compiler crash (again, yes)
grynspan Nov 8, 2024
e71c2ad
Work around the compiler crash a second time
grynspan Nov 8, 2024
5ef993d
Use a dedicated type to represent any attachable value rather than an…
grynspan Nov 10, 2024
98c96a1
Nest AnyAttachable
grynspan Nov 10, 2024
e714477
Add AttachableContainer protocol for abstracting away box/adapter typ…
grynspan Nov 10, 2024
ffbe17a
Update comments, make AttachableContainer always Copyable & Sendable
grynspan Nov 10, 2024
33bcb03
Actually no, make Test.AttachableContainer optionally copyable/sendab…
grynspan Nov 10, 2024
6c90061
Enable SuppressedAssociatedTypes feature
grynspan Nov 10, 2024
1e06f22
Move AttachableContainer to its own file
grynspan Nov 10, 2024
77e5be4
Delete incorrect comment
grynspan Nov 11, 2024
ae8fc54
Hoist source location up to Event
grynspan Nov 11, 2024
ec9542d
Post issue events to the current configuration
grynspan Nov 11, 2024
0967acc
Use the proxied withUnsafeBufferPointer call more
grynspan Nov 11, 2024
064222d
Update doc comment for updated .valueAttached case
grynspan Nov 11, 2024
8660c4d
Fix documentation links on Event.sourceLocation
grynspan Nov 11, 2024
6bb2335
Correct comment
grynspan Nov 11, 2024
da4ea7c
Add SuppressedAssociatedTypes to CMake; remove buffer pointer conform…
grynspan Nov 11, 2024
839766e
Remove generic parameter on ABIv0 structure
grynspan Nov 11, 2024
5ed7039
Replace tabs with spaces
grynspan Nov 11, 2024
b9b9436
Move sourceLocation back to Attachment
grynspan Nov 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Documentation/Proposals/0005-ranged-confirmations.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ A new overload of `confirmation()` is added:
/// - comment: An optional comment to apply to any issues generated by this
/// function.
/// - expectedCount: A range of integers indicating the number of times the
/// expected event should occur when `body` is invoked.
/// expected event should occur when `body` is invoked.
/// - isolation: The actor to which `body` is isolated, if any.
/// - sourceLocation: The source location to which any recorded issues should
/// be attributed.
Expand Down Expand Up @@ -93,7 +93,7 @@ A new overload of `confirmation()` is added:
/// let minBuns = 5
/// let maxBuns = 10
/// await confirmation(
/// "Baked between \(minBuns) and \(maxBuns) buns",
/// "Baked between \(minBuns) and \(maxBuns) buns",
/// expectedCount: minBuns ... maxBuns
/// ) { bunBaked in
/// foodTruck.eventHandler = { event in
Expand Down
1 change: 1 addition & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ extension Array where Element == PackageDescription.SwiftSetting {
availabilityMacroSettings + [
.unsafeFlags(["-require-explicit-sendable"]),
.enableUpcomingFeature("ExistentialAny"),
.enableExperimentalFeature("SuppressedAssociatedTypes"),

.enableExperimentalFeature("AccessLevelOnImport"),
.enableUpcomingFeature("InternalImportsByDefault"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ extension ABIv0 {
/// The path where the attachment was written.
var path: String?

init(encoding attachment: borrowing Test.Attachment, in eventContext: borrowing Event.Context) {
init(encoding attachment: borrowing Test.Attachment<Test.AnyAttachable>, in eventContext: borrowing Event.Context) {
path = attachment.fileSystemPath
}
}
Expand Down
48 changes: 12 additions & 36 deletions Sources/Testing/Attachments/Test.Attachable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,18 @@ extension Test {
///
/// To attach an attachable value to a test report or test run output, use it
/// to initialize a new instance of ``Test/Attachment``, then call
/// ``Test/Attachment/attach()``. An attachment can only be attached once.
/// ``Test/Attachment/attach(sourceLocation:)``. An attachment can only be
/// attached 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
/// conform to this protocol.
///
/// A type should conform to this protocol if it can be represented as a
/// sequence of bytes that would be diagnostically useful if a test fails.
/// sequence of bytes that would be diagnostically useful if a test fails. If
/// a type cannot conform directly to this protocol (such as a non-final class
/// or a type declared in a third-party module), you can create a container
/// type that conforms to ``Test/AttachableContainer`` to act as a proxy.
public protocol Attachable: ~Copyable {
/// An estimate of the number of bytes of memory needed to store this value
/// as an attachment.
Expand Down Expand Up @@ -61,7 +65,7 @@ extension Test {
/// 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<R>(for attachment: borrowing Test.Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R
borrowing func withUnsafeBufferPointer<R>(for attachment: borrowing Test.Attachment<Self>, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R
}
}

Expand Down Expand Up @@ -103,56 +107,28 @@ extension Test.Attachable where Self: StringProtocol {
// developers can attach raw data when needed.
@_spi(Experimental)
extension Array<UInt8>: Test.Attachable {
public func withUnsafeBufferPointer<R>(for attachment: borrowing Test.Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
public func withUnsafeBufferPointer<R>(for attachment: borrowing Test.Attachment<Self>, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
try withUnsafeBytes(body)
}
}

@_spi(Experimental)
extension ContiguousArray<UInt8>: Test.Attachable {
public func withUnsafeBufferPointer<R>(for attachment: borrowing Test.Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
public func withUnsafeBufferPointer<R>(for attachment: borrowing Test.Attachment<Self>, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
try withUnsafeBytes(body)
}
}

@_spi(Experimental)
extension ArraySlice<UInt8>: Test.Attachable {
public func withUnsafeBufferPointer<R>(for attachment: borrowing Test.Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
public func withUnsafeBufferPointer<R>(for attachment: borrowing Test.Attachment<Self>, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
try withUnsafeBytes(body)
}
}

@_spi(Experimental)
extension UnsafeBufferPointer<UInt8>: Test.Attachable {
public func withUnsafeBufferPointer<R>(for attachment: borrowing Test.Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
try body(.init(self))
}
}

@_spi(Experimental)
extension UnsafeMutableBufferPointer<UInt8>: Test.Attachable {
public func withUnsafeBufferPointer<R>(for attachment: borrowing Test.Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
try body(.init(self))
}
}

@_spi(Experimental)
extension UnsafeRawBufferPointer: Test.Attachable {
public func withUnsafeBufferPointer<R>(for attachment: borrowing Test.Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
try body(self)
}
}

@_spi(Experimental)
extension UnsafeMutableRawBufferPointer: Test.Attachable {
public func withUnsafeBufferPointer<R>(for attachment: borrowing Test.Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
try body(.init(self))
}
}

@_spi(Experimental)
extension String: Test.Attachable {
public func withUnsafeBufferPointer<R>(for attachment: borrowing Test.Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
public func withUnsafeBufferPointer<R>(for attachment: borrowing Test.Attachment<Self>, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
var selfCopy = self
return try selfCopy.withUTF8 { utf8 in
try body(UnsafeRawBufferPointer(utf8))
Expand All @@ -162,7 +138,7 @@ extension String: Test.Attachable {

@_spi(Experimental)
extension Substring: Test.Attachable {
public func withUnsafeBufferPointer<R>(for attachment: borrowing Test.Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
public func withUnsafeBufferPointer<R>(for attachment: borrowing Test.Attachment<Self>, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R {
var selfCopy = self
return try selfCopy.withUTF8 { utf8 in
try body(UnsafeRawBufferPointer(utf8))
Expand Down
37 changes: 37 additions & 0 deletions Sources/Testing/Attachments/Test.AttachableContainer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2024 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
//

@_spi(Experimental)
extension Test {
/// A protocol describing a type that can be attached to a test report or
/// 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 ``Test/Attachment``, then call
/// ``Test/Attachment/attach(sourceLocation:)``. An attachment can only be
/// attached once.
///
/// A type can conform to this protocol if it represents another type that
/// cannot directly conform to ``Test/Attachable``, such as a non-final class
/// or a type declared in a third-party module.
public protocol AttachableContainer<AttachableValue>: 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 }
}
}
Loading