@@ -33,5 +33,187 @@ class AsyncTests: XCTestCase {
3333 let firstMonster = fetchedResult [ 0 ]
3434 XCTAssertEqual ( firstMonster. name, " What's my name " )
3535 }
36+
37+ @available ( macOS 12 . 0 , iOS 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , * )
38+ func testSubscribeObjectAsyncSequence( ) async {
39+ guard let dflat = dflat else { return }
40+ await dflat. performChanges (
41+ [ MyGame . Sample. Monster. self] ,
42+ changesHandler: { ( txnContext) in
43+ for i in 0 ..< 10 {
44+ let creationRequest = MyGame . Sample. MonsterChangeRequest. creationRequest ( )
45+ creationRequest. name = " name \( i) "
46+ try ! txnContext. submit ( creationRequest)
47+ }
48+ }
49+ )
50+ let fetchedResult = dflat. fetch ( for: MyGame . Sample. Monster. self) . all ( )
51+ XCTAssertEqual ( fetchedResult. count, 10 )
52+ let firstMonster = fetchedResult [ 0 ]
53+ XCTAssertEqual ( firstMonster. name, " name 0 " )
54+ let subscribeTask = Task {
55+ var updatedObject : MyGame . Sample . Monster ? = nil
56+ for await newObject in dflat. subscribe ( object: firstMonster, bufferingPolicy: . unbounded) {
57+ updatedObject = newObject
58+ }
59+ XCTAssertEqual ( updatedObject? . color, . red)
60+ }
61+ await dflat. performChanges (
62+ [ MyGame . Sample. Monster. self] ,
63+ changesHandler: { ( txnContext) in
64+ guard let changeRequest = MyGame . Sample. MonsterChangeRequest. changeRequest ( firstMonster)
65+ else { return }
66+ changeRequest. color = . red
67+ try ! txnContext. submit ( changeRequest)
68+ }
69+ )
70+ await dflat. performChanges (
71+ [ MyGame . Sample. Monster. self] ,
72+ changesHandler: { ( txnContext) in
73+ guard
74+ let deletionRequest = MyGame . Sample. MonsterChangeRequest. deletionRequest ( firstMonster)
75+ else { return }
76+ try ! txnContext. submit ( deletionRequest)
77+ }
78+ )
79+ await subscribeTask. value
80+ }
81+
82+ @available ( macOS 12 . 0 , iOS 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , * )
83+ func testSubscribeOutdatedObjectAndCacnelBeforeNextUpdateAsyncSequence( ) async {
84+ guard let dflat = dflat else { return }
85+ await dflat. performChanges (
86+ [ MyGame . Sample. Monster. self] ,
87+ changesHandler: { ( txnContext) in
88+ for i in 0 ..< 10 {
89+ let creationRequest = MyGame . Sample. MonsterChangeRequest. creationRequest ( )
90+ creationRequest. name = " name \( i) "
91+ try ! txnContext. submit ( creationRequest)
92+ }
93+ }
94+ )
95+ let fetchedResult = dflat. fetch ( for: MyGame . Sample. Monster. self) . all ( )
96+ XCTAssertEqual ( fetchedResult. count, 10 )
97+ let firstMonster = fetchedResult [ 0 ]
98+ XCTAssertEqual ( firstMonster. name, " name 0 " )
99+ await dflat. performChanges (
100+ [ MyGame . Sample. Monster. self] ,
101+ changesHandler: { ( txnContext) in
102+ guard let changeRequest = MyGame . Sample. MonsterChangeRequest. changeRequest ( firstMonster)
103+ else { return }
104+ changeRequest. color = . red
105+ try ! txnContext. submit ( changeRequest)
106+ }
107+ )
108+ let subscribeTask = Task {
109+ var updatedObject : MyGame . Sample . Monster ? = nil
110+ for await newObject in dflat. subscribe ( object: firstMonster, bufferingPolicy: . unbounded) {
111+ updatedObject = newObject
112+ break
113+ }
114+ XCTAssertEqual ( updatedObject? . color, . red)
115+ }
116+ await subscribeTask. value
117+ await dflat. performChanges (
118+ [ MyGame . Sample. Monster. self] ,
119+ changesHandler: { ( txnContext) in
120+ guard
121+ let deletionRequest = MyGame . Sample. MonsterChangeRequest. deletionRequest ( firstMonster)
122+ else { return }
123+ try ! txnContext. submit ( deletionRequest)
124+ }
125+ )
126+ }
127+
128+ @available ( macOS 12 . 0 , iOS 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , * )
129+ func testSubscribeFetchedResultAsyncSequence( ) async {
130+ guard let dflat = dflat else { return }
131+ await dflat. performChanges (
132+ [ MyGame . Sample. Monster. self] ,
133+ changesHandler: { ( txnContext) in
134+ for i in 0 ..< 10 {
135+ let creationRequest = MyGame . Sample. MonsterChangeRequest. creationRequest ( )
136+ creationRequest. name = " name \( i) "
137+ creationRequest. mana = Int16 ( i * 10 )
138+ try ! txnContext. submit ( creationRequest)
139+ }
140+ }
141+ )
142+ let fetchedResult = dflat. fetch ( for: MyGame . Sample. Monster. self) . where (
143+ MyGame . Sample. Monster. mana <= 50 , orderBy: [ MyGame . Sample. Monster. mana. ascending] )
144+ XCTAssertEqual ( fetchedResult. count, 6 )
145+ let subscribeTask = Task { ( ) -> FetchedResult < MyGame . Sample . Monster > in
146+ var updateCount = 0
147+ var updatedFetchedResult = fetchedResult
148+ for await newFetchedResult in dflat. subscribe (
149+ fetchedResult: fetchedResult, bufferingPolicy: . unbounded)
150+ {
151+ updatedFetchedResult = newFetchedResult
152+ updateCount += 1
153+ if updateCount == 4 {
154+ break
155+ }
156+ }
157+ return updatedFetchedResult
158+ }
159+ // Add one.
160+ await dflat. performChanges (
161+ [ MyGame . Sample. Monster. self] ,
162+ changesHandler: { ( txnContext) in
163+ let creationRequest = MyGame . Sample. MonsterChangeRequest. creationRequest ( )
164+ creationRequest. name = " name 10 "
165+ creationRequest. mana = 15
166+ try ! txnContext. submit ( creationRequest)
167+ }
168+ )
169+ // Mutate one, move to later.
170+ await dflat. performChanges (
171+ [ MyGame . Sample. Monster. self] ,
172+ changesHandler: { ( txnContext) in
173+ let monster = dflat. fetch ( for: MyGame . Sample. Monster. self) . where (
174+ MyGame . Sample. Monster. name == " name 2 " ) [ 0 ]
175+ guard let changeRequest = MyGame . Sample. MonsterChangeRequest. changeRequest ( monster) else {
176+ return
177+ }
178+ changeRequest. mana = 43
179+ try ! txnContext. submit ( changeRequest)
180+ }
181+ )
182+ // Mutate one, move to earlier.
183+ await dflat. performChanges (
184+ [ MyGame . Sample. Monster. self] ,
185+ changesHandler: { ( txnContext) in
186+ let monster = dflat. fetch ( for: MyGame . Sample. Monster. self) . where (
187+ MyGame . Sample. Monster. name == " name 4 " ) [ 0 ]
188+ guard let changeRequest = MyGame . Sample. MonsterChangeRequest. changeRequest ( monster) else {
189+ return
190+ }
191+ changeRequest. mana = 13
192+ try ! txnContext. submit ( changeRequest)
193+ }
194+ )
195+ // Delete one, move to earlier.
196+ await dflat. performChanges (
197+ [ MyGame . Sample. Monster. self] ,
198+ changesHandler: { ( txnContext) in
199+ let monster = dflat. fetch ( for: MyGame . Sample. Monster. self) . where (
200+ MyGame . Sample. Monster. name == " name 3 " ) [ 0 ]
201+ guard let deletionRequest = MyGame . Sample. MonsterChangeRequest. deletionRequest ( monster)
202+ else { return }
203+ try ! txnContext. submit ( deletionRequest)
204+ }
205+ )
206+ let updatedFetchedResult = await subscribeTask. value
207+ XCTAssertEqual ( updatedFetchedResult. count, 6 )
208+ XCTAssertEqual ( updatedFetchedResult [ 0 ] . name, " name 0 " )
209+ XCTAssertEqual ( updatedFetchedResult [ 1 ] . name, " name 1 " )
210+ XCTAssertEqual ( updatedFetchedResult [ 2 ] . name, " name 4 " )
211+ XCTAssertEqual ( updatedFetchedResult [ 3 ] . name, " name 10 " )
212+ XCTAssertEqual ( updatedFetchedResult [ 4 ] . name, " name 2 " )
213+ XCTAssertEqual ( updatedFetchedResult [ 5 ] . name, " name 5 " )
214+ let finalFetchedResult = dflat. fetch ( for: MyGame . Sample. Monster. self) . where (
215+ MyGame . Sample. Monster. mana <= 50 , orderBy: [ MyGame . Sample. Monster. mana. ascending] )
216+ XCTAssertEqual ( updatedFetchedResult, finalFetchedResult)
217+ }
36218 #endif
37219}
0 commit comments