1
1
import Foundation
2
2
3
3
#if canImport(SwiftSyntax509)
4
- import SnapshotTesting
4
+ @ _spi ( Internals ) import SnapshotTesting
5
5
import SwiftParser
6
6
import SwiftSyntax
7
7
import SwiftSyntaxBuilder
@@ -35,7 +35,7 @@ import Foundation
35
35
of value: @autoclosure ( ) throws -> Value ? ,
36
36
as snapshotting: Snapshotting < Value , String > ,
37
37
message: @autoclosure ( ) -> String = " " ,
38
- record isRecording: Bool = isRecording ,
38
+ record isRecording: Bool ? = nil ,
39
39
timeout: TimeInterval = 5 ,
40
40
syntaxDescriptor: InlineSnapshotSyntaxDescriptor = InlineSnapshotSyntaxDescriptor ( ) ,
41
41
matches expected: ( ( ) -> String ) ? = nil ,
@@ -44,95 +44,116 @@ import Foundation
44
44
line: UInt = #line,
45
45
column: UInt = #column
46
46
) {
47
- let _: Void = installTestObserver
48
- do {
49
- var actual : String ?
50
- let expectation = XCTestExpectation ( )
51
- if let value = try value ( ) {
52
- snapshotting. snapshot ( value) . run {
53
- actual = $0
54
- expectation. fulfill ( )
47
+ let record =
48
+ ( isRecording == true ? . all : isRecording == false ? . missing : nil )
49
+ ?? SnapshotTestingConfiguration . current? . record
50
+ ?? _record
51
+ withSnapshotTesting ( record: record) {
52
+ let _: Void = installTestObserver
53
+ do {
54
+ var actual : String ?
55
+ let expectation = XCTestExpectation ( )
56
+ if let value = try value ( ) {
57
+ snapshotting. snapshot ( value) . run {
58
+ actual = $0
59
+ expectation. fulfill ( )
60
+ }
61
+ switch XCTWaiter . wait ( for: [ expectation] , timeout: timeout) {
62
+ case . completed:
63
+ break
64
+ case . timedOut:
65
+ recordIssue (
66
+ """
67
+ Exceeded timeout of \( timeout) seconds waiting for snapshot.
68
+
69
+ This can happen when an asynchronously loaded value (like a network response) has not \
70
+ loaded. If a timeout is unavoidable, consider setting the " timeout " parameter of
71
+ " assertInlineSnapshot " to a higher value.
72
+ """ ,
73
+ file: file,
74
+ line: line
75
+ )
76
+ return
77
+ case . incorrectOrder, . interrupted, . invertedFulfillment:
78
+ recordIssue ( " Couldn't snapshot value " , file: file, line: line)
79
+ return
80
+ @unknown default :
81
+ recordIssue ( " Couldn't snapshot value " , file: file, line: line)
82
+ return
83
+ }
55
84
}
56
- switch XCTWaiter . wait ( for: [ expectation] , timeout: timeout) {
57
- case . completed:
58
- break
59
- case . timedOut:
60
- XCTFail (
85
+ let expected = expected ? ( )
86
+ guard
87
+ record != . all,
88
+ record != . missing || expected != nil
89
+ else {
90
+ // NB: Write snapshot state before calling `XCTFail` in case `continueAfterFailure = false`
91
+ inlineSnapshotState [ File ( path: file) , default: [ ] ] . append (
92
+ InlineSnapshot (
93
+ expected: expected,
94
+ actual: actual,
95
+ wasRecording: record == . all,
96
+ syntaxDescriptor: syntaxDescriptor,
97
+ function: " \( function) " ,
98
+ line: line,
99
+ column: column
100
+ )
101
+ )
102
+
103
+ var failure : String
104
+ if syntaxDescriptor. trailingClosureLabel
105
+ == InlineSnapshotSyntaxDescriptor . defaultTrailingClosureLabel
106
+ {
107
+ failure = " Automatically recorded a new snapshot. "
108
+ } else {
109
+ failure = """
110
+ Automatically recorded a new snapshot for " \( syntaxDescriptor. trailingClosureLabel) " .
111
+ """
112
+ }
113
+ if let difference = snapshotting. diffing. diff ( expected ?? " " , actual ?? " " ) ? . 0 {
114
+ failure += " Difference: … \n \n \( difference. indenting ( by: 2 ) ) "
115
+ }
116
+ recordIssue (
61
117
"""
62
- Exceeded timeout of \( timeout ) seconds waiting for snapshot.
118
+ \( failure )
63
119
64
- This can happen when an asynchronously loaded value (like a network response) has not \
65
- loaded. If a timeout is unavoidable, consider setting the " timeout " parameter of
66
- " assertInlineSnapshot " to a higher value.
120
+ Re-run " \( function) " to assert against the newly-recorded snapshot.
67
121
""" ,
68
122
file: file,
69
123
line: line
70
124
)
71
125
return
72
- case . incorrectOrder, . interrupted, . invertedFulfillment:
73
- XCTFail ( " Couldn't snapshot value " , file: file, line: line)
74
- return
75
- @unknown default :
76
- XCTFail ( " Couldn't snapshot value " , file: file, line: line)
77
- return
78
126
}
79
- }
80
- let expected = expected ? ( )
81
- guard !isRecording, let expected
82
- else {
83
- // NB: Write snapshot state before calling `XCTFail` in case `continueAfterFailure = false`
84
- inlineSnapshotState [ File ( path: file) , default: [ ] ] . append (
85
- InlineSnapshot (
86
- expected: expected,
87
- actual: actual,
88
- wasRecording: isRecording,
89
- syntaxDescriptor: syntaxDescriptor,
90
- function: " \( function) " ,
91
- line: line,
92
- column: column
93
- )
94
- )
95
127
96
- var failure : String
97
- if syntaxDescriptor. trailingClosureLabel
98
- == InlineSnapshotSyntaxDescriptor . defaultTrailingClosureLabel
99
- {
100
- failure = " Automatically recorded a new snapshot. "
101
- } else {
102
- failure = """
103
- Automatically recorded a new snapshot for " \( syntaxDescriptor. trailingClosureLabel) " .
128
+ guard let expected
129
+ else {
130
+ recordIssue (
104
131
"""
132
+ No expected value to assert against.
133
+ """ ,
134
+ file: file,
135
+ line: line
136
+ )
137
+ return
105
138
}
106
- if let difference = snapshotting. diffing. diff ( expected ?? " " , actual ?? " " ) ? . 0 {
107
- failure += " Difference: … \n \n \( difference. indenting ( by: 2 ) ) "
108
- }
109
- XCTFail (
139
+ guard
140
+ let difference = snapshotting. diffing. diff ( expected, actual ?? " " ) ? . 0
141
+ else { return }
142
+
143
+ let message = message ( )
144
+ syntaxDescriptor. fail (
110
145
"""
111
- \( failure )
146
+ \( message . isEmpty ? " Snapshot did not match. Difference: … " : message )
112
147
113
- Re-run " \( function ) " to assert against the newly-recorded snapshot.
148
+ \( difference . indenting ( by : 2 ) )
114
149
""" ,
115
150
file: file,
116
- line: line
151
+ line: line,
152
+ column: column
117
153
)
118
- return
154
+ } catch {
155
+ recordIssue ( " Threw error: \( error) " , file: file, line: line)
119
156
}
120
- guard let difference = snapshotting. diffing. diff ( expected, actual ?? " " ) ? . 0
121
- else { return }
122
-
123
- let message = message ( )
124
- syntaxDescriptor. fail (
125
- """
126
- \( message. isEmpty ? " Snapshot did not match. Difference: … " : message)
127
-
128
- \( difference. indenting ( by: 2 ) )
129
- """ ,
130
- file: file,
131
- line: line,
132
- column: column
133
- )
134
- } catch {
135
- XCTFail ( " Threw error: \( error) " , file: file, line: line)
136
157
}
137
158
}
138
159
#else
@@ -197,6 +218,8 @@ public struct InlineSnapshotSyntaxDescriptor: Hashable {
197
218
/// Initializes an inline snapshot syntax descriptor.
198
219
///
199
220
/// - Parameters:
221
+ /// - deprecatedTrailingClosureLabels: An array of deprecated labels to consider for the inline
222
+ /// snapshot.
200
223
/// - trailingClosureLabel: The label of the trailing closure that returns the inline snapshot.
201
224
/// - trailingClosureOffset: The offset of the trailing closure that returns the inline
202
225
/// snapshot, relative to the first trailing closure.
@@ -242,7 +265,7 @@ public struct InlineSnapshotSyntaxDescriptor: Hashable {
242
265
visitor. walk ( testSource. sourceFile)
243
266
trailingClosureLine = visitor. trailingClosureLine
244
267
}
245
- XCTFail (
268
+ recordIssue (
246
269
message ( ) ,
247
270
file: file,
248
271
line: trailingClosureLine. map ( UInt . init) ?? line
@@ -386,7 +409,7 @@ public struct InlineSnapshotSyntaxDescriptor: Hashable {
386
409
) {
387
410
self . file = file
388
411
self . line = snapshots. first? . line
389
- self . wasRecording = snapshots. first? . wasRecording ?? isRecording
412
+ self . wasRecording = snapshots. first? . wasRecording ?? false
390
413
self . indent = String (
391
414
sourceLocationConverter. sourceLines
392
415
. first { $0. first? . isWhitespace == true && $0. contains { !$0. isWhitespace } } ?
0 commit comments