diff --git a/src/DiffEngine.Tests/InlinePatcherTests.cs b/src/DiffEngine.Tests/InlinePatcherTests.cs index 6c7db593..a7c107c2 100644 --- a/src/DiffEngine.Tests/InlinePatcherTests.cs +++ b/src/DiffEngine.Tests/InlinePatcherTests.cs @@ -123,6 +123,27 @@ public async Task ASnapshotBeforeAVerbatimStringOpeningOnAnEscapedQuoteIsStillFo const string q3 = "\"\"\""; const string q4 = "\"\"\"\""; + /// + /// A comment between the argument and the closing paren. A line comment's span includes the + /// newline that ends it, so trimming trailing whitespace first ate that newline and the + /// comment then looked like part of the argument - which is not a string literal. + /// + [Test] + public async Task ATrailingCommentIsNotPartOfTheArgument() + { + var source = Method( + " await Snapshot(\"old\" // note\n" + + " );"); + + var status = TryApply(source, 5, InlinePatchMode.Set, "\"old\"", "new", out var newSource, out var reason); + + await Assert.That(status).IsEqualTo(PatchStatus.Applied); + await Assert.That(reason).IsEmpty(); + // The literal is replaced and the comment is left where it was, rather than being + // swallowed into the argument + await Assert.That(newSource).Contains("Snapshot(\"new\" // note"); + await Assert.That(newSource).DoesNotContain("\"old\""); + } [Test] public async Task ReplaceRegularLiteral() { diff --git a/src/DiffEngine/Inline/InlinePatcher.cs b/src/DiffEngine/Inline/InlinePatcher.cs index e44cace5..9eef3481 100644 --- a/src/DiffEngine/Inline/InlinePatcher.cs +++ b/src/DiffEngine/Inline/InlinePatcher.cs @@ -915,16 +915,19 @@ static void TrimSpan(string source, SourceScan scan, ref int start, ref int end) while (end > start) { - if (char.IsWhiteSpace(source[end - 1])) + // The comment is asked about before the whitespace, because a line comment's span + // includes the newline that ends it. Trimming first ate that newline, after which + // nothing ended at `end` any more and the comment stayed inside the argument + if (scan.TryGetCommentEndingAt(end, out var commentStart) && + commentStart >= start) { - end--; + end = commentStart; continue; } - if (scan.TryGetCommentEndingAt(end, out var commentStart) && - commentStart >= start) + if (char.IsWhiteSpace(source[end - 1])) { - end = commentStart; + end--; continue; }