Forge
csharpdeeb25a2
1using Avalonia;
2using CascadeIDE.Models;
3using CascadeIDE.Cockpit.Graph;
4using CascadeIDE.Services.CodeNavigation;
5using CascadeIDE.Services.Navigation;
6using CascadeIDE.Features.WorkspaceNavigation.Application;
7using CascadeIDE.ViewModels;
8using Xunit;
9
10namespace CascadeIDE.Tests;
11
12public sealed class CodeNavigationMapWorkspaceInstrumentBlockCompositorTests
13{
14 [Fact]
15 public void Empty_Scene_Yields_No_Blocks()
16 {
17 var scene = new CodeNavigationMapGraphSceneVm { Nodes = [], Edges = [] };
18 var blocks = CodeNavigationMapWorkspaceInstrumentBlockCompositor.Compose(scene, 400, 300);
19 Assert.Empty(blocks);
20 }
21
22 [Fact]
23 public void File_Mode_No_Legend_One_Graph_Block_Full_Viewport()
24 {
25 var n = new CodeNavigationMapGraphNodeLayout
26 {
27 Id = "a",
28 Kind = "anchor",
29 FullPath = "x",
30 Label = "a",
31 Center = new Point(50, 50),
32 Radius = 10,
33 IsAnchor = true
34 };
35 var scene = new CodeNavigationMapGraphSceneVm
36 {
37 Nodes = [n],
38 Edges = [],
39 UseLegendColumn = false,
40 LegendColumnLeft = 400
41 };
42 var blocks = CodeNavigationMapWorkspaceInstrumentBlockCompositor.Compose(scene, 400, 300);
43 Assert.Single(blocks);
44 Assert.Equal(CodeNavigationMapWorkspaceInstrumentBlockIds.Graph, blocks[0].Id);
45 Assert.Equal(new Rect(0, 0, 400, 300), blocks[0].Bounds);
46 }
47
48 [Fact]
49 public void ControlFlow_Beside_Legend_Splits_Horizontally()
50 {
51 var scene = new CodeNavigationMapGraphSceneVm
52 {
53 Nodes = [TestNode("n0", 10, 10)],
54 Edges = [],
55 UseLegendColumn = true,
56 LegendColumnLeft = 220,
57 LegendPlacement = CodeNavigationMapLegendBlockPlacement.BesideGraph
58 };
59 var blocks = CodeNavigationMapWorkspaceInstrumentBlockCompositor.Compose(scene, 400, 300);
60 Assert.Equal(2, blocks.Count);
61 Assert.Equal(CodeNavigationMapWorkspaceInstrumentBlockKind.Graph, blocks[0].Kind);
62 Assert.Equal(CodeNavigationMapWorkspaceInstrumentBlockKind.Legend, blocks[1].Kind);
63 Assert.Equal(new Rect(0, 0, 220, 300), blocks[0].Bounds);
64 Assert.Equal(new Rect(220, 0, 180, 300), blocks[1].Bounds);
65 }
66
67 [Fact]
68 public void ControlFlow_Below_Legend_Splits_Vertically()
69 {
70 var scene = new CodeNavigationMapGraphSceneVm
71 {
72 Nodes = [TestNode("n0", 10, 10)],
73 Edges = [],
74 UseLegendColumn = true,
75 LegendColumnLeft = 0,
76 LegendPlacement = CodeNavigationMapLegendBlockPlacement.BelowGraph,
77 LegendBlockTopY = 180
78 };
79 var blocks = CodeNavigationMapWorkspaceInstrumentBlockCompositor.Compose(scene, 400, 400);
80 Assert.Equal(2, blocks.Count);
81 Assert.Equal(new Rect(0, 0, 400, 180), blocks[0].Bounds);
82 Assert.Equal(new Rect(0, 180, 400, 220), blocks[1].Bounds);
83 }
84
85 [Fact]
86 public void Compositor_Integration_ControlFlow_Produces_Two_Blocks()
87 {
88 var c = new CodeNavigationMapCompositor();
89 var doc = new GraphDocument
90 {
91 AnchorPath = "A.cs",
92 Nodes =
93 [
94 new GraphNode
95 {
96 Id = "n0",
97 Path = "A.cs",
98 Kind = "anchor",
99 Label = "A"
100 },
101 new GraphNode
102 {
103 Id = "n1",
104 Path = "A.cs",
105 Kind = "call_step",
106 Label = "S1",
107 LegendIndex = 1,
108 LegendText = "first line"
109 }
110 ],
111 Edges = [new GraphEdge { FromId = "n0", ToId = "n1", Kind = "Call" }]
112 };
113 var r = c.Compose(doc, CodeNavigationMapLevelKind.ControlFlow, 500, 400, CodeNavigationMapDetailLevel.Inspect);
114 Assert.NotEmpty(r.CodeNavigationMapInstrumentBlocks);
115 Assert.Equal(2, r.CodeNavigationMapInstrumentBlocks.Count);
116 Assert.Contains(r.CodeNavigationMapInstrumentBlocks, b => b.Id == CodeNavigationMapInstrumentBlockIds.Graph);
117 Assert.Contains(r.CodeNavigationMapInstrumentBlocks, b => b.Id == CodeNavigationMapInstrumentBlockIds.Legend);
118 }
119
120 private static CodeNavigationMapGraphNodeLayout TestNode(string id, double x, double y) =>
121 new()
122 {
123 Id = id,
124 Kind = "call_step",
125 FullPath = "p",
126 Label = id,
127 Center = new Point(x, y),
128 Radius = 8,
129 IsAnchor = false
130 };
131}
132
View only · write via MCP/CIDE