Skip to content

Commit 5b406be

Browse files
committed
WIP: Prototype for a TemporaryDirectoryTrait and AsyncDeferrableTrait
I just want to raise the idea of using test traits over `with` function to avoid nesting levels due to `with*` functions in tests.
1 parent 17b6273 commit 5b406be

File tree

1 file changed

+103
-21
lines changed

1 file changed

+103
-21
lines changed

Tests/SwiftBuildTests/PreferredRunDestinationTests.swift

Lines changed: 103 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,36 +18,118 @@ import SWBTestSupport
1818

1919
@Suite
2020
fileprivate struct PreferredRunDestinationTests {
21-
@Test(.requireSDKs(.macOS))
21+
@Test(.requireSDKs(.macOS), .temporaryDirectory, .asyncDeferrable)
2222
func platformExists() async throws {
23-
try await withTemporaryDirectory { (temporaryDirectory: NamedTemporaryDirectory) in
24-
try await withAsyncDeferrable { deferrable in
25-
let testSession = try await TestSWBSession(temporaryDirectory: temporaryDirectory)
26-
await deferrable.addBlock {
27-
await #expect(throws: Never.self) {
28-
try await testSession.close()
29-
}
23+
let testSession = try await TestSWBSession(temporaryDirectory: TemporaryDirectoryTrait.temporaryDirectory)
24+
try await AsyncDeferrableTrait.defer {
25+
try await testSession.close()
26+
}
27+
let runDestination = try await testSession.session.preferredRunDestination(forPlatform: "macosx")
28+
#expect(runDestination.sdk == "macosx")
29+
}
30+
31+
@Test(.temporaryDirectory, .asyncDeferrable)
32+
func unknownPlatform() async throws {
33+
let testSession = try await TestSWBSession(temporaryDirectory: TemporaryDirectoryTrait.temporaryDirectory)
34+
try await AsyncDeferrableTrait.defer {
35+
try await testSession.close()
36+
}
37+
await #expect(throws: (any Error).self) {
38+
try await testSession.session.preferredRunDestination(forPlatform: "unknown_platform")
39+
}
40+
}
41+
}
42+
43+
struct TemporaryDirectoryTrait: TestTrait {
44+
@TaskLocal private static var _temporaryDirectory: NamedTemporaryDirectory?
45+
46+
static var temporaryDirectory: NamedTemporaryDirectory {
47+
get throws {
48+
guard let _temporaryDirectory else {
49+
throw StubError.error("Accessing temporary directory in test that doesn't specify .temporaryDirectory trait")
50+
}
51+
return _temporaryDirectory
52+
}
53+
}
54+
55+
package init() {}
56+
57+
struct TestScopeProvider: TestScoping {
58+
func provideScope(
59+
for test: Test,
60+
testCase: Test.Case?,
61+
performing function: @Sendable () async throws -> Void
62+
) async throws {
63+
try await withTemporaryDirectory { temporaryDirectory in
64+
try await $_temporaryDirectory.withValue(temporaryDirectory) {
65+
try await function()
3066
}
31-
let runDestination = try await testSession.session.preferredRunDestination(forPlatform: "macosx")
32-
#expect(runDestination.sdk == "macosx")
3367
}
3468
}
3569
}
3670

37-
@Test
38-
func unknownPlatform() async throws {
39-
try await withTemporaryDirectory { (temporaryDirectory: NamedTemporaryDirectory) in
71+
func scopeProvider(for test: Test, testCase: Test.Case?) -> TestScopeProvider? {
72+
guard testCase != nil else {
73+
// We only need to set up a new temporary directory for the execution of a parameterized version of the test.
74+
return nil
75+
}
76+
return TestScopeProvider()
77+
}
78+
}
79+
80+
extension Trait where Self == TemporaryDirectoryTrait {
81+
static var temporaryDirectory: TemporaryDirectoryTrait {
82+
return TemporaryDirectoryTrait()
83+
}
84+
}
85+
86+
struct AsyncDeferrableTrait: TestTrait {
87+
@TaskLocal private static var _deferrable: Deferrable?
88+
89+
static var deferrable: Deferrable {
90+
get throws {
91+
guard let _deferrable else {
92+
throw StubError.error("Accessing temporary directory in test that doesn't specify .asyncDeferrable trait")
93+
}
94+
return _deferrable
95+
}
96+
}
97+
98+
static func `defer`(sourceLocation: SourceLocation = #_sourceLocation, _ body: @escaping @Sendable () async throws -> Void) async throws {
99+
try await deferrable.addBlock {
100+
await #expect(throws: Never.self, sourceLocation: sourceLocation) {
101+
try await body()
102+
}
103+
}
104+
}
105+
106+
package init() {}
107+
108+
struct TestScopeProvider: TestScoping {
109+
func provideScope(
110+
for test: Test,
111+
testCase: Test.Case?,
112+
performing function: @Sendable () async throws -> Void
113+
) async throws {
40114
try await withAsyncDeferrable { deferrable in
41-
let testSession = try await TestSWBSession(temporaryDirectory: temporaryDirectory)
42-
await deferrable.addBlock {
43-
await #expect(throws: Never.self) {
44-
try await testSession.close()
45-
}
46-
}
47-
await #expect(throws: (any Error).self) {
48-
try await testSession.session.preferredRunDestination(forPlatform: "unknown_platform")
115+
try await $_deferrable.withValue(deferrable) {
116+
try await function()
49117
}
50118
}
51119
}
52120
}
121+
122+
func scopeProvider(for test: Test, testCase: Test.Case?) -> TestScopeProvider? {
123+
guard testCase != nil else {
124+
// We only need to set up a deferrable for the execution of a parameterized version of the test.
125+
return nil
126+
}
127+
return TestScopeProvider()
128+
}
129+
}
130+
131+
extension Trait where Self == AsyncDeferrableTrait {
132+
static var asyncDeferrable: AsyncDeferrableTrait {
133+
return AsyncDeferrableTrait()
134+
}
53135
}

0 commit comments

Comments
 (0)