Skip to content

Commit 4fe1ede

Browse files
committed
Add test for unsubscribing and resubscribing.
1 parent 2d9e787 commit 4fe1ede

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

pkgs/watcher/test/directory_watcher/file_tests.dart

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'dart:async';
56
import 'dart:io' as io;
67
import 'dart:io';
78
import 'dart:isolate';
89

10+
import 'package:async/async.dart';
911
import 'package:test/test.dart';
1012
import 'package:test_descriptor/test_descriptor.dart' as d;
1113
import 'package:watcher/src/utils.dart';
@@ -34,6 +36,78 @@ void _fileTests({required bool isNative}) {
3436
}
3537
});
3638

39+
// ResubscribableWatcher wraps all the directory watchers to add handling of
40+
// multiple subscribers. The underlying watcher is created when there is at
41+
// least one subscriber and closed when there are zero subscribers. So,
42+
// exercise that behavior in various ways.
43+
test('ResubscribableWatcher handles multiple subscriptions ', () async {
44+
final watcher = createWatcher();
45+
46+
// One subscription, one event, close the subscription.
47+
final queue1 = StreamQueue(watcher.events);
48+
final event1 = queue1.next;
49+
await watcher.ready;
50+
writeFile('a.txt');
51+
expect(await event1, isAddEvent('a.txt'));
52+
await queue1.cancel(immediate: true);
53+
54+
// Open before "ready", cancel before event.
55+
final queue2a = StreamQueue(watcher.events);
56+
// Open before "ready", cancel after one event.
57+
final queue2b = StreamQueue(watcher.events);
58+
// Open before "ready", cancel after two events.
59+
final queue2c = StreamQueue(watcher.events);
60+
61+
unawaited(queue2a.cancel(immediate: true));
62+
63+
await watcher.ready;
64+
65+
// Open after "ready", cancel before event.
66+
final queue2d = StreamQueue(watcher.events);
67+
68+
// Open after "ready", cancel after one event.
69+
final queue2e = StreamQueue(watcher.events);
70+
71+
// Open after "ready", cancel after two events.
72+
final queue2f = StreamQueue(watcher.events);
73+
74+
unawaited(queue2d.cancel(immediate: true));
75+
76+
writeFile('b.txt');
77+
78+
expect(await queue2b.next, isAddEvent('b.txt'));
79+
expect(await queue2c.next, isAddEvent('b.txt'));
80+
expect(await queue2e.next, isAddEvent('b.txt'));
81+
expect(await queue2f.next, isAddEvent('b.txt'));
82+
await queue2b.cancel(immediate: true);
83+
await queue2e.cancel(immediate: true);
84+
85+
// Remaining subscriptions still get events.
86+
writeFile('c.txt');
87+
expect(await queue2c.next, isAddEvent('c.txt'));
88+
expect(await queue2f.next, isAddEvent('c.txt'));
89+
90+
// New subscriber gets events without waiting for "ready" because the
91+
// underlying "watch" is still running.
92+
final queue2g = StreamQueue(watcher.events);
93+
writeFile('d.txt');
94+
expect(await queue2g.next, isAddEvent('d.txt'));
95+
96+
// Close all the subscriptions.
97+
await queue2c.cancel(immediate: true);
98+
await queue2f.cancel(immediate: true);
99+
await queue2g.cancel(immediate: true);
100+
101+
// Open another subscription. This time it does not get events from before
102+
// "ready" because the underlying "watch" was closed.
103+
final queue3 = StreamQueue(watcher.events);
104+
writeFile('e.txt');
105+
await watcher.ready;
106+
writeFile('f.txt');
107+
expect(await queue3.next, isAddEvent('f.txt'));
108+
await queue3.cancel(immediate: true);
109+
});
110+
37111
test('does not notify for files that already exist when started', () async {
38112
// Make some pre-existing files.
39113
writeFile('a.txt');

0 commit comments

Comments
 (0)