anchor.diff:                  //        (I tested this on Ubuntu WSL2 only)
                   System.Threading.Thread.Sleep(oneSecond)
   
  -                File.WriteAllText(newFilePath, "")
  -                File.WriteAllText(changedFilePath, "changed content")
  +                File.WriteAllText(newFilePath, "content")
  +                File.WriteAllText(changedFilePath, "new content")
                   File.Delete(deletedFilePath)
                   File.Move(srcForRenamedFilePath, dstForRenamedFilePath)
   
  +                let mutable error = None
                   try
  -                    do! Async.TimeoutAfter(defaultTimeout, tcs.Task) |> Async.AwaitTaskUnwrappingException |> Async.Ignore
  -                with | :? TimeoutException as ex -> failtest $"Got {filesChanged.Count} of the expected {allExpectedChanges.Length} events. {ex.Message}"
  -
  -                // Note: the polling watcher currently returns changes for directories when
  -                // their last write time is modified. This means we get a change for the sub-directory itself
  -                // (creating a file inside a directory changes its last write time)
  -                // This does not seem to be a problem...
  -                Expect.containsAll filesChanged allExpectedChanges ""
  -            }
  -
  -        "No event if disabled",
  +                    do! Async.TimeoutAfter(negativeTimeout, tcs.Task) |> Async.AwaitTaskUnwrappingException |> Async.Ignore
  +                with | ex -> error <- Some ex
  +
  +                match error with
  +                | None -> failtest $"The watcher detected {filesChanged.Count} change(s)!"
  +                | Some ex ->
  +                    match ex with
  +                    | :? TimeoutException -> () // Expected
  +                    | ex -> failtest $"Expected a timeout but got {ex}"
  +            }
  +
  +        "No event if disposed",
           fun usePolling tempFolder ->
               async {
                   let newFilePath = Path.Combine(tempFolder, "newFile")
  
positive.code:                 Expect.containsAll filesChanged [ srcFile; dstFile ] ""
              }
  
          "Files in sub-directory",
          fun usePolling tempFolder ->
              async {
                  let subDirPath = Path.Combine(tempFolder, "subdir")
                  Directory.CreateDirectory(subDirPath) |> ignore
  
                  let newFilePath = Path.Combine(subDirPath, "newFile")
                  let changedFilePath = Path.Combine(subDirPath, "changedFile")
                  let deletedFilePath = Path.Combine(subDirPath, "deletedFile")
                  let srcForRenamedFilePath = Path.Combine(subDirPath, "srcForRenamedFile")
                  let dstForRenamedFilePath = Path.Combine(subDirPath, "dstForRenamedFile")
  
                  File.WriteAllText(changedFilePath, "content")
                  File.WriteAllText(deletedFilePath, "content")
                  File.WriteAllText(srcForRenamedFilePath, "content")
  
                  let allExpectedChanges = [
                      newFilePath
                      changedFilePath
                      deletedFilePath
                      srcForRenamedFilePath
                      dstForRenamedFilePath
                      ]
  
                  use watcher = createWatcher tempFolder usePolling []
                  let tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously)
                  let filesChanged = new HashSet<string>()
  
                  let onFileChange = fun path ->
                      filesChanged.Add(path) |> ignore
                      if filesChanged.Count >= allExpectedChanges.Length
                      then tcs.TrySetResult(true) |> ignore
  
                  watcher.OnFileChange.Subscribe(onFileChange) |> ignore
                  watcher.OnError.Subscribe(fun err -> printfn "Watcher error: %A" <| err.GetException()) |> ignore
                  watcher.EnableRaisingEvents <- true
  
                  // On Unix the file write time is in 1s increments;
                  // if we don't wait, there's a chance that the polling
  
negative.code:                     | ex -> failtest $"Expected a timeout but got {ex}"
              }
  
          "Delete sub-directory",
          fun usePolling tempFolder ->
              async {
  