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
27 changes: 27 additions & 0 deletions src/DiffEngine.Tests/InlineStagingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,33 @@ public async Task ClearRemovesEveryFrameworksTrio()
await Assert.That(project.StagedFiles()).IsEmpty();
}

/// <summary>
/// A settle that names the framework it came from takes only that framework's trio. The queue
/// has always scoped a settle this way; staging is the same situation and had no way to say
/// it, so in a net8;net10 run where net10 started passing and net8 did not, net10's settle
/// deleted net8's still-failing snapshot and it was then pending nowhere.
/// </summary>
[Test]
public async Task ClearScopedToAnOriginLeavesTheOtherFrameworkStaged()
{
using var project = new TempProject();
var source = project.Source("SampleTests.cs");
InlineStaging.Persist(
[
new(
[
new(Patch(source, "from net8", framework: "net8.0"), ["net8.0"]),
new(Patch(source, "from net10", framework: "net10.0"), ["net10.0"]),
])
]);

var cleared = InlineStaging.Clear(source, 42, null, origin: "net10.0");

await Assert.That(cleared).IsEqualTo(1);
// net8's trio is still there, and still reviewable
await Assert.That(project.StagedFiles().Count).IsEqualTo(3);
}

[Test]
public async Task ClearFindsACallSiteWhoseLineHasMovedByMember()
{
Expand Down
33 changes: 30 additions & 3 deletions src/DiffEngine/Inline/InlineStaging.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,34 @@ public static int Persist(IEnumerable<PendingInline> pending)
/// of its own. Verify's own fallback writes under the project's intermediate directory, which
/// is normally inside that <c>obj</c> and found anyway, but does not have to be.
/// </param>
public static int Clear(string sourceFile, int line, string? memberName, string? extraDirectory = null)
/// <param name="origin">
/// The framework moniker of the run that settled, which scopes the clear to that run's own
/// trio. This is what <see cref="InlineQueue.Settle(string, string?)" /> already does with a
/// queue, and staging is the same situation with the same answer: one call site stages one
/// trio per framework, so a multi-framework run where one framework starts passing and another
/// does not would otherwise have the passing one delete the failing one's staged snapshot.
/// <para>
/// Null clears every framework's trio for the call site, which is right for a retire - the
/// call site is not an inline snapshot in any framework any more - and is the behaviour of
/// every caller that does not pass this.
/// </para>
/// <para>
/// A trio staged without a framework label is cleared either way, since there is nothing to
/// scope it by and leaving it would strand it forever.
/// </para>
/// </param>
public static int Clear(string sourceFile, int line, string? memberName, string? extraDirectory = null, string? origin = null)
{
var cleared = 0;
foreach (var directory in StagingDirectories(sourceFile, extraDirectory))
{
cleared += ClearIn(directory, sourceFile, line, memberName);
cleared += ClearIn(directory, sourceFile, line, memberName, origin);
}

return cleared;
}

static int ClearIn(string directory, string sourceFile, int line, string? memberName)
static int ClearIn(string directory, string sourceFile, int line, string? memberName, string? origin)
{
var staged = ReadStaged(directory)
.Where(_ => SamePath(_.Patch.SourceFile, sourceFile))
Expand All @@ -111,6 +127,17 @@ static int ClearIn(string directory, string sourceFile, int line, string? member
}
}

if (origin != null)
{
// One call site stages one trio per framework, so a settle that names the framework it
// came from must take only that one. Without it a net9 run that started passing
// deleted net8's still-failing trio beside its own, and that snapshot was then pending
// nowhere: not staged, and not in a queue either, since nothing had one
matching = matching
.Where(_ => _.Patch.Framework == null || _.Patch.Framework == origin)
.ToList();
}

var cleared = 0;
foreach (var entry in matching)
{
Expand Down
Loading