Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions src/DiffEngine.Tests/ExtensionCaseTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/// <summary>
/// Extensions are matched the way file systems produce them.
/// <para>
/// ExtensionLookup, PathLookup and BinaryExtensions all compared ordinally while every
/// registration is lowercase, so .PNG, .JPG and .Docx - which is exactly what Windows and macOS
/// hand back - matched nothing. The tool resolved for foo.png and not for foo.PNG.
/// Viewer/ImageExtensions already uses OrdinalIgnoreCase for the same kind of lookup.
/// </para>
/// </summary>
[NotInParallel]
public class ExtensionCaseTests
{
[Test]
public async Task ExtensionsResolveWhateverTheirCasing()
{
var extension = $".zz{Guid.NewGuid():N}";
var tool = DiffTools.AddTool(
name: $"CaseProbe{Guid.NewGuid():N}",
autoRefresh: false,
isMdi: false,
supportsText: false,
requiresTarget: true,
useShellExecute: false,
launchArguments: new(
Left: (temp, target) => $"\"{temp}\" \"{target}\"",
Right: (temp, target) => $"\"{target}\" \"{temp}\""),
exePath: Environment.ProcessPath!,
binaryExtensions: [extension]);

await Assert.That(tool).IsNotNull();

await Assert.That(DiffTools.TryFindByExtension(extension, out _)).IsTrue();
await Assert.That(DiffTools.TryFindByExtension(extension.ToUpperInvariant(), out _)).IsTrue();

await Assert.That(DiffTools.TryFindForInputFilePath($"file{extension.ToUpperInvariant()}", out _)).IsTrue();

await Assert.That(tool!.BinaryExtensions.Contains(extension.ToUpperInvariant())).IsTrue();
}
}
8 changes: 6 additions & 2 deletions src/DiffEngine/DiffTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

public static partial class DiffTools
{
static Dictionary<string, ResolvedTool> ExtensionLookup = [];
static Dictionary<string, ResolvedTool> PathLookup = [];
// Case insensitive, because the keys are file extensions and executable paths and the file
// systems that produce them are. An ordinal lookup meant .PNG, .JPG and .Docx - which is what
// Windows and macOS hand back - matched none of the lowercase registrations, so the tool
// resolved for foo.png and not for foo.PNG. Viewer/ImageExtensions already does this
static Dictionary<string, ResolvedTool> ExtensionLookup = new(StringComparer.OrdinalIgnoreCase);
static Dictionary<string, ResolvedTool> PathLookup = new(StringComparer.OrdinalIgnoreCase);
static Dictionary<DiffTool, ResolvedTool> ToolLookup = [];
static ResolvedTool? firstTextTool;
static List<ResolvedTool> resolved = [];
Expand Down
4 changes: 3 additions & 1 deletion src/DiffEngine/ResolvedTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ Extensions must begin with a period.
}
}

BinaryExtensions = binaryExtensions.ToFrozenSet();
// Case insensitive for the same reason ExtensionLookup is: a binary extension is compared
// against whatever casing the file system produced
BinaryExtensions = binaryExtensions.ToFrozenSet(StringComparer.OrdinalIgnoreCase);

RequiresTarget = requiresTarget;
SupportsText = supportsText;
Expand Down
Loading