Skip to content

Commit f4abd7a

Browse files
authored
Update Comment to use CustomTestStringConvertible during string interpolation. (#936)
This PR ensures that `Comment`, when constructed from a string literal with interpolations, stringifies interpolated values using `String.init(descriptionForTest:)` rather than the default behaviour (i.e. `String.init(description:)`.) For example: ```swift enum E: CustomTestStringConvertible { case a case b case c var testDescription: String { switch self { case .a: "Once I was the King of Spain" case .b: "Now I eat humble pie" case .c: "Now I vacuum the turf at SkyDome™" } } } #expect(1 == 2, "\(E.a) / \(E.b) / \(E.a) / \(E.c)") ``` Before: > 🛑 Expectation failed: 1 == 2 - .a / .b / .a / .c After: > 🛑 Expectation failed: 1 == 2 - Once I was the King of Spain / Now I eat > humble pie / Once I was the King of Spain / Now I vacuum the turf at SkyDome™ ### 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 10ab127 commit f4abd7a

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

Sources/Testing/Traits/Comment.swift

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ public struct Comment: RawRepresentable, Sendable {
7777
}
7878
}
7979

80-
// MARK: - ExpressibleByStringLiteral, ExpressibleByStringInterpolation, CustomStringConvertible
80+
// MARK: - ExpressibleByStringLiteral, CustomStringConvertible
8181

82-
extension Comment: ExpressibleByStringLiteral, ExpressibleByStringInterpolation, CustomStringConvertible {
82+
extension Comment: ExpressibleByStringLiteral, CustomStringConvertible {
8383
public init(stringLiteral: String) {
8484
self.init(rawValue: stringLiteral, kind: .stringLiteral)
8585
}
@@ -89,6 +89,45 @@ extension Comment: ExpressibleByStringLiteral, ExpressibleByStringInterpolation,
8989
}
9090
}
9191

92+
// MARK: - ExpressibleByStringInterpolation
93+
94+
extension Comment: ExpressibleByStringInterpolation {
95+
public init(stringInterpolation: StringInterpolation) {
96+
self.init(rawValue: stringInterpolation.rawValue)
97+
}
98+
99+
/// The string interpolation handler type for ``Comment``.
100+
@_documentation(visibility: private)
101+
public struct StringInterpolation: StringInterpolationProtocol, Sendable {
102+
/// Storage for the string constructed by this instance.
103+
///
104+
/// `DefaultStringInterpolation` in the Swift standard library also simply
105+
/// accumulates its result in a string.
106+
@usableFromInline var rawValue: String = ""
107+
108+
public init(literalCapacity: Int, interpolationCount: Int) {}
109+
110+
@inlinable public mutating func appendLiteral(_ literal: String) {
111+
rawValue += literal
112+
}
113+
114+
@inlinable public mutating func appendInterpolation(_ value: (some Any)?) {
115+
rawValue += String(describingForTest: value)
116+
}
117+
118+
@inlinable public mutating func appendInterpolation(_ value: (some StringProtocol)?) {
119+
// Special-case strings to not include the quotation marks added by
120+
// CustomTestStringConvertible (which in the context of interpolation
121+
// probably violate the Principle of Least Surprise).
122+
if let value {
123+
rawValue += value
124+
} else {
125+
rawValue += String(describingForTest: value)
126+
}
127+
}
128+
}
129+
}
130+
92131
// MARK: - Equatable, Hashable, Comparable
93132

94133
extension Comment: Equatable, Hashable {}

Tests/TestingTests/Traits/CommentTests.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,31 @@ struct CommentTests {
5757
func explicitlyNilComment() {
5858
#expect(true as Bool, nil as Comment?)
5959
}
60+
61+
@Test("String interpolation")
62+
func stringInterpolation() {
63+
let value1: Int = 123
64+
let value2: Int? = nil
65+
let value3: Any.Type = Int.self
66+
let comment: Comment = "abc\(value1)def\(value2)ghi\(value3)"
67+
#expect(comment.rawValue == "abc123defnilghiInt")
68+
}
69+
70+
@Test("String interpolation with a custom type")
71+
func stringInterpolationWithCustomType() {
72+
struct S: CustomStringConvertible, CustomTestStringConvertible {
73+
var description: String {
74+
"wrong!"
75+
}
76+
77+
var testDescription: String {
78+
"right!"
79+
}
80+
}
81+
82+
let comment: Comment = "abc\(S())def\(S() as S?)ghi\(S.self)jkl\("string")"
83+
#expect(comment.rawValue == "abcright!defright!ghiSjklstring")
84+
}
6085
}
6186

6287
// MARK: - Fixtures

0 commit comments

Comments
 (0)