@@ -28,10 +28,12 @@ import Testing
28
28
struct MainActorQueueTests {
29
29
// MARK: Behavior Tests
30
30
31
+ @TestingQueue
31
32
@Test func test_shared_returnsSameInstance( ) async {
32
33
#expect( MainActorQueue . shared === MainActorQueue . shared)
33
34
}
34
35
36
+ @TestingQueue
35
37
@Test func test_enqueue_executesOnMainThread( ) async {
36
38
let key : DispatchSpecificKey < Void > = . init( )
37
39
DispatchQueue . main. setSpecific ( key: key, value: ( ) )
@@ -41,6 +43,7 @@ struct MainActorQueueTests {
41
43
await systemUnderTest. enqueueAndWait { /* Drain the queue */ }
42
44
}
43
45
46
+ @TestingQueue
44
47
@Test func test_enqueue_sendsEventsInOrder( ) async {
45
48
for iteration in 1 ... 1_000 {
46
49
systemUnderTest. enqueue { [ counter] in
@@ -50,6 +53,7 @@ struct MainActorQueueTests {
50
53
await systemUnderTest. enqueueAndWait { /* Drain the queue */ }
51
54
}
52
55
56
+ @TestingQueue
53
57
@Test func test_enqueue_startsExecutionOfNextTaskAfterSuspension( ) async {
54
58
let semaphore = Semaphore ( )
55
59
@@ -65,6 +69,7 @@ struct MainActorQueueTests {
65
69
await systemUnderTest. enqueueAndWait { /* Drain the queue */ }
66
70
}
67
71
72
+ @TestingQueue
68
73
@Test func test_enqueueAndWait_executesOnMainThread( ) async {
69
74
let key : DispatchSpecificKey < Void > = . init( )
70
75
DispatchQueue . main. setSpecific ( key: key, value: ( ) )
@@ -73,6 +78,7 @@ struct MainActorQueueTests {
73
78
}
74
79
}
75
80
81
+ @TestingQueue
76
82
@Test func test_enqueueAndWait_allowsReentrancy( ) async {
77
83
await systemUnderTest. enqueueAndWait { [ systemUnderTest, counter] in
78
84
await systemUnderTest. enqueueAndWait { [ counter] in
@@ -82,6 +88,7 @@ struct MainActorQueueTests {
82
88
}
83
89
}
84
90
91
+ @TestingQueue
85
92
@Test func test_enqueue_doesNotRetainTaskAfterExecution( ) async {
86
93
final class Reference : Sendable { }
87
94
final class ReferenceHolder : @unchecked Sendable {
@@ -128,6 +135,7 @@ struct MainActorQueueTests {
128
135
#expect( referenceHolder. weakReference == nil )
129
136
}
130
137
138
+ @TestingQueue
131
139
@Test func test_enqueueAndWait_sendsEventsInOrder( ) async {
132
140
for iteration in 1 ... 1_000 {
133
141
systemUnderTest. enqueue { [ counter] in
@@ -147,12 +155,14 @@ struct MainActorQueueTests {
147
155
await systemUnderTest. enqueueAndWait { /* Drain the queue */ }
148
156
}
149
157
158
+ @TestingQueue
150
159
@Test func test_enqueueAndWait_canReturn( ) async {
151
160
let expectedValue = UUID ( )
152
161
let returnedValue = await systemUnderTest. enqueueAndWait { expectedValue }
153
162
#expect( expectedValue == returnedValue)
154
163
}
155
164
165
+ @TestingQueue
156
166
@Test func test_enqueueAndWait_throwing_canReturn( ) async throws {
157
167
let expectedValue = UUID ( )
158
168
@Sendable func throwingMethod( ) throws { }
@@ -163,6 +173,7 @@ struct MainActorQueueTests {
163
173
#expect( expectedValue == returnedValue)
164
174
}
165
175
176
+ @TestingQueue
166
177
@Test func test_enqueueAndWait_canThrow( ) async {
167
178
struct TestError : Error , Equatable {
168
179
private let identifier = UUID ( )
@@ -180,3 +191,10 @@ struct MainActorQueueTests {
180
191
private let systemUnderTest = MainActorQueue ( )
181
192
private let counter = Counter ( )
182
193
}
194
+
195
+ /// A global actor that forces the above `MainActorQueueTests` to not run on `main`, where tests may otherwise deadlock due to waiting for `main` from `main`.
196
+ @globalActor
197
+ private struct TestingQueue {
198
+ fileprivate actor Shared { }
199
+ fileprivate static let shared = Shared ( )
200
+ }
0 commit comments