From df3996643f85624d7a3a09a9d7d7d36baa7b887d Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 14 Aug 2026 19:24:54 +1000 Subject: [PATCH] cleanup --- src/DiffEngine/Inline/RuntimeMoniker.cs | 4 +++- src/DiffEngine/Viewer/ImageExtensions.cs | 2 +- .../TrackerTrackedFilesTest.cs | 12 ++++++------ src/DiffEngineTray.Tests/TrayViewerSyncTest.cs | 18 ++++++++---------- .../AttachedViewerTests.cs | 10 +++++----- src/DiffEngineViewer.Tests/GlobalUsings.cs | 2 ++ src/DiffEngineViewer.Tests/ImageHeaderTests.cs | 2 -- src/DiffEngineViewer.Tests/ImageScreenTests.cs | 4 ++-- src/DiffEngineViewer.Tests/SamplePng.cs | 4 ---- .../ViewerLaunchTests.cs | 2 +- .../GlobalUsings.cs | 2 ++ .../ImageCacheTests.cs | 2 +- src/DiffEngineViewer/Images/ImageHeader.cs | 3 +-- src/DiffEngineViewer/Images/ImageRows.cs | 2 +- src/DiffEngineViewer/RevealFile.cs | 2 -- src/DiffEngineViewer/ViewerProgram.cs | 3 +-- 16 files changed, 34 insertions(+), 40 deletions(-) create mode 100644 src/DiffEngineViewer.Windows.Tests/GlobalUsings.cs diff --git a/src/DiffEngine/Inline/RuntimeMoniker.cs b/src/DiffEngine/Inline/RuntimeMoniker.cs index e8e2ca11..f2a5c87e 100644 --- a/src/DiffEngine/Inline/RuntimeMoniker.cs +++ b/src/DiffEngine/Inline/RuntimeMoniker.cs @@ -27,6 +27,7 @@ static class RuntimeMoniker return null; } + // ReSharper disable once RedundantSuppressNullableWarningExpression var parts = frameworkName!.Split(','); var identifier = parts[0].Trim(); string? versionText = null; @@ -35,7 +36,7 @@ static class RuntimeMoniker var part = parts[index].Trim(); if (part.StartsWith("Version=v", StringComparison.Ordinal)) { - versionText = part.Substring("Version=v".Length); + versionText = part["Version=v".Length..]; break; } } @@ -52,6 +53,7 @@ static class RuntimeMoniker ".NETCoreApp" when version.Major >= 5 => $"net{version.Major}.{minor}", ".NETCoreApp" => $"netcoreapp{version.Major}.{minor}", // "4.6.2" reads as net462, matching how TFMs are written. + // ReSharper disable once RedundantSuppressNullableWarningExpression ".NETFramework" => "net" + versionText!.Replace(".", ""), ".NETStandard" => $"netstandard{version.Major}.{minor}", _ => null diff --git a/src/DiffEngine/Viewer/ImageExtensions.cs b/src/DiffEngine/Viewer/ImageExtensions.cs index 2c75ee8d..70f11ff4 100644 --- a/src/DiffEngine/Viewer/ImageExtensions.cs +++ b/src/DiffEngine/Viewer/ImageExtensions.cs @@ -26,7 +26,7 @@ static class ImageExtensions ".webp" ]; - static readonly HashSet lookup = new(All, StringComparer.OrdinalIgnoreCase); + static readonly HashSet lookup = [with(All, StringComparer.OrdinalIgnoreCase)]; public static bool Is(string path) => lookup.Contains(Path.GetExtension(path)); diff --git a/src/DiffEngineTray.Tests/TrackerTrackedFilesTest.cs b/src/DiffEngineTray.Tests/TrackerTrackedFilesTest.cs index a53c3b08..7c3c574c 100644 --- a/src/DiffEngineTray.Tests/TrackerTrackedFilesTest.cs +++ b/src/DiffEngineTray.Tests/TrackerTrackedFilesTest.cs @@ -66,13 +66,13 @@ public async Task AcceptingATrackedMoveMovesTheFile() { await using var tracker = new RecordingTracker(); ITrackedFiles tracked = tracker; - File.WriteAllText(temp, "content"); + await File.WriteAllTextAsync(temp, "content"); tracker.AddMove(temp, target, null, null, false, null); var (ok, _) = tracked.Accept(TrackedKeys.ForMove(temp)); await Assert.That(ok).IsTrue(); - await Assert.That(File.ReadAllText(target)).IsEqualTo("content"); + await Assert.That(await File.ReadAllTextAsync(target)).IsEqualTo("content"); await Assert.That(tracker.Moves).IsEmpty(); } @@ -86,7 +86,7 @@ public async Task ALockedMoveIsRefusedWithoutPrompting() await using var tracker = new RecordingTracker( lockedFilesResolver: (_, _) => throw new("must not prompt")); ITrackedFiles tracked = tracker; - File.WriteAllText(temp, "content"); + await File.WriteAllTextAsync(temp, "content"); tracker.AddMove(temp, target, null, null, false, null); using (new FileStream(target, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) { @@ -115,7 +115,7 @@ public async Task AcceptAllSweepsAndCountsWhatStayed() await using var tracker = new RecordingTracker(); ITrackedFiles tracked = tracker; tracker.AddDelete(file); - File.WriteAllText(temp, "content"); + await File.WriteAllTextAsync(temp, "content"); tracker.AddMove(temp, target, null, null, false, null); var (accepted, kept) = tracked.AcceptAll(); @@ -123,7 +123,7 @@ public async Task AcceptAllSweepsAndCountsWhatStayed() await Assert.That(accepted).IsEqualTo(2); await Assert.That(kept).IsEqualTo(0); await Assert.That(File.Exists(file)).IsFalse(); - await Assert.That(File.ReadAllText(target)).IsEqualTo("content"); + await Assert.That(await File.ReadAllTextAsync(target)).IsEqualTo("content"); } [Test] @@ -132,7 +132,7 @@ public async Task DiscardAllUntracksDeletesAndDropsMoveTemps() await using var tracker = new RecordingTracker(); ITrackedFiles tracked = tracker; tracker.AddDelete(file); - File.WriteAllText(temp, "content"); + await File.WriteAllTextAsync(temp, "content"); tracker.AddMove(temp, target, null, null, false, null); var count = tracked.DiscardAll(); diff --git a/src/DiffEngineTray.Tests/TrayViewerSyncTest.cs b/src/DiffEngineTray.Tests/TrayViewerSyncTest.cs index d70b50fc..b1b4977e 100644 --- a/src/DiffEngineTray.Tests/TrayViewerSyncTest.cs +++ b/src/DiffEngineTray.Tests/TrayViewerSyncTest.cs @@ -1,7 +1,5 @@ extern alias viewer; -using System.Collections.Concurrent; - // The viewer's own copies of the protocol types. DiffEngineViewer links DiffEngine's Inline and // Protocol sources rather than referencing them, so the same names exist in both assemblies and // only the alias tells them apart. That duplication is the point of these tests: the two halves @@ -130,7 +128,7 @@ public async Task TrayAcceptOfATrackedMoveReachesTheAttachedViewer() pair.Tracker.Accept(pair.Tracker.Moves.Single()); await Assert.That(pair.Pump().Keys()).IsEquivalentTo([Key(sample, 1)]); - await Assert.That(File.ReadAllText(move.Target)).IsEqualTo("received"); + await Assert.That(await File.ReadAllTextAsync(move.Target)).IsEqualTo("received"); } [Test] @@ -186,7 +184,7 @@ public async Task ViewerAcceptAllEmptiesTheTray() await Assert.That(pair.Tracker.Snapshots).IsEmpty(); await Assert.That(pair.Tracker.Moves).IsEmpty(); await Assert.That(pair.Tracker.Deletes).IsEmpty(); - await Assert.That(File.ReadAllText(move.Target)).IsEqualTo("received"); + await Assert.That(await File.ReadAllTextAsync(move.Target)).IsEqualTo("received"); await Assert.That(File.Exists(delete.File)).IsFalse(); } @@ -250,7 +248,7 @@ public async Task ViewerAcceptOfATrackedMoveReachesTheTray() await Assert.That(pair.Pump().Keys()).IsEquivalentTo([Key(sample, 1)]); await Assert.That(pair.Tracker.Moves).IsEmpty(); - await Assert.That(File.ReadAllText(move.Target)).IsEqualTo("received"); + await Assert.That(await File.ReadAllTextAsync(move.Target)).IsEqualTo("received"); } /// @@ -493,7 +491,7 @@ public async Task ADeleteWithNoTrayReachesTheViewerAndTheFileGoes() using var noTray = new NoTray(); var file = pair.StageStaleFile(); - DiffRunner.AddDelete(file); + await DiffRunner.AddDeleteAsync(file); await Assert.That(pair.Viewer.Keys()).IsEquivalentTo([TrackedKeys.ForDelete(file)]); @@ -535,7 +533,7 @@ public async Task AMoveWithNoTrayReachesTheViewerAndTheFileMoves() pair.Act(CommandKind.Accept, move.Key); - await Assert.That(File.ReadAllText(move.Target)).IsEqualTo("received"); + await Assert.That(await File.ReadAllTextAsync(move.Target)).IsEqualTo("received"); await Assert.That(File.Exists(move.Temp)).IsFalse(); } @@ -564,7 +562,7 @@ public async Task AResentMoveReplacesItsEntry() var move = pair.StageMove(); PendingFiles.AddMove(move.Temp, move.Target, null, null, false, null); - File.WriteAllText(move.Temp, "second run"); + await File.WriteAllTextAsync(move.Temp, "second run"); PendingFiles.AddMove(move.Temp, move.Target, null, null, false, null); await Assert.That(pair.Viewer.Queue).HasSingleItem(); @@ -581,7 +579,7 @@ public async Task AFullListingCarriesTheViewersOwnPendingFiles() await using var pair = new ViewerOwned(); using var noTray = new NoTray(); var file = pair.StageStaleFile(); - DiffRunner.AddDelete(file); + await DiffRunner.AddDeleteAsync(file); var full = pair.Send(new(ViewerVerb.ListFull)); var plain = pair.Send(new(ViewerVerb.List)); @@ -801,7 +799,7 @@ public ViewerOwned(Func? applier = null) previousPort = Environment.GetEnvironmentVariable(ViewerClient.PortVariable); Environment.SetEnvironmentVariable(ViewerClient.PortVariable, server.Port.ToString()); Window = new(SessionState.Start(ViewerMode.Inline)); - actions = new ViewerActions( + actions = new( patch => { Applied.Add(patch); diff --git a/src/DiffEngineViewer.Tests/AttachedViewerTests.cs b/src/DiffEngineViewer.Tests/AttachedViewerTests.cs index 618a8808..bc026efd 100644 --- a/src/DiffEngineViewer.Tests/AttachedViewerTests.cs +++ b/src/DiffEngineViewer.Tests/AttachedViewerTests.cs @@ -221,8 +221,8 @@ public async Task MoveAndDeleteLinesMaterialize() { var temp = Path.Combine(Path.GetTempPath(), $"deview_{Guid.NewGuid():N}.received.txt"); var target = Path.Combine(Path.GetTempPath(), $"deview_{Guid.NewGuid():N}.verified.txt"); - File.WriteAllText(temp, "incoming"); - File.WriteAllText(target, "committed"); + await File.WriteAllTextAsync(temp, "incoming"); + await File.WriteAllTextAsync(target, "committed"); try { var (server, cancel) = Listing(() => ViewerResponse.Listing( @@ -260,7 +260,7 @@ public async Task MoveAndDeleteLinesMaterialize() public async Task AnUnreadableFileDegradesNotCrashes() { var file = Path.Combine(Path.GetTempPath(), $"deview_{Guid.NewGuid():N}.verified.txt"); - File.WriteAllText(file, "locked away"); + await File.WriteAllTextAsync(file, "locked away"); try { using var holder = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.None); @@ -294,7 +294,7 @@ public async Task AnUnreadableFileDegradesNotCrashes() public async Task UnchangedFilesAreNotReReadAndAChangeRefreshes() { var file = Path.Combine(Path.GetTempPath(), $"deview_{Guid.NewGuid():N}.verified.txt"); - File.WriteAllText(file, "first"); + await File.WriteAllTextAsync(file, "first"); try { var (server, cancel) = Listing(() => ViewerResponse.Listing( @@ -312,7 +312,7 @@ public async Task UnchangedFilesAreNotReReadAndAChangeRefreshes() await Assert.That(host.State.Queue.Single()).IsSameReferenceAs(first); // A stamp needs a distinct write time; length changing makes it deterministic. - File.WriteAllText(file, "second, longer"); + await File.WriteAllTextAsync(file, "second, longer"); link.Pump(); await Assert.That(host.State.Queue.Single().RightText).IsEqualTo("second, longer"); await cancel.CancelAsync(); diff --git a/src/DiffEngineViewer.Tests/GlobalUsings.cs b/src/DiffEngineViewer.Tests/GlobalUsings.cs index 4b2b3d77..d03ab28e 100644 --- a/src/DiffEngineViewer.Tests/GlobalUsings.cs +++ b/src/DiffEngineViewer.Tests/GlobalUsings.cs @@ -1 +1,3 @@ global using System.Text.RegularExpressions; +global using System.Buffers.Binary; +global using System.IO.Compression; \ No newline at end of file diff --git a/src/DiffEngineViewer.Tests/ImageHeaderTests.cs b/src/DiffEngineViewer.Tests/ImageHeaderTests.cs index ee8f3b34..dc4ae5eb 100644 --- a/src/DiffEngineViewer.Tests/ImageHeaderTests.cs +++ b/src/DiffEngineViewer.Tests/ImageHeaderTests.cs @@ -1,5 +1,3 @@ -using System.Buffers.Binary; - /// /// What the sniffer makes of each format's leading bytes. /// diff --git a/src/DiffEngineViewer.Tests/ImageScreenTests.cs b/src/DiffEngineViewer.Tests/ImageScreenTests.cs index 76b5f463..a5b7a82f 100644 --- a/src/DiffEngineViewer.Tests/ImageScreenTests.cs +++ b/src/DiffEngineViewer.Tests/ImageScreenTests.cs @@ -99,8 +99,8 @@ public Task DeleteInQueue() => public async Task PanesCarryThePicture() { var screen = ScreenBuilder.Build(State(Received(), Expected())); - await Assert.That(screen.Left.Image).IsEqualTo(new ImagePane("temp/sample.received.png", 800, 600)); - await Assert.That(screen.Right.Image).IsEqualTo(new ImagePane("code/sample.verified.png", 800, 600)); + await Assert.That(screen.Left.Image).IsEqualTo(new("temp/sample.received.png", 800, 600)); + await Assert.That(screen.Right.Image).IsEqualTo(new("code/sample.verified.png", 800, 600)); } [Test] diff --git a/src/DiffEngineViewer.Tests/SamplePng.cs b/src/DiffEngineViewer.Tests/SamplePng.cs index 0f58d8b2..99dfbb64 100644 --- a/src/DiffEngineViewer.Tests/SamplePng.cs +++ b/src/DiffEngineViewer.Tests/SamplePng.cs @@ -1,7 +1,3 @@ -using System.Buffers.Binary; -using System.IO.Compression; -using System.Text; - /// /// A real, decodable PNG built byte by byte. /// diff --git a/src/DiffEngineViewer.Tests/ViewerLaunchTests.cs b/src/DiffEngineViewer.Tests/ViewerLaunchTests.cs index 5d95e4ab..d20cd7e0 100644 --- a/src/DiffEngineViewer.Tests/ViewerLaunchTests.cs +++ b/src/DiffEngineViewer.Tests/ViewerLaunchTests.cs @@ -326,7 +326,7 @@ public async Task GroupedQueue() "Accepting the conflicted entry writes the variant on screen", "Accept all skips the conflict and says 1 conflict needs review"); - foreach (var patch in new engine::DiffEngine.InlinePatch[] + foreach (var patch in new[] { new(grouped, 6, "\"old value\"", "first new") { diff --git a/src/DiffEngineViewer.Windows.Tests/GlobalUsings.cs b/src/DiffEngineViewer.Windows.Tests/GlobalUsings.cs new file mode 100644 index 00000000..0b4fd261 --- /dev/null +++ b/src/DiffEngineViewer.Windows.Tests/GlobalUsings.cs @@ -0,0 +1,2 @@ +global using System.Buffers.Binary; +global using System.IO.Compression; \ No newline at end of file diff --git a/src/DiffEngineViewer.Windows.Tests/ImageCacheTests.cs b/src/DiffEngineViewer.Windows.Tests/ImageCacheTests.cs index 3e295243..3368735a 100644 --- a/src/DiffEngineViewer.Windows.Tests/ImageCacheTests.cs +++ b/src/DiffEngineViewer.Windows.Tests/ImageCacheTests.cs @@ -50,7 +50,7 @@ public async Task RedecodesWhenTheFileChanges() // A different size, so the change is visible whatever the file system's timestamp // resolution turns out to be. - File.WriteAllBytes(path, SamplePng.Build(4, 4, 40, 200, 40)); + await File.WriteAllBytesAsync(path, SamplePng.Build(4, 4, 40, 200, 40)); await Assert.That(cache.Get(path)!.Width).IsEqualTo(4); } diff --git a/src/DiffEngineViewer/Images/ImageHeader.cs b/src/DiffEngineViewer/Images/ImageHeader.cs index 1cb83c6a..c50d5f80 100644 --- a/src/DiffEngineViewer/Images/ImageHeader.cs +++ b/src/DiffEngineViewer/Images/ImageHeader.cs @@ -83,8 +83,7 @@ static bool TryJpeg(ReadOnlySpan bytes, out ImageHeader header) continue; } - if (marker == 0x01 || - marker is >= 0xD0 and <= 0xD9) + if (marker is 0x01 or >= 0xD0 and <= 0xD9) { continue; } diff --git a/src/DiffEngineViewer/Images/ImageRows.cs b/src/DiffEngineViewer/Images/ImageRows.cs index 47b819c0..b918e600 100644 --- a/src/DiffEngineViewer/Images/ImageRows.cs +++ b/src/DiffEngineViewer/Images/ImageRows.cs @@ -59,7 +59,7 @@ static Row Cell(int number, string label, string? value, string? other, RowKind kind = value == other ? RowKind.Unchanged : RowKind.Modified; } - return new(number, kind, $"{label.PadRight(labelWidth)}{value}"); + return new(number, kind, $"{label,-labelWidth}{value}"); } static string? Format(ImageFile? image) diff --git a/src/DiffEngineViewer/RevealFile.cs b/src/DiffEngineViewer/RevealFile.cs index d8c716cd..7532e5d6 100644 --- a/src/DiffEngineViewer/RevealFile.cs +++ b/src/DiffEngineViewer/RevealFile.cs @@ -1,5 +1,3 @@ -using System.Diagnostics; - /// /// Shows a file in the platform's file manager. Best effort: revealing is a convenience beside /// the review, so a missing file manager or a deleted file degrades to nothing rather than an diff --git a/src/DiffEngineViewer/ViewerProgram.cs b/src/DiffEngineViewer/ViewerProgram.cs index 20c818c6..b1e05b31 100644 --- a/src/DiffEngineViewer/ViewerProgram.cs +++ b/src/DiffEngineViewer/ViewerProgram.cs @@ -314,8 +314,7 @@ static SessionState Apply(SessionState state, ViewerInput input, OwnerLink? link // resolve which item was chosen, so clearing first would swallow the command. And not when // a right-click opened another menu in the same frame, which is the dismissal's successor // rather than something to undo. - if (input.MenuClosed && - input.RightClickedQueueItem < 0 && + if (input is {MenuClosed: true, RightClickedQueueItem: < 0} && state.Menu is not null) { state = state with { Menu = null };