diff --git a/docs/diff-tool.custom.md b/docs/diff-tool.custom.md
index 073068bc..c49438b5 100644
--- a/docs/diff-tool.custom.md
+++ b/docs/diff-tool.custom.md
@@ -53,7 +53,7 @@ New tools are added to the top of the order, the last tool added will resolve be
```cs
await DiffRunner.LaunchAsync(tempFile, targetFile);
```
-snippet source | anchor
+snippet source | anchor
Alternatively the instance returned from `AddTool*` can be used to explicitly launch that tool.
diff --git a/readme.md b/readme.md
index 91212d86..017fb99a 100644
--- a/readme.md
+++ b/readme.md
@@ -108,7 +108,7 @@ A tool can be launched using the following:
```cs
await DiffRunner.LaunchAsync(tempFile, targetFile);
```
-snippet source | anchor
+snippet source | anchor
Note that this method will respect the above [difference behavior](/docs/diff-tool.md#detected-difference-behavior) in terms of Auto refresh and MDI behaviors.
@@ -123,7 +123,7 @@ A tool can be closed using the following:
```cs
DiffRunner.Kill(file1, file2);
```
-snippet source | anchor
+snippet source | anchor
Note that this method will respect the above [difference behavior](/docs/diff-tool.md#detected-difference-behavior) in terms of MDI behavior.
diff --git a/src/DiffEngine.Tests/DiffRunnerTests.cs b/src/DiffEngine.Tests/DiffRunnerTests.cs
index 5a0af685..0c179866 100644
--- a/src/DiffEngine.Tests/DiffRunnerTests.cs
+++ b/src/DiffEngine.Tests/DiffRunnerTests.cs
@@ -7,6 +7,28 @@ public class DiffRunnerTests
static string SourceDirectory { get; } = Path.GetDirectoryName(GetSourceFile())!;
static string GetSourceFile([CallerFilePath] string path = "") => path;
+ // Launching registers a real pending move of file1 over file2 with whatever owns the queue on
+ // this machine, usually the developer's tray. Accepting it moves file1, and discarding it
+ // deletes file1 and then its directory. Run against the source directory that quietly destroys
+ // the checked in fixtures, so the tests get copies instead.
+ // One directory for the whole class, because IsRunning matches the exact command string and
+ // WaitForRunning is also used at test start to wait out the previous test's kill, both of which
+ // want the same paths across tests. Fresh per run, so a FakeDiffTool left behind by a crashed
+ // earlier run cannot match this run's command.
+ static string TempDirectory { get; } = Path.Combine(
+ Path.GetTempPath(),
+ "DiffEngine.DiffRunnerTests",
+ Guid.NewGuid().ToString("N"));
+
+ [After(Class)]
+ public static void DeleteTempDirectory()
+ {
+ if (Directory.Exists(TempDirectory))
+ {
+ Directory.Delete(TempDirectory, true);
+ }
+ }
+
static ResolvedTool tool;
string file2;
string file1;
@@ -216,11 +238,21 @@ async Task WaitForRunning(bool expected)
public DiffRunnerTests()
{
- file1 = Path.Combine(SourceDirectory, "DiffRunner.file1.txt");
- file2 = Path.Combine(SourceDirectory, "DiffRunner.file2.txt");
+ file1 = CopyFixture("DiffRunner.file1.txt");
+ file2 = CopyFixture("DiffRunner.file2.txt");
command = tool.BuildCommand(file1, file2);
}
+ // Per test rather than per class: a discard deletes the temp file and its directory, so the
+ // copies have to be put back for the test that follows.
+ static string CopyFixture(string name)
+ {
+ Directory.CreateDirectory(TempDirectory);
+ var target = Path.Combine(TempDirectory, name);
+ File.Copy(Path.Combine(SourceDirectory, name), target, true);
+ return target;
+ }
+
static DiffRunnerTests() =>
tool = DiffTools.AddTool(
name: "FakeDiffTool",
diff --git a/src/DiffEngine.Tests/ModuleInitializer.cs b/src/DiffEngine.Tests/ModuleInitializer.cs
index b9205d43..6d65819b 100644
--- a/src/DiffEngine.Tests/ModuleInitializer.cs
+++ b/src/DiffEngine.Tests/ModuleInitializer.cs
@@ -1,4 +1,10 @@
-public static class ModuleInitializer
+// DiffEngineTray is the obsolete public shim, but its IsRunning is still where the tray check lives.
+#pragma warning disable CS0618
+
+using System.Net;
+using System.Net.Sockets;
+
+public static class ModuleInitializer
{
[ModuleInitializer]
public static void Initialize()
@@ -6,5 +12,33 @@ public static void Initialize()
FileExtensions.AddTextFileConvention(_ => _.EndsWith(".txtConvention".AsSpan()));
Logging.Enable();
DiffRunner.Disabled = false;
+ DetachFromPendingFileSurfaces();
+ }
+
+ ///
+ /// Launching sends a real pending move to whatever owns the queue on this machine. On a
+ /// developer box that is the tray, started at login, and an accept or discard from it kills the
+ /// diff tool process DiffRunnerTests is asserting on. Being inconclusive when a tray is running
+ /// would mean those tests never run locally, so cut both routes instead: no tray, and a viewer
+ /// port nothing is listening on.
+ ///
+ /// A failed move send is the end of the road in PendingFiles.AddMove, and only a delete
+ /// launches a viewer, which nothing here adds. So the moves these tests produce go nowhere and
+ /// no process outside the test can see them.
+ ///
+ ///
+ /// The cost is that the real piper send is not covered from here. That belongs with a tray
+ /// under test control, which is what DiffEngineTray.Tests/DiffRunnerCanKillTest does.
+ ///
+ ///
+ static void DetachFromPendingFileSurfaces()
+ {
+ DiffEngineTray.IsRunning = false;
+
+ var listener = new TcpListener(IPAddress.Loopback, 0);
+ listener.Start();
+ var port = ((IPEndPoint) listener.LocalEndpoint).Port;
+ listener.Stop();
+ Environment.SetEnvironmentVariable(ViewerClient.PortVariable, port.ToString());
}
}