1- @Timeout (Duration (minutes: 20 ))
2-
31import 'dart:convert' ;
42import 'dart:io' ;
53
64import 'package:flutter_data/flutter_data.dart' ;
7- import 'package:mockito/mockito.dart' ;
85import 'package:test/test.dart' ;
96
107import '../_support/familia.dart' ;
@@ -97,13 +94,12 @@ void main() async {
9794 exception: isA <OfflineException >());
9895
9996 // familia is remembered as failed to persist
100- // TODO fix: at location [0] is <1> instead of '1' (need # and ## again?)
101- // expect(
102- // container.familia.offlineOperations
103- // .only(DataRequestLabel('save', type: 'familia'))
104- // .map((o) => o.label.id)
105- // .toList(),
106- // [familia.id]);
97+ expect (
98+ container.familia.offlineOperations
99+ .only (DataRequestLabel ('save' , type: 'familia' ))
100+ .map ((o) => o.label.id)
101+ .toList (),
102+ [familia.id]);
107103
108104 // try with familia2 (tests it can work without ID)
109105 final familia2 = Familia (surname: 'Montewicz' );
@@ -114,17 +110,15 @@ void main() async {
114110 }
115111
116112 // now two familia failed to persist
117- // expect(
118- // container.familia.offlineOperations
119- // .only(DataRequestLabel('save', type: 'familia'))
120- // .map((o) => o.label.id)
121- // .toList(),
122- // unorderedEquals([familia.id, familia2.id]));
113+ expect (
114+ container.familia.offlineOperations
115+ .only (DataRequestLabel ('save' , type: 'familia' ))
116+ .map ((o) => o.label.id)
117+ .toList (),
118+ unorderedEquals ([familia.id, familia2.id]));
123119
124120 // retry saving both
125121 await container.familia.offlineOperations.retry ();
126- // await 1ms for each familia
127- await oneMs ();
128122
129123 // none of them could be saved upon retry
130124 expect (container.familia.offlineOperations.map ((o) {
@@ -143,7 +137,6 @@ void main() async {
143137
144138 // retry
145139 await container.familia.offlineOperations.retry ();
146- await oneMs ();
147140
148141 // familia2 failed on retry, operation still pending
149142 expect (container.familia.offlineOperations.map ((o) => o.model),
@@ -158,7 +151,6 @@ void main() async {
158151
159152 // retry
160153 await container.familia.offlineOperations.retry ();
161- await oneMs ();
162154
163155 // should be empty as all saves succeeded
164156 expect (container.familia.offlineOperations.map ((o) => o.model), isEmpty);
@@ -173,7 +165,6 @@ void main() async {
173165 } catch (_) {
174166 // without onError, ignore exception
175167 }
176- await oneMs ();
177168
178169 // assert familia3 hasn't been persisted
179170 expect (
@@ -194,42 +185,32 @@ void main() async {
194185 });
195186
196187 test ('delete' , () async {
197- final listener = Listener <DataState <List <Familia >?>?>();
198188 // listening to local changes is enough
199189 final notifier = container.familia.watchAllNotifier ();
200-
201- final dispose = notifier.addListener (listener);
202- disposeFns.add (dispose);
190+ final tester = notifier.tester ();
203191
204192 final familia = Familia (id: '1' , surname: 'Smith' ).saveLocal ();
205- await oneMs ();
206193
207194 // should show up through watchAllNotifier
208- verify (listener (
209- argThat (isA <DataState >().having ((s) => s.model, 'model' , [familia])),
210- )).called (1 );
195+ await tester.expectDataState ([familia]);
211196
212197 // network issue deleting familia
213198 container.read (responseProvider.notifier).state = TestResponse ((_) {
214199 throw SocketException ('unreachable' );
215200 });
216201
217202 // delete familia and send offline exception to notifier
203+ // NOTE: keep await, so that we give onError the chance to update the notifier
218204 await familia.delete (
219205 onError: (e, _, __) async {
220- await oneMs ();
221206 expect (e, isA <OfflineException >());
222207 expect (e.error, isA <SocketException >());
223208 return null ;
224209 },
225210 );
226211
227- await oneMs ();
228-
229212 // verify the model in local storage has been deleted
230- verify (listener (
231- argThat (isA <DataState >().having ((s) => s.model, 'model' , isEmpty)),
232- )).called (2 );
213+ await tester.expectDataState (isEmpty);
233214
234215 // familia is remembered as failed to persist
235216 expect (
@@ -240,7 +221,6 @@ void main() async {
240221
241222 // retry
242223 await container.familia.offlineOperations.retry ();
243- await oneMs ();
244224
245225 // could not be deleted upon retry
246226 expect (
@@ -254,55 +234,43 @@ void main() async {
254234
255235 // retry
256236 await container.familia.offlineOperations.retry ();
257- await oneMs ();
258237
259238 // now offline queue is empty
260239 expect (container.familia.offlineOperations, isEmpty);
261240 });
262241
263242 test ('save & delete combined' , () async {
264- final listener = Listener <DataState <List <Familia >?>?>();
265243 // listening to local changes enough
266244 final notifier = container.familia.watchAllNotifier (remote: false );
267-
268- final dispose = notifier.addListener (listener);
269- disposeFns.add (dispose);
245+ final tester = notifier.tester ();
270246
271247 // setup familia
272248 final familia = Familia (id: '19' , surname: 'Ko' );
273- await oneMs ();
274249
275250 // network issues
276251 container.read (responseProvider.notifier).state = TestResponse ((_) {
277252 throw SocketException ('unreachable' );
278253 });
279254
280- // save...
255+ // save
281256 await familia.save (
282257 headers: {'X-Override-Name' : 'Johnson' },
283258 onError: (e, _, __) async {
284- await oneMs ();
285259 notifier.updateWith (exception: e);
286260 return null ;
287261 },
288262 );
289263
290- await oneMs ();
291-
292- // ...and immediately delete
264+ // immediately delete
293265 await familia.delete (
294266 onError: (e, _, __) async {
295- await oneMs ();
296267 notifier.updateWith (exception: e);
297268 return null ;
298269 },
299270 );
300271
301- // assert it's an OfflineException, TWICE (one call per updateWith(e))
302- verify (listener (argThat (
303- isA <DataState >()
304- .having ((s) => s.exception, 'exception' , isA <OfflineException >()),
305- ))).called (1 );
272+ // assert it's an OfflineException
273+ tester.expectDataState (isNotNull, exception: isA <OfflineException >());
306274
307275 // should see the failed save queued
308276 expect (
@@ -331,16 +299,16 @@ void main() async {
331299
332300 // retry
333301 await container.familia.offlineOperations.retry ();
334- await oneMs ();
335- // same result...
302+
303+ // same result
336304 expect (container.familia.offlineOperations, hasLength (2 ));
337305
338306 // change the response to success
339307 container.read (responseProvider.notifier).state = TestResponse .json ('' );
340308
341309 // retry
342310 await container.familia.offlineOperations.retry ();
343- await oneMs ();
311+
344312 // done
345313 expect (container.familia.offlineOperations, isEmpty);
346314 });
@@ -367,7 +335,6 @@ void main() async {
367335 return result;
368336 },
369337 );
370- await oneMs ();
371338 // fails to go through
372339 expect (container.familia.offlineOperations, hasLength (1 ));
373340
@@ -383,7 +350,7 @@ void main() async {
383350
384351 // retry
385352 await container.familia.offlineOperations.retry ();
386- await oneMs ();
353+
387354 // done
388355 expect (container.familia.offlineOperations, isEmpty);
389356 });
0 commit comments