Forge
csharpdeeb25a2
1#nullable enable
2
3using CascadeIDE.Features.Chat;
4using CascadeIDE.Models.Intercom;
5using CascadeIDE.Services;
6using CascadeIDE.Services.Intercom;
7using Xunit;
8
9namespace CascadeIDE.Tests;
10
11public sealed class IntercomAttachmentMessageBuilderTests
12{
13 [Fact]
14 public void TryBuild_replaces_bracket_with_marker_and_attachment()
15 {
16 var dir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), nameof(IntercomAttachmentMessageBuilderTests) + "_" + Guid.NewGuid().ToString("N"))).FullName;
17 var file = Path.Combine(dir, "Foo.cs");
18 File.WriteAllText(file, "class C { void Run() { } }");
19
20 var editor = new IntercomAttachmentResolveAtSend.EditorSnapshot(
21 file,
22 File.ReadAllText(file),
23 null,
24 null,
25 0);
26
27 Assert.True(
28 IntercomAttachmentMessageBuilder.TryBuild(
29 "see [M:Run]",
30 new Dictionary<string, AttachmentAnchor>(),
31 editor,
32 dir,
33 null,
34 out var outbound,
35 out var err),
36 err);
37
38 Assert.Contains("⟦a:", outbound.Content, StringComparison.Ordinal);
39 Assert.Single(outbound.Attachments);
40 Assert.Equal("Run", outbound.Attachments[0].MemberKey);
41 Assert.False(string.IsNullOrWhiteSpace(outbound.Attachments[0].Excerpt));
42 }
43
44 [Fact]
45 public void TryBuild_fails_when_member_key_not_in_file()
46 {
47 var dir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), nameof(IntercomAttachmentMessageBuilderTests) + "_fail_" + Guid.NewGuid().ToString("N"))).FullName;
48 var file = Path.Combine(dir, "Foo.cs");
49 File.WriteAllText(file, "class C { void Other() { } }");
50
51 var editor = new IntercomAttachmentResolveAtSend.EditorSnapshot(file, File.ReadAllText(file), null, null, 0);
52
53 Assert.False(
54 IntercomAttachmentMessageBuilder.TryBuild(
55 "see [M:Missing]",
56 new Dictionary<string, AttachmentAnchor>(),
57 editor,
58 dir,
59 null,
60 out _,
61 out var err));
62 Assert.Contains("Missing", err, StringComparison.Ordinal);
63 }
64
65 [Fact]
66 public void TryPrepare_degraded_when_member_key_not_in_file()
67 {
68 var dir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), nameof(IntercomAttachmentMessageBuilderTests) + "_deg_" + Guid.NewGuid().ToString("N"))).FullName;
69 var file = Path.Combine(dir, "Foo.cs");
70 File.WriteAllText(file, "class C { void Other() { } }");
71
72 var editor = new IntercomAttachmentResolveAtSend.EditorSnapshot(file, File.ReadAllText(file), null, null, 0);
73
74 Assert.True(
75 IntercomAttachmentMessageBuilder.TryPrepare(
76 "see [M:Missing]",
77 new Dictionary<string, AttachmentAnchor>(),
78 editor,
79 dir,
80 null,
81 out var prepared));
82
83 Assert.Equal(IntercomMessagePrepareStatus.PartialSuccess, prepared.Status);
84 Assert.True(prepared.IsCommittable);
85 Assert.Contains("⟦a:", prepared.Outbound.Content, StringComparison.Ordinal);
86 Assert.Single(prepared.Outbound.Attachments);
87 Assert.Equal("Missing", prepared.Outbound.Attachments[0].MemberKey);
88 }
89
90 [Fact]
91 public void TryPrepareForMcp_fast_path_preserves_L_without_excerpt_and_defers_M()
92 {
93 var dir = Directory.CreateDirectory(
94 Path.Combine(Path.GetTempPath(), nameof(IntercomAttachmentMessageBuilderTests) + "_mcp_" + Guid.NewGuid().ToString("N")))
95 .FullName;
96 var file = Path.Combine(dir, "Foo.cs");
97 File.WriteAllText(
98 file,
99 """
100 namespace Sample;
101 public class C {
102 public void Run() { }
103 }
104 """);
105
106 var rel = "Foo.cs";
107 Assert.True(
108 IntercomAttachmentMessageBuilder.TryPrepareForMcp(
109 $"line [F:{rel}; L:2-3] member [M:Run]",
110 new Dictionary<string, AttachmentAnchor>(),
111 IntercomAttachmentResolveAtSend.EditorSnapshot.ForMcpBracketResolve(file),
112 dir,
113 null,
114 out var prepared));
115 Assert.True(prepared.IsCommittable);
116 Assert.Equal(2, prepared.Outbound.Attachments.Count);
117
118 var lineAnchor = prepared.Outbound.Attachments[0];
119 Assert.Equal(2, lineAnchor.LineStart);
120 Assert.Equal(3, lineAnchor.LineEnd);
121 Assert.Null(lineAnchor.Excerpt);
122
123 var memberAnchor = prepared.Outbound.Attachments[1];
124 Assert.Equal("Run", memberAnchor.MemberKey);
125 Assert.Equal(3, memberAnchor.LineStart);
126 Assert.Equal(3, memberAnchor.LineEnd);
127 Assert.Equal(IntercomAttachmentRevealPlan.OutcomeResolved, memberAnchor.ResolveOutcome);
128 Assert.Null(memberAnchor.Excerpt);
129 }
130
131 [Fact]
132 public void SplitFeedSegments_splits_marker_into_attach_segment()
133 {
134 var anchors = new[]
135 {
136 new AttachmentAnchor { Id = "abcd1234", DisplayLabel = "Run" },
137 };
138 var segments = IntercomAttachmentMarkers.SplitFeedSegments("x ⟦a:abcd1234⟧ y", anchors);
139 Assert.Equal(3, segments.Count);
140 Assert.Equal(IntercomAttachmentFeedSegmentKind.Attachment, segments[1].Kind);
141 Assert.Equal("[Run]", segments[1].Text);
142 }
143}
144
View only · write via MCP/CIDE