Forge
csharpdeeb25a2
1using CascadeIDE.Services;
2using Xunit;
3
4namespace CascadeIDE.Tests;
5
6public sealed class CascadeIdeMafProjectAgentRulesTests
7{
8 [Fact]
9 public void TryLoadMerged_MergesSingleFileAndFragmentsInOrder()
10 {
11 var root = Path.Combine(Path.GetTempPath(), "cascade-rules-test-" + Guid.NewGuid().ToString("n"));
12 Directory.CreateDirectory(Path.Combine(root, ".cascade-ide", "maf-project-rules"));
13
14 File.WriteAllText(Path.Combine(root, ".cascade-ide", "maf-project-rules.md"), "Alpha rule.");
15 File.WriteAllText(Path.Combine(root, ".cascade-ide", "maf-project-rules", "b.md"), "Beta.");
16 File.WriteAllText(Path.Combine(root, ".cascade-ide", "maf-project-rules", "a.md"), "Gamma.");
17
18 try
19 {
20 var merged = CascadeIdeMafProjectAgentRules.TryLoadMerged(root);
21 Assert.NotNull(merged);
22 Assert.Contains("Alpha rule.", merged, StringComparison.Ordinal);
23 Assert.Contains("## a.md", merged, StringComparison.Ordinal);
24 Assert.Contains("Gamma.", merged, StringComparison.Ordinal);
25 Assert.Contains("## b.md", merged, StringComparison.Ordinal);
26 Assert.Contains("Beta.", merged, StringComparison.Ordinal);
27 Assert.True(merged.IndexOf("Gamma.", StringComparison.Ordinal) < merged.IndexOf("Beta.", StringComparison.Ordinal),
28 "Fragments should be merged in filename sort order (a.md before b.md).");
29 }
30 finally
31 {
32 try { Directory.Delete(root, recursive: true); }
33 catch { /* temp cleanup best-effort */ }
34 }
35 }
36
37 [Fact]
38 public void BuildInstructions_AppendsProjectBlockWhenProvided()
39 {
40 var prompts = new MafIdeAgentPrompts.PromptPack(
41 AgentSystem: "CORE",
42 SalvageRecapSystem: "S",
43 SalvageUserMessageTemplate: "{{USER_QUERY}}\n{{TOOL_PAYLOAD}}",
44 OptionalSections: new Dictionary<string, string>
45 {
46 ["pack_mode_debug"] = "DEBUG PACK",
47 ["pack_domain_csharp_roslyn"] = "ROSLYN PACK",
48 });
49 var merged = CascadeIdeMafIdeAgentChat.BuildInstructions(
50 prompts,
51 cascadeConversation:
52 [
53 new ChatMessage("user", "Приложение падает в .cs файле, помоги с debug"),
54 ],
55 minimizedContextBlock: "Program.cs: exception",
56 projectAgentRulesMarkdown: "## rule\nhello");
57 Assert.Contains("CORE", merged, StringComparison.Ordinal);
58 Assert.Contains("Проектные правила", merged, StringComparison.Ordinal);
59 Assert.Contains("hello", merged, StringComparison.Ordinal);
60 }
61
62 [Fact]
63 public void PromptPackRouter_SelectsPacks_ForClearDebugAndCSharpSignal()
64 {
65 var prompts = new MafIdeAgentPrompts.PromptPack(
66 AgentSystem: "CORE",
67 SalvageRecapSystem: "S",
68 SalvageUserMessageTemplate: "{{USER_QUERY}}\n{{TOOL_PAYLOAD}}",
69 OptionalSections: new Dictionary<string, string>
70 {
71 ["pack_mode_debug"] = "DEBUG PACK",
72 ["pack_domain_csharp_roslyn"] = "ROSLYN PACK",
73 });
74
75 var route = MafPromptPackRouter.Route(
76 prompts,
77 [
78 new ChatMessage("tool", "error: null reference"),
79 new ChatMessage("user", "Fix debug bug in .cs class, stack error in service"),
80 ],
81 minimizedContextBlock: "using System;\nclass Service {}",
82 budgetChars: 1_200);
83
84 Assert.True(route.Selections.Count > 0);
85 Assert.Contains(route.Selections, s => string.Equals(s.Key, "pack_mode_debug", StringComparison.Ordinal));
86 }
87}
88
View only · write via MCP/CIDE