Skip to content

Commit 5e54f49

Browse files
Improve MacroTesting Documentation and Add Swift Testing Integration (pointfreeco#35)
Co-authored-by: Stephen Celis <[email protected]>
1 parent 1036b14 commit 5e54f49

File tree

7 files changed

+96
-41
lines changed

7 files changed

+96
-41
lines changed

README.md

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ You can even have the library automatically re-record the macro expansion direct
8282
file by providing the `record` argument to `assertMacro`:
8383
8484
```swift
85-
assertMacro(["stringify": StringifyMacro.self], record: true) {
85+
assertMacro(["stringify": StringifyMacro.self], record: .all) {
8686
"""
8787
#stringify(a + b)
8888
"""
@@ -126,13 +126,13 @@ class StringifyMacroTests: XCTestCase {
126126
}
127127
```
128128

129-
You can pass the `isRecording` parameter to `withMacroTesting` to re-record every assertion in the
129+
You can pass the `record` parameter to `withMacroTesting` to re-record every assertion in the
130130
test case (or suite, if you're using your own custom base test case class):
131131

132132
```swift
133133
override func invokeTest() {
134134
withMacroTesting(
135-
isRecording: true
135+
record: .all
136136
) {
137137
super.invokeTest()
138138
}
@@ -187,6 +187,41 @@ func testNonAsyncFunctionDiagnostic() {
187187
}
188188
```
189189

190+
## Integration with Swift Testing
191+
192+
If you are using Swift's built-in Testing framework, this library also supports it. Instead of relying solely
193+
on XCTest, you can configure your tests using the `Trait` system provided by `swift-testing`. For example:
194+
195+
```swift
196+
import Testing
197+
import MacroTesting
198+
199+
@Suite(
200+
.macros(
201+
record: .missing // Record only missing snapshots
202+
macros: ["stringify": StringifyMacro.self],
203+
)
204+
)
205+
struct StringifyMacroSwiftTestingTests {
206+
@Test
207+
func testStringify() {
208+
assertMacro {
209+
"""
210+
#stringify(a + b)
211+
"""
212+
} expansion: {
213+
"""
214+
(a + b, "a + b")
215+
"""
216+
}
217+
}
218+
}
219+
```
220+
221+
Additionally, the `record` parameter in `macros` can be used to control the recording behavior for all
222+
tests in the suite. This value can also be configured using the `SNAPSHOT_TESTING_RECORD` environment
223+
variable to dynamically adjust recording behavior based on your CI or local environment.
224+
190225
## Documentation
191226

192227
The latest documentation for this library is available [here][macro-testing-docs].

Sources/MacroTesting/AssertMacro.swift

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ import XCTest
6969
/// }
7070
/// ```
7171
///
72-
/// > Tip: Use ``withMacroTesting(indentationWidth:isRecording:macros:operation:)-5id9j`` in your
72+
/// > Tip: Use ``withMacroTesting(indentationWidth:record:macros:operation:)-7cm1s`` in your
7373
/// > test case's `invokeTest` to avoid the repetitive work of passing the macro mapping to every
7474
/// > `assertMacro`:
7575
/// >
@@ -96,17 +96,19 @@ import XCTest
9696
///
9797
/// - Parameters:
9898
/// - macros: The macros to expand in the original source string. Required, either implicitly via
99-
/// ``withMacroTesting(indentationWidth:isRecording:macros:operation:)-5id9j``, or explicitly
99+
/// ``withMacroTesting(indentationWidth:record:macros:operation:)-7cm1s``, or explicitly
100100
/// via this parameter.
101101
/// - indentationWidth: The `Trivia` for setting indentation during macro expansion
102102
/// (e.g., `.spaces(2)`). Defaults to the original source's indentation if unspecified. If the
103103
/// original source lacks indentation, it defaults to `.spaces(4)`.
104-
/// - isRecording: Always records new snapshots when enabled.
104+
/// - record: The recording strategy to use for the macro expansion. If not provided, it defaults to the current
105+
/// configuration, which can be set using the `SNAPSHOT_TESTING_RECORD` environment variable
105106
/// - originalSource: A string of Swift source code.
106107
/// - diagnosedSource: Swift source code annotated with expected diagnostics.
107108
/// - fixedSource: Swift source code with expected fix-its applied.
108109
/// - expandedSource: Expected Swift source string with macros expanded.
109-
/// - file: The file where the assertion occurs. The default is the filename of the test case
110+
/// - fileID: The file ID where the assertion occurs.
111+
/// - filePath: The file where the assertion occurs. The default is the filename of the test case
110112
/// where you call this function.
111113
/// - function: The function where the assertion occurs. The default is the name of the test
112114
/// method where you call this function.
@@ -480,22 +482,24 @@ extension BasicMacroExpansionContext {
480482

481483
/// Asserts that a given Swift source string matches an expected string with all macros expanded.
482484
///
483-
/// See ``assertMacro(_:indentationWidth:record:of:diagnostics:fixes:expansion:file:function:line:column:)-pkfi``
485+
/// See ``assertMacro(_:indentationWidth:record:of:diagnostics:fixes:expansion:fileID:file:function:line:column:)-90l38``
484486
/// for more details.
485487
///
486488
/// - Parameters:
487489
/// - macros: The macros to expand in the original source string. Required, either implicitly via
488-
/// ``withMacroTesting(indentationWidth:isRecording:macros:operation:)-5id9j``, or explicitly
490+
/// ``withMacroTesting(indentationWidth:record:macros:operation:)-7cm1s``, or explicitly
489491
/// via this parameter.
490492
/// - indentationWidth: The `Trivia` for setting indentation during macro expansion
491493
/// (e.g., `.spaces(2)`). Defaults to the original source's indentation if unspecified. If the
492494
/// original source lacks indentation, it defaults to `.spaces(4)`.
493-
/// - isRecording: Always records new snapshots when enabled.
495+
/// - record: The recording strategy to use. If not provided, it defaults to the current
496+
/// configuration, which can be set using the `SNAPSHOT_TESTING_RECORD` environment variable.
494497
/// - originalSource: A string of Swift source code.
495498
/// - diagnosedSource: Swift source code annotated with expected diagnostics.
496499
/// - fixedSource: Swift source code with expected fix-its applied.
497500
/// - expandedSource: Expected Swift source string with macros expanded.
498-
/// - file: The file where the assertion occurs. The default is the filename of the test case
501+
/// - fileID: The file ID where the assertion occurs.
502+
/// - filePath: The file where the assertion occurs. The default is the filename of the test case
499503
/// where you call this function.
500504
/// - function: The function where the assertion occurs. The default is the name of the test
501505
/// method where you call this function.
@@ -557,7 +561,7 @@ public func assertMacro(
557561
/// ```swift
558562
/// class StringifyTests: XCTestCase {
559563
/// override func invokeTest() {
560-
/// withMacroTesting(isRecording: true, macros: [StringifyMacro.self]) {
564+
/// withMacroTesting(record: .all, macros: [StringifyMacro.self]) {
561565
/// super.invokeTest()
562566
/// }
563567
/// }
@@ -568,7 +572,8 @@ public func assertMacro(
568572
/// - indentationWidth: The `Trivia` for setting indentation during macro expansion
569573
/// (e.g., `.spaces(2)`). Defaults to the original source's indentation if unspecified. If the
570574
/// original source lacks indentation, it defaults to `.spaces(4)`.
571-
/// - isRecording: Determines if a new macro expansion will be recorded.
575+
/// - record: The recording strategy to use for the macro expansion. If not provided, it defaults to the current
576+
/// configuration, which can be set using the `SNAPSHOT_TESTING_RECORD` environment variable.
572577
/// - macros: Specifies the macros to be expanded in the input Swift source string.
573578
/// - operation: The operation to run with the configuration updated.
574579
public func withMacroTesting<R>(
@@ -589,14 +594,15 @@ public func withMacroTesting<R>(
589594

590595
/// Customizes `assertMacro` for the duration of an operation.
591596
///
592-
/// See ``withMacroTesting(indentationWidth:isRecording:macros:operation:)-5id9j`` for
597+
/// See ``withMacroTesting(indentationWidth:record:macros:operation:)-7cm1s`` for
593598
/// more details.
594599
///
595600
/// - Parameters:
596601
/// - indentationWidth: The `Trivia` for setting indentation during macro expansion
597602
/// (e.g., `.spaces(2)`). Defaults to the original source's indentation if unspecified. If the
598603
/// original source lacks indentation, it defaults to `.spaces(4)`.
599-
/// - isRecording: Determines if a new macro expansion will be recorded.
604+
/// - record: The recording strategy to use for the macro expansion. If not provided, it defaults to the current
605+
/// configuration, which can be set using the `SNAPSHOT_TESTING_RECORD` environment variable.
600606
/// - macros: Specifies the macros to be expanded in the input Swift source string.
601607
/// - operation: The operation to run with the configuration updated.
602608
public func withMacroTesting<R>(
@@ -617,14 +623,15 @@ public func withMacroTesting<R>(
617623

618624
/// Customizes `assertMacro` for the duration of an operation.
619625
///
620-
/// See ``withMacroTesting(indentationWidth:isRecording:macros:operation:)-5id9j`` for
621-
/// more details.
626+
/// See ``assertMacro(_:indentationWidth:record:of:diagnostics:fixes:expansion:fileID:file:function:line:column:)-90l38``
627+
/// for more details.
622628
///
623629
/// - Parameters:
624630
/// - indentationWidth: The `Trivia` for setting indentation during macro expansion
625631
/// (e.g., `.spaces(2)`). Defaults to the original source's indentation if unspecified. If the
626632
/// original source lacks indentation, it defaults to `.spaces(4)`.
627-
/// - isRecording: Determines if a new macro expansion will be recorded.
633+
/// - record: The recording strategy to use for the macro expansion. If not provided, it defaults to the current
634+
/// configuration, which can be set using the `SNAPSHOT_TESTING_RECORD` environment variable.
628635
/// - macros: Specifies the macros to be expanded in the input Swift source string.
629636
/// - operation: The operation to run with the configuration updated.
630637
public func withMacroTesting<R>(
@@ -643,14 +650,15 @@ public func withMacroTesting<R>(
643650

644651
/// Customizes `assertMacro` for the duration of an operation.
645652
///
646-
/// See ``withMacroTesting(indentationWidth:isRecording:macros:operation:)-5id9j`` for
653+
/// See ``withMacroTesting(indentationWidth:record:macros:operation:)-7cm1s`` for
647654
/// more details.
648655
///
649656
/// - Parameters:
650657
/// - indentationWidth: The `Trivia` for setting indentation during macro expansion
651658
/// (e.g., `.spaces(2)`). Defaults to the original source's indentation if unspecified. If the
652659
/// original source lacks indentation, it defaults to `.spaces(4)`.
653-
/// - isRecording: Determines if a new macro expansion will be recorded.
660+
/// - record: The recording strategy to use for the macro expansion. If not provided, it defaults to the current
661+
/// configuration, which can be set using the `SNAPSHOT_TESTING_RECORD` environment variable
654662
/// - macros: Specifies the macros to be expanded in the input Swift source string.
655663
/// - operation: The operation to run with the configuration updated.
656664
public func withMacroTesting<R>(
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
# ``MacroTesting/assertMacro(_:record:of:diagnostics:fixes:expansion:file:function:line:column:)-6hxgm``
1+
# ``MacroTesting/assertMacro(_:indentationWidth:record:of:diagnostics:fixes:expansion:fileID:file:function:line:column:)-8zqk4``
22

33
## Topics
44

55
### Overloads
66

7-
- ``assertMacro(_:record:of:diagnostics:fixes:expansion:file:function:line:column:)-3hjp``
7+
- ``assertMacro(_:record:of:matches:fileID:file:function:line:column:)-2wi38``
8+
- ``assertMacro(_:indentationWidth:record:of:diagnostics:fixes:expansion:fileID:file:function:line:column:)-90l38``
89

910
### Deprecations
1011

11-
- ``assertMacro(_:applyFixIts:record:of:matches:file:function:line:column:)-4xamb``
12-
- ``assertMacro(_:applyFixIts:record:of:matches:file:function:line:column:)-7jwrb``
12+
- ``assertMacro(_:record:of:matches:fileID:file:function:line:column:)-6vxvm``
13+
- ``assertMacro(_:applyFixIts:record:of:matches:fileID:file:function:line:column:)-4381w``
14+
- ``assertMacro(_:applyFixIts:record:of:matches:fileID:file:function:line:column:)-9mzoj``

Sources/MacroTesting/Documentation.docc/MacroTesting.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ running the test again will produce a nicely formatted message:
5757

5858
You can even have the library automatically re-record the macro expansion directly into your test
5959
file by providing the `record` argument to
60-
``assertMacro(_:record:of:diagnostics:fixes:expansion:file:function:line:column:)-6hxgm``
60+
``assertMacro(_:indentationWidth:record:of:diagnostics:fixes:expansion:fileID:file:function:line:column:)-8zqk4``
6161
```swift
62-
assertMacro(["stringify": StringifyMacro.self], record: true) {
62+
assertMacro(["stringify": StringifyMacro.self], record: .all) {
6363
"""
6464
#stringify(a + b)
6565
"""
@@ -103,14 +103,14 @@ class StringifyMacroTests: XCTestCase {
103103
}
104104
```
105105

106-
You can pass the `isRecording` parameter to
107-
``withMacroTesting(isRecording:macros:operation:)-2vypn`` to re-record every assertion in the test
106+
You can pass the `record` parameter to
107+
``withMacroTesting(indentationWidth:record:macros:operation:)-7cm1s`` to re-record every assertion in the test
108108
case (or suite, if you're using your own custom base test case class):
109109

110110
```swift
111111
override func invokeTest() {
112112
withMacroTesting(
113-
isRecording: true
113+
record: .all
114114
) {
115115
super.invokeTest()
116116
}
@@ -169,5 +169,5 @@ func testNonAsyncFunctionDiagnostic() {
169169

170170
### Essentials
171171

172-
- ``assertMacro(_:record:of:diagnostics:fixes:expansion:file:function:line:column:)-6hxgm``
173-
- ``withMacroTesting(isRecording:macros:operation:)-2vypn``
172+
- ``assertMacro(_:indentationWidth:record:of:diagnostics:fixes:expansion:fileID:file:function:line:column:)-8zqk4``
173+
- ``withMacroTesting(indentationWidth:record:macros:operation:)-7cm1s``
Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
# ``MacroTesting/withMacroTesting(isRecording:macros:operation:)-2vypn``
1+
# ``MacroTesting/withMacroTesting(indentationWidth:record:macros:operation:)-6ayf5``
22

33
## Topics
44

55
### Overloads
66

7-
- ``withMacroTesting(isRecording:macros:operation:)-6bf9b``
8-
- ``withMacroTesting(isRecording:macros:operation:)-7jgpz``
9-
- ``withMacroTesting(isRecording:macros:operation:)-7fx9t``
7+
- ``withMacroTesting(indentationWidth:record:macros:operation:)-7cm1s``
8+
- ``withMacroTesting(indentationWidth:record:macros:operation:)-5a7qi``
9+
- ``withMacroTesting(indentationWidth:record:macros:operation:)-9ghea``
10+
11+
### Deprecations
12+
13+
- ``withMacroTesting(indentationWidth:isRecording:macros:operation:)-1yql2``
14+
- ``withMacroTesting(indentationWidth:isRecording:macros:operation:)-9du8s``
15+
- ``withMacroTesting(indentationWidth:isRecording:macros:operation:)-91prk``
16+
- ``withMacroTesting(indentationWidth:isRecording:macros:operation:)-5id9j``

Sources/MacroTesting/MacrosTestTrait.swift

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@
44
import SwiftSyntaxMacros
55
import Testing
66

7-
@_spi(Experimental)
87
extension Trait where Self == _MacrosTestTrait {
98
/// Configure snapshot testing in a suite or test.
109
///
1110
/// - Parameters:
12-
/// - record: The record mode of the test.
13-
/// - diffTool: The diff tool to use in failure messages.
11+
/// - indentationWidth: The `Trivia` for setting indentation during macro expansion (e.g., `.spaces(2)`).
12+
/// Defaults to the original source's indentation if unspecified.
13+
/// - record: The recording strategy to use for macro expansions. This can be set to `.all`, `.missing`,
14+
/// `.never`, or `.failed`. If not provided, it uses the current configuration, which can also be set via
15+
/// the `SNAPSHOT_TESTING_RECORD` environment variable.
16+
/// - macros: A dictionary mapping macro names to their implementations. This specifies which macros
17+
/// should be expanded during testing.
1418
public static func macros(
1519
indentationWidth: Trivia? = nil,
1620
record: SnapshotTestingConfiguration.Record? = nil,
@@ -27,7 +31,6 @@
2731
}
2832

2933
/// A type representing the configuration of snapshot testing.
30-
@_spi(Experimental)
3134
public struct _MacrosTestTrait: SuiteTrait, TestTrait {
3235
public let isRecursive = true
3336
let configuration: MacroTestingConfiguration

Tests/MacroTestingTests/SwiftTestingTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#if canImport(Testing)
2-
@_spi(Experimental) import MacroTesting
2+
import MacroTesting
33
import Testing
44

55
@Suite(
66
.macros(
7-
//record: .failed,
7+
// record: .failed,
88
macros: ["URL": URLMacro.self]
99
)
1010
)

0 commit comments

Comments
 (0)