Forge
csharpdeeb25a2
1#nullable enable
2
3using CascadeIDE.Models.Intercom;
4using CascadeIDE.Services.Intercom;
5using Xunit;
6
7namespace CascadeIDE.Tests;
8
9public sealed class IntercomMessageCodeCorrespondenceTests
10{
11 [Fact]
12 public void Find_OverlappingLineRanges_ReturnsOrdinal()
13 {
14 var lane = new[]
15 {
16 laneMessage(1, 0, attach("src/Foo.cs", 10, 20)),
17 laneMessage(2, 1, attach("src/Other.cs", 1, 5)),
18 };
19
20 var entries = IntercomMessageCodeCorrespondenceProjector.BuildInferred(lane);
21 var query = new IntercomCodeRefQuery("src/Foo.cs", 15, 18);
22 var hits = IntercomMessageCodeCorrespondenceProjector.Find(entries, query, workspaceRoot: null);
23
24 Assert.Single(hits);
25 Assert.Equal(1, hits[0].Ordinal);
26 }
27
28 [Fact]
29 public void Find_NonOverlapping_ReturnsEmpty()
30 {
31 var lane = new[] { laneMessage(1, 0, attach("src/Foo.cs", 10, 20)) };
32 var entries = IntercomMessageCodeCorrespondenceProjector.BuildInferred(lane);
33 var query = new IntercomCodeRefQuery("src/Foo.cs", 50, 60);
34 var hits = IntercomMessageCodeCorrespondenceProjector.Find(entries, query, null);
35
36 Assert.Empty(hits);
37 }
38
39 [Fact]
40 public void Find_FileOnlyQuery_MatchesAnchorWithoutLines()
41 {
42 var lane = new[] { laneMessage(1, 0, new AttachmentAnchor { File = "src/Bar.cs" }) };
43 var entries = IntercomMessageCodeCorrespondenceProjector.BuildInferred(lane);
44 var query = new IntercomCodeRefQuery("src/Bar.cs", null, null);
45 var hits = IntercomMessageCodeCorrespondenceProjector.Find(entries, query, null);
46
47 Assert.Single(hits);
48 }
49
50 [Fact]
51 public void Find_SameFileDifferentMemberKeys_MatchesByMemberOnly()
52 {
53 var lane = new[]
54 {
55 laneMessage(1, 0, attach("src/Foo.cs", 10, 20, "M:Foo.Bar")),
56 laneMessage(2, 1, attach("src/Foo.cs", 10, 20, "M:Foo.Baz")),
57 };
58
59 var entries = IntercomMessageCodeCorrespondenceProjector.BuildInferred(lane);
60 var query = IntercomCodeRefQuery.FromAnchor(new AttachmentAnchor
61 {
62 File = "src/Foo.cs",
63 LineStart = 99,
64 LineEnd = 99,
65 MemberKey = "M:Foo.Bar",
66 });
67 var hits = IntercomMessageCodeCorrespondenceProjector.Find(entries, query, null);
68
69 Assert.Single(hits);
70 Assert.Equal(1, hits[0].Ordinal);
71 }
72
73 [Fact]
74 public void TryParse_LineLiteral_RequiresActiveFile()
75 {
76 var editor = new IntercomAttachmentResolveAtSend.EditorSnapshot(null, "", null, null, null);
77 Assert.False(IntercomCodeRefParser.TryParse("L:10-20", editor, null, null, out _, out var err));
78 Assert.Contains("активного файла", err, StringComparison.Ordinal);
79 }
80
81 private static IntercomMessageCodeCorrespondenceProjector.LaneMessage laneMessage(
82 int ordinal,
83 int messageIndex,
84 params AttachmentAnchor[] attachments) =>
85 new(ordinal, messageIndex, Guid.NewGuid(), attachments);
86
87 private static AttachmentAnchor attach(string file, int start, int end, string? memberKey = null) =>
88 new()
89 {
90 File = file,
91 LineStart = start,
92 LineEnd = end,
93 MemberKey = memberKey,
94 AttachmentShape = memberKey is not null ? "member" : "text-range",
95 };
96}
97
View only · write via MCP/CIDE