Skip to content

Commit f01c11b

Browse files
authored
Show the snapshot an F# entry is anchored on (#827)
QueueEntry.Expected decided "new snapshot" from OriginalExpression being null and never looked at OriginalValue, which is the anchor a producer sends when its language does not implement CallerArgumentExpression. F# does not, so every F# entry opened with an empty expected pane and every received line marked as added - while the applier was anchoring on that same value and the staged expected.txt was written from it. It is the snapshot the expression would have parsed to, not source text: the patcher compares it against what a literal parses to, and against NewContent for an already-applied patch. So it goes in the pane as it is, under the plain "expected" header, and only a patch with neither anchor still reads as a new snapshot.
1 parent 535facb commit f01c11b

3 files changed

Lines changed: 88 additions & 1 deletion

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
+----------------------------------------------------------------------------------------------+
2+
| SampleTests.fs:42 inline 1 of 1 |
3+
+----------------------+-----------------------------------+-----------------------------------+
4+
| Pending (1) | received | expected |
5+
+----------------------+-----------------------------------+-----------------------------------+
6+
| > SampleTests.fs:42 | 1 the quick | 1 the quick |
7+
| | ~ 2 brown dog | ~ 2 brown fox |
8+
| | 3 jumps over | 3 jumps over |
9+
| | 4 the lazy | 4 the lazy |
10+
| | 5 dog | 5 dog |
11+
| | | |
12+
| | | |
13+
| | | |
14+
| | | |
15+
| | | |
16+
| | | |
17+
| | | |
18+
| | | |
19+
| | | |
20+
| | | |
21+
| | | |
22+
+----------------------+-----------------------------------+-----------------------------------+
23+
| [Accept] [Discard] [Accept all] lines 1-5 of 5 |
24+
+----------------------------------------------------------------------------------------------+
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/// <summary>
2+
/// An entry from a producer whose language does not implement CallerArgumentExpression, which is
3+
/// F#. There is no source text for the previous argument, so the patch carries its value instead -
4+
/// the same snapshot the expression would have parsed to, and the same anchor one parse further
5+
/// on.
6+
/// </summary>
7+
public class FsharpEntryTests
8+
{
9+
[Test]
10+
public async Task The_previous_snapshot_fills_the_expected_pane()
11+
{
12+
var state = Fixtures.Inline(Patch());
13+
14+
var entry = state.Queue[0];
15+
16+
await Assert.That(entry.RightHeader).IsEqualTo("expected");
17+
await Assert.That(entry.RightText).IsEqualTo(Fixtures.Expected);
18+
await Assert.That(entry.Warning).IsNull();
19+
}
20+
21+
/// <summary>
22+
/// With neither anchor there is genuinely nothing to compare against, which is what the empty
23+
/// side is for.
24+
/// </summary>
25+
[Test]
26+
public async Task A_first_run_still_reads_as_a_new_snapshot()
27+
{
28+
var state = Fixtures.Inline(
29+
new InlinePatch("SampleTests.fs", 42, null, Fixtures.Received)
30+
{
31+
TestName = null
32+
});
33+
34+
var entry = state.Queue[0];
35+
36+
await Assert.That(entry.RightHeader).IsEqualTo("expected (new snapshot)");
37+
await Assert.That(entry.RightText).IsEmpty();
38+
}
39+
40+
/// <summary>
41+
/// And what that looks like: two full panes with one line differing, rather than five added
42+
/// lines beside nothing.
43+
/// </summary>
44+
[Test]
45+
public Task Screen() =>
46+
Verify(Fixtures.Render(Fixtures.Inline(Patch())));
47+
48+
static InlinePatch Patch() =>
49+
new("SampleTests.fs", 42, null, Fixtures.Received)
50+
{
51+
TestName = null,
52+
OriginalValue = Fixtures.Expected
53+
};
54+
}

src/DiffEngineViewer/QueueEntry.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,16 @@ public static QueueEntry ForDelete(
198198
{
199199
if (patch.OriginalExpression is null)
200200
{
201-
return ("expected (new snapshot)", "", null);
201+
// A producer whose language has no CallerArgumentExpression - F#, which does not
202+
// implement it - anchors on the argument's value instead. It is the same snapshot the
203+
// expression would have parsed to, so it is the same pane; without this every F#
204+
// entry read as a new snapshot against an empty side, with every received line new.
205+
if (patch.OriginalValue is null)
206+
{
207+
return ("expected (new snapshot)", "", null);
208+
}
209+
210+
return ("expected", SourceLanguage.NormalizeNewlines(patch.OriginalValue), null);
202211
}
203212

204213
// Read as the language of the file it came out of: an F# literal is not a C# one, and a

0 commit comments

Comments
 (0)