Fix registerCustomWatcher to allow nulls (#107)

The idea behind the closures passed to `registerCustomWatcher` is that
they should return `null` if the particular implementation does not
support the provided path (in which case we should fallback to other
implementations).

Modified a test to check this.
diff --git a/lib/src/custom_watcher_factory.dart b/lib/src/custom_watcher_factory.dart
index 8f4132b..fc4e3fb 100644
--- a/lib/src/custom_watcher_factory.dart
+++ b/lib/src/custom_watcher_factory.dart
@@ -31,9 +31,9 @@
 /// will be used instead of the default.
 void registerCustomWatcher(
   String id,
-  DirectoryWatcher Function(String path, {Duration? pollingDelay})?
+  DirectoryWatcher? Function(String path, {Duration? pollingDelay})?
       createDirectoryWatcher,
-  FileWatcher Function(String path, {Duration? pollingDelay})?
+  FileWatcher? Function(String path, {Duration? pollingDelay})?
       createFileWatcher,
 ) {
   if (_customWatcherFactories.containsKey(id)) {
diff --git a/test/custom_watcher_factory_test.dart b/test/custom_watcher_factory_test.dart
index 89f8e3c..331d243 100644
--- a/test/custom_watcher_factory_test.dart
+++ b/test/custom_watcher_factory_test.dart
@@ -5,15 +5,21 @@
 
 void main() {
   late _MemFs memFs;
-  final defaultFactoryId = 'MemFs';
+  final memFsFactoryId = 'MemFs';
+  final noOpFactoryId = 'NoOp';
 
   setUpAll(() {
     memFs = _MemFs();
-    var watcherFactory = _MemFsWatcherFactory(memFs);
+    var memFsWatcherFactory = _MemFsWatcherFactory(memFs);
+    var noOpWatcherFactory = _NoOpWatcherFactory();
     registerCustomWatcher(
-        defaultFactoryId,
-        watcherFactory.createDirectoryWatcher,
-        watcherFactory.createFileWatcher);
+        noOpFactoryId,
+        noOpWatcherFactory.createDirectoryWatcher,
+        noOpWatcherFactory.createFileWatcher);
+    registerCustomWatcher(
+        memFsFactoryId,
+        memFsWatcherFactory.createDirectoryWatcher,
+        memFsWatcherFactory.createFileWatcher);
   });
 
   test('notifies for files', () async {
@@ -44,7 +50,7 @@
 
   test('registering twice throws', () async {
     expect(
-        () => registerCustomWatcher(defaultFactoryId,
+        () => registerCustomWatcher(memFsFactoryId,
             (_, {pollingDelay}) => throw 0, (_, {pollingDelay}) => throw 0),
         throwsA(isA<ArgumentError>()));
   });
@@ -116,10 +122,18 @@
   final _MemFs _memFs;
   _MemFsWatcherFactory(this._memFs);
 
-  DirectoryWatcher createDirectoryWatcher(String path,
+  DirectoryWatcher? createDirectoryWatcher(String path,
           {Duration? pollingDelay}) =>
       _MemFsWatcher(path, _memFs.watchStream(path));
 
-  FileWatcher createFileWatcher(String path, {Duration? pollingDelay}) =>
+  FileWatcher? createFileWatcher(String path, {Duration? pollingDelay}) =>
       _MemFsWatcher(path, _memFs.watchStream(path));
 }
+
+class _NoOpWatcherFactory {
+  DirectoryWatcher? createDirectoryWatcher(String path,
+          {Duration? pollingDelay}) =>
+      null;
+
+  FileWatcher? createFileWatcher(String path, {Duration? pollingDelay}) => null;
+}