|
2 | 2 | // for details. All rights reserved. Use of this source code is governed by a |
3 | 3 | // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
|
| 5 | +import 'dart:async'; |
5 | 6 | import 'dart:io' as io; |
6 | 7 | import 'dart:io'; |
7 | 8 | import 'dart:isolate'; |
8 | 9 |
|
| 10 | +import 'package:async/async.dart'; |
9 | 11 | import 'package:test/test.dart'; |
10 | 12 | import 'package:test_descriptor/test_descriptor.dart' as d; |
11 | 13 | import 'package:watcher/src/utils.dart'; |
@@ -34,6 +36,79 @@ void _fileTests({required bool isNative}) { |
34 | 36 | } |
35 | 37 | }); |
36 | 38 |
|
| 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 then close it. |
| 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 | + final queue2aHasNext = queue2a.hasNext; |
| 62 | + unawaited(queue2a.cancel(immediate: true)); |
| 63 | + expect(await queue2aHasNext, false); |
| 64 | + |
| 65 | + await watcher.ready; |
| 66 | + |
| 67 | + // Open after "ready", cancel before event. |
| 68 | + final queue2d = StreamQueue(watcher.events); |
| 69 | + |
| 70 | + // Open after "ready", cancel after one event. |
| 71 | + final queue2e = StreamQueue(watcher.events); |
| 72 | + |
| 73 | + // Open after "ready", cancel after two events. |
| 74 | + final queue2f = StreamQueue(watcher.events); |
| 75 | + |
| 76 | + unawaited(queue2d.cancel(immediate: true)); |
| 77 | + |
| 78 | + writeFile('b.txt'); |
| 79 | + |
| 80 | + expect(await queue2b.next, isAddEvent('b.txt')); |
| 81 | + expect(await queue2c.next, isAddEvent('b.txt')); |
| 82 | + expect(await queue2e.next, isAddEvent('b.txt')); |
| 83 | + expect(await queue2f.next, isAddEvent('b.txt')); |
| 84 | + final queue2bHasNext = queue2b.hasNext; |
| 85 | + await queue2b.cancel(immediate: true); |
| 86 | + expect(await queue2bHasNext, false); |
| 87 | + final queue2eHasNext = queue2e.hasNext; |
| 88 | + await queue2e.cancel(immediate: true); |
| 89 | + expect(await queue2eHasNext, false); |
| 90 | + |
| 91 | + // Remaining subscriptions still get events. |
| 92 | + writeFile('c.txt'); |
| 93 | + expect(await queue2c.next, isAddEvent('c.txt')); |
| 94 | + expect(await queue2f.next, isAddEvent('c.txt')); |
| 95 | + final queue2cHasNext = queue2c.hasNext; |
| 96 | + await queue2c.cancel(immediate: true); |
| 97 | + expect(await queue2cHasNext, false); |
| 98 | + final queue2fHasNext = queue2f.hasNext; |
| 99 | + await queue2f.cancel(immediate: true); |
| 100 | + expect(await queue2fHasNext, false); |
| 101 | + |
| 102 | + // Repeat the first simple test: one subscription then close it. |
| 103 | + final queue3 = StreamQueue(watcher.events); |
| 104 | + await watcher.ready; |
| 105 | + writeFile('d.txt'); |
| 106 | + expect(await queue3.next, isAddEvent('d.txt')); |
| 107 | + final queue3HasNext = queue3.hasNext; |
| 108 | + await queue3.cancel(immediate: true); |
| 109 | + expect(await queue3HasNext, false); |
| 110 | + }); |
| 111 | + |
37 | 112 | test('does not notify for files that already exist when started', () async { |
38 | 113 | // Make some pre-existing files. |
39 | 114 | writeFile('a.txt'); |
|
0 commit comments