Add/enable Windows tests (dart-lang/watcher#124)

diff --git a/pkgs/watcher/test/directory_watcher/shared.dart b/pkgs/watcher/test/directory_watcher/shared.dart
index ebce488..07fbf9c 100644
--- a/pkgs/watcher/test/directory_watcher/shared.dart
+++ b/pkgs/watcher/test/directory_watcher/shared.dart
@@ -134,6 +134,8 @@
 
       renameFile('from.txt', 'to.txt');
       await inAnyOrder([isRemoveEvent('from.txt'), isModifyEvent('to.txt')]);
+    }, onPlatform: {
+      'windows': Skip('https://github.com/dart-lang/watcher/issues/125')
     });
   });
 
@@ -276,7 +278,8 @@
         isAddEvent('new')
       ]);
     }, onPlatform: {
-      'mac-os': Skip('https://github.com/dart-lang/watcher/issues/21')
+      'mac-os': Skip('https://github.com/dart-lang/watcher/issues/21'),
+      'windows': Skip('https://github.com/dart-lang/watcher/issues/21')
     });
 
     test('emits events for many nested files added at once', () async {
diff --git a/pkgs/watcher/test/directory_watcher/windows_test.dart b/pkgs/watcher/test/directory_watcher/windows_test.dart
index 6ea412f..3ddb47e 100644
--- a/pkgs/watcher/test/directory_watcher/windows_test.dart
+++ b/pkgs/watcher/test/directory_watcher/windows_test.dart
@@ -14,11 +14,9 @@
 void main() {
   watcherFactory = (dir) => WindowsDirectoryWatcher(dir);
 
-  // TODO(grouma) - renable when https://github.com/dart-lang/sdk/issues/31760
-  // is resolved.
   group('Shared Tests:', () {
     sharedTests();
-  }, skip: 'SDK issue see - https://github.com/dart-lang/sdk/issues/31760');
+  });
 
   test('DirectoryWatcher creates a WindowsDirectoryWatcher on Windows', () {
     expect(DirectoryWatcher('.'), TypeMatcher<WindowsDirectoryWatcher>());
diff --git a/pkgs/watcher/test/no_subscription/windows_test.dart b/pkgs/watcher/test/no_subscription/windows_test.dart
new file mode 100644
index 0000000..eb381d0
--- /dev/null
+++ b/pkgs/watcher/test/no_subscription/windows_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('windows')
+
+import 'package:test/test.dart';
+import 'package:watcher/src/directory_watcher/windows.dart';
+
+import 'shared.dart';
+import '../utils.dart';
+
+void main() {
+  watcherFactory = (dir) => WindowsDirectoryWatcher(dir);
+
+  sharedTests();
+}
diff --git a/pkgs/watcher/test/ready/shared.dart b/pkgs/watcher/test/ready/shared.dart
index 6578c52..d9bb5ae 100644
--- a/pkgs/watcher/test/ready/shared.dart
+++ b/pkgs/watcher/test/ready/shared.dart
@@ -21,19 +21,21 @@
     expect(ready, isFalse);
 
     // Subscribe to the events.
-    watcher.events.listen((event) {});
+    var subscription = watcher.events.listen((event) {});
 
     await watcher.ready;
 
     // Should eventually be ready.
     expect(watcher.isReady, isTrue);
+
+    await subscription.cancel();
   });
 
   test('ready completes immediately when already ready', () async {
     var watcher = createWatcher();
 
     // Subscribe to the events.
-    watcher.events.listen((event) {});
+    var subscription = watcher.events.listen((event) {});
 
     // Allow watcher to become ready
     await watcher.ready;
@@ -43,6 +45,8 @@
         watcher.ready.timeout(Duration(milliseconds: 0),
             onTimeout: () => throw 'Does not complete immedately'),
         completes);
+
+    await subscription.cancel();
   });
 
   test('ready returns a future that does not complete after unsubscribing',
diff --git a/pkgs/watcher/test/ready/windows_test.dart b/pkgs/watcher/test/ready/windows_test.dart
new file mode 100644
index 0000000..eb381d0
--- /dev/null
+++ b/pkgs/watcher/test/ready/windows_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('windows')
+
+import 'package:test/test.dart';
+import 'package:watcher/src/directory_watcher/windows.dart';
+
+import 'shared.dart';
+import '../utils.dart';
+
+void main() {
+  watcherFactory = (dir) => WindowsDirectoryWatcher(dir);
+
+  sharedTests();
+}
diff --git a/pkgs/watcher/test/utils.dart b/pkgs/watcher/test/utils.dart
index 8d8981c..23adcbc 100644
--- a/pkgs/watcher/test/utils.dart
+++ b/pkgs/watcher/test/utils.dart
@@ -48,6 +48,12 @@
 /// The stream of events from the watcher started with [startWatcher].
 late StreamQueue<WatchEvent> _watcherEvents;
 
+/// Whether the event stream has been closed.
+///
+/// If this is not done by a test (by calling [startClosingEventStream]) it will
+/// be done automatically via [addTearDown] in [startWatcher].
+var _hasClosedStream = true;
+
 /// Creates a new [Watcher] that watches a temporary file or directory and
 /// starts monitoring it for events.
 ///
@@ -70,6 +76,10 @@
   _watcherEvents = StreamQueue(watcher.events);
   // Forces a subscription to the underlying stream.
   unawaited(_watcherEvents.hasNext);
+
+  _hasClosedStream = false;
+  addTearDown(startClosingEventStream);
+
   await watcher.ready;
 }
 
@@ -80,6 +90,8 @@
 /// indefinitely because they might in the future and because the watcher is
 /// normally only closed after the test completes.
 void startClosingEventStream() async {
+  if (_hasClosedStream) return;
+  _hasClosedStream = true;
   await pumpEventQueue();
   await _watcherEvents.cancel(immediate: true);
 }