@@ -45,11 +45,11 @@ final class EventEmitterTests: XCTestCase {
45
45
func testEventEmitterAttachListener( ) async throws {
46
46
// Given: An event emitter and a listener
47
47
let emitter = AuthStateChangeEventEmitter ( )
48
- var receivedEvents : [ AuthChangeEvent ] = [ ]
48
+ let receivedEvents = LockIsolated < [ AuthChangeEvent ] > ( [ ] )
49
49
50
50
// When: Attaching a listener
51
51
let token = emitter. attach { event, _ in
52
- receivedEvents. append ( event)
52
+ receivedEvents. withValue { $0 . append ( event) }
53
53
}
54
54
55
55
// And: Emitting an event
@@ -60,26 +60,26 @@ final class EventEmitterTests: XCTestCase {
60
60
// Note: We need to wait a bit for the async event processing
61
61
try await Task . sleep ( nanoseconds: 100_000_000 ) // 0.1 seconds
62
62
63
- XCTAssertEqual ( receivedEvents. count, 1 )
64
- XCTAssertEqual ( receivedEvents. first, . signedIn)
63
+ XCTAssertEqual ( receivedEvents. value . count, 1 )
64
+ XCTAssertEqual ( receivedEvents. value . first, . signedIn)
65
65
66
66
// Cleanup
67
- token. remove ( )
67
+ token. cancel ( )
68
68
}
69
69
70
70
func testEventEmitterMultipleListeners( ) async throws {
71
71
// Given: An event emitter and multiple listeners
72
72
let emitter = AuthStateChangeEventEmitter ( )
73
- var listener1Events : [ AuthChangeEvent ] = [ ]
74
- var listener2Events : [ AuthChangeEvent ] = [ ]
73
+ let listener1Events = LockIsolated < [ AuthChangeEvent ] > ( [ ] )
74
+ let listener2Events = LockIsolated < [ AuthChangeEvent ] > ( [ ] )
75
75
76
76
// When: Attaching multiple listeners
77
77
let token1 = emitter. attach { event, _ in
78
- listener1Events. append ( event)
78
+ listener1Events. withValue { $0 . append ( event) }
79
79
}
80
80
81
81
let token2 = emitter. attach { event, _ in
82
- listener2Events. append ( event)
82
+ listener2Events. withValue { $0 . append ( event) }
83
83
}
84
84
85
85
// And: Emitting events
@@ -90,24 +90,24 @@ final class EventEmitterTests: XCTestCase {
90
90
// Then: Both listeners should receive all events
91
91
try await Task . sleep ( nanoseconds: 100_000_000 ) // 0.1 seconds
92
92
93
- XCTAssertEqual ( listener1Events. count, 2 )
94
- XCTAssertEqual ( listener2Events. count, 2 )
95
- XCTAssertEqual ( listener1Events, [ . signedIn, . tokenRefreshed] )
96
- XCTAssertEqual ( listener2Events, [ . signedIn, . tokenRefreshed] )
93
+ XCTAssertEqual ( listener1Events. value . count, 2 )
94
+ XCTAssertEqual ( listener2Events. value . count, 2 )
95
+ XCTAssertEqual ( listener1Events. value , [ . signedIn, . tokenRefreshed] )
96
+ XCTAssertEqual ( listener2Events. value , [ . signedIn, . tokenRefreshed] )
97
97
98
98
// Cleanup
99
- token1. remove ( )
100
- token2. remove ( )
99
+ token1. cancel ( )
100
+ token2. cancel ( )
101
101
}
102
102
103
103
func testEventEmitterRemoveListener( ) async throws {
104
104
// Given: An event emitter and a listener
105
105
let emitter = AuthStateChangeEventEmitter ( )
106
- var receivedEvents : [ AuthChangeEvent ] = [ ]
106
+ let receivedEvents = LockIsolated < [ AuthChangeEvent ] > ( [ ] )
107
107
108
108
// When: Attaching a listener
109
109
let token = emitter. attach { event, _ in
110
- receivedEvents. append ( event)
110
+ receivedEvents. withValue { $0 . append ( event) }
111
111
}
112
112
113
113
// And: Emitting an event
@@ -116,27 +116,27 @@ final class EventEmitterTests: XCTestCase {
116
116
117
117
// Then: Listener should receive the event
118
118
try await Task . sleep ( nanoseconds: 100_000_000 ) // 0.1 seconds
119
- XCTAssertEqual ( receivedEvents. count, 1 )
119
+ XCTAssertEqual ( receivedEvents. value . count, 1 )
120
120
121
121
// When: Removing the listener
122
- token. remove ( )
122
+ token. cancel ( )
123
123
124
124
// And: Emitting another event
125
125
emitter. emit ( . signedOut, session: nil )
126
126
127
127
// Then: Listener should not receive the new event
128
128
try await Task . sleep ( nanoseconds: 100_000_000 ) // 0.1 seconds
129
- XCTAssertEqual ( receivedEvents. count, 1 ) // Should still be 1
129
+ XCTAssertEqual ( receivedEvents. value . count, 1 ) // Should still be 1
130
130
}
131
131
132
132
func testEventEmitterEmitWithSession( ) async throws {
133
133
// Given: An event emitter and a listener
134
134
let emitter = AuthStateChangeEventEmitter ( )
135
- var receivedSessions : [ Session ? ] = [ ]
135
+ let receivedSessions = LockIsolated < [ Session ? ] > ( [ ] )
136
136
137
137
// When: Attaching a listener
138
138
let token = emitter. attach { _, session in
139
- receivedSessions. append ( session)
139
+ receivedSessions. withValue { $0 . append ( session) }
140
140
}
141
141
142
142
// And: Emitting an event with session
@@ -145,43 +145,43 @@ final class EventEmitterTests: XCTestCase {
145
145
146
146
// Then: Listener should receive the session
147
147
try await Task . sleep ( nanoseconds: 100_000_000 ) // 0.1 seconds
148
- XCTAssertEqual ( receivedSessions. count, 1 )
149
- XCTAssertEqual ( receivedSessions. first?? . accessToken, session. accessToken)
148
+ XCTAssertEqual ( receivedSessions. value . count, 1 )
149
+ XCTAssertEqual ( receivedSessions. value . first?? . accessToken, session. accessToken)
150
150
151
151
// Cleanup
152
- token. remove ( )
152
+ token. cancel ( )
153
153
}
154
154
155
155
func testEventEmitterEmitWithoutSession( ) async throws {
156
156
// Given: An event emitter and a listener
157
157
let emitter = AuthStateChangeEventEmitter ( )
158
- var receivedSessions : [ Session ? ] = [ ]
158
+ let receivedSessions = LockIsolated < [ Session ? ] > ( [ ] )
159
159
160
160
// When: Attaching a listener
161
161
let token = emitter. attach { _, session in
162
- receivedSessions. append ( session)
162
+ receivedSessions. withValue { $0 . append ( session) }
163
163
}
164
164
165
165
// And: Emitting an event without session
166
166
emitter. emit ( . signedOut, session: nil )
167
167
168
168
// Then: Listener should receive nil session
169
169
try await Task . sleep ( nanoseconds: 100_000_000 ) // 0.1 seconds
170
- XCTAssertEqual ( receivedSessions. count, 1 )
171
- XCTAssertNil ( receivedSessions. first)
170
+ XCTAssertEqual ( receivedSessions. value . count, 1 )
171
+ XCTAssertNil ( receivedSessions. value . first)
172
172
173
173
// Cleanup
174
- token. remove ( )
174
+ token. cancel ( )
175
175
}
176
176
177
177
func testEventEmitterEmitWithToken( ) async throws {
178
178
// Given: An event emitter and a listener
179
179
let emitter = AuthStateChangeEventEmitter ( )
180
- var receivedEvents : [ AuthChangeEvent ] = [ ]
180
+ let receivedEvents = LockIsolated < [ AuthChangeEvent ] > ( [ ] )
181
181
182
182
// When: Attaching a listener
183
183
let token = emitter. attach { event, _ in
184
- receivedEvents. append ( event)
184
+ receivedEvents. withValue { $0 . append ( event) }
185
185
}
186
186
187
187
// And: Emitting an event with specific token
@@ -190,21 +190,21 @@ final class EventEmitterTests: XCTestCase {
190
190
191
191
// Then: Listener should receive the event
192
192
try await Task . sleep ( nanoseconds: 100_000_000 ) // 0.1 seconds
193
- XCTAssertEqual ( receivedEvents. count, 1 )
194
- XCTAssertEqual ( receivedEvents. first, . signedIn)
193
+ XCTAssertEqual ( receivedEvents. value . count, 1 )
194
+ XCTAssertEqual ( receivedEvents. value . first, . signedIn)
195
195
196
196
// Cleanup
197
- token. remove ( )
197
+ token. cancel ( )
198
198
}
199
199
200
200
func testEventEmitterAllAuthChangeEvents( ) async throws {
201
201
// Given: An event emitter and a listener
202
202
let emitter = AuthStateChangeEventEmitter ( )
203
- var receivedEvents : [ AuthChangeEvent ] = [ ]
203
+ let receivedEvents = LockIsolated < [ AuthChangeEvent ] > ( [ ] )
204
204
205
205
// When: Attaching a listener
206
206
let token = emitter. attach { event, _ in
207
- receivedEvents. append ( event)
207
+ receivedEvents. withValue { $0 . append ( event) }
208
208
}
209
209
210
210
// And: Emitting all possible auth change events
@@ -226,30 +226,30 @@ final class EventEmitterTests: XCTestCase {
226
226
227
227
// Then: Listener should receive all events
228
228
try await Task . sleep ( nanoseconds: 100_000_000 ) // 0.1 seconds
229
- XCTAssertEqual ( receivedEvents. count, allEvents. count)
230
- XCTAssertEqual ( receivedEvents, allEvents)
229
+ XCTAssertEqual ( receivedEvents. value . count, allEvents. count)
230
+ XCTAssertEqual ( receivedEvents. value , allEvents)
231
231
232
232
// Cleanup
233
- token. remove ( )
233
+ token. cancel ( )
234
234
}
235
235
236
236
func testEventEmitterConcurrentEmissions( ) async throws {
237
237
// Given: An event emitter and a listener
238
238
let emitter = AuthStateChangeEventEmitter ( )
239
- var receivedEvents : [ AuthChangeEvent ] = [ ]
239
+ let receivedEvents = LockIsolated < [ AuthChangeEvent ] > ( [ ] )
240
240
let lock = NSLock ( )
241
241
242
242
// When: Attaching a listener
243
243
let token = emitter. attach { event, _ in
244
244
lock. lock ( )
245
- receivedEvents. append ( event)
245
+ receivedEvents. withValue { $0 . append ( event) }
246
246
lock. unlock ( )
247
247
}
248
248
249
249
// And: Emitting events concurrently
250
250
let session = Session . validSession
251
251
await withTaskGroup ( of: Void . self) { group in
252
- for i in 0 ..< 10 {
252
+ for _ in 0 ..< 10 {
253
253
group. addTask {
254
254
emitter. emit ( . signedIn, session: session)
255
255
}
@@ -258,20 +258,20 @@ final class EventEmitterTests: XCTestCase {
258
258
259
259
// Then: Listener should receive all events
260
260
try await Task . sleep ( nanoseconds: 100_000_000 ) // 0.1 seconds
261
- XCTAssertEqual ( receivedEvents. count, 10 )
261
+ XCTAssertEqual ( receivedEvents. value . count, 10 )
262
262
263
263
// Cleanup
264
- token. remove ( )
264
+ token. cancel ( )
265
265
}
266
266
267
267
func testEventEmitterMemoryManagement( ) async throws {
268
268
// Given: An event emitter and a weak reference to a listener
269
269
let emitter = AuthStateChangeEventEmitter ( )
270
- var receivedEvents : [ AuthChangeEvent ] = [ ]
270
+ let receivedEvents = LockIsolated < [ AuthChangeEvent ] > ( [ ] )
271
271
272
272
// When: Attaching a listener
273
273
let token = emitter. attach { event, _ in
274
- receivedEvents. append ( event)
274
+ receivedEvents. withValue { $0 . append ( event) }
275
275
}
276
276
277
277
// And: Emitting an event
@@ -280,17 +280,17 @@ final class EventEmitterTests: XCTestCase {
280
280
281
281
// Then: Listener should receive the event
282
282
try await Task . sleep ( nanoseconds: 100_000_000 ) // 0.1 seconds
283
- XCTAssertEqual ( receivedEvents. count, 1 )
283
+ XCTAssertEqual ( receivedEvents. value . count, 1 )
284
284
285
285
// When: Removing the token
286
- token. remove ( )
286
+ token. cancel ( )
287
287
288
288
// Then: No memory leaks should occur
289
289
// (This is more of a manual verification, but we can test that the token is properly removed)
290
290
XCTAssertNotNil ( token)
291
291
292
292
// Cleanup
293
- token. remove ( )
293
+ token. cancel ( )
294
294
}
295
295
296
296
// MARK: - Integration Tests
0 commit comments