Forge
csharpdeeb25a2
1using CascadeIDE.Services.Presentation;
2using Xunit;
3
4namespace CascadeIDE.Tests;
5
6public sealed class PresentationParserTests
7{
8 private static readonly PresentationGrammarTokens Default = PresentationGrammarTokens.Default;
9
10 private static readonly PresentationGrammarTokens FullWordGrammar =
11 PresentationGrammarTokens.FromSettings("()", " ", "+", "PFD", "Forward", "MFD");
12
13 private static PresentationAnchorSlot[] Unweighted(params PresentationAnchorKind[] kinds) =>
14 kinds.Select(k => new PresentationAnchorSlot(k, null)).ToArray();
15
16 [Fact]
17 public void Empty_Yields_NoScreens()
18 {
19 var r = PresentationParser.Parse("", Default);
20 Assert.True(r.IsSuccess);
21 Assert.Empty(r.Screens);
22 }
23
24 [Fact]
25 public void SingleScreen_ThreeAnchors_Plus()
26 {
27 var r = PresentationParser.Parse("(P+F+M)", Default);
28 Assert.True(r.IsSuccess);
29 Assert.Single(r.Screens);
30 Assert.Equal(Unweighted(PresentationAnchorKind.Pfd, PresentationAnchorKind.Forward, PresentationAnchorKind.Mfd), r.Screens[0]);
31 }
32
33 [Fact]
34 public void SingleScreen_ThreeAnchors_WithZoneSeparator_Pipe()
35 {
36 var g = PresentationGrammarTokens.FromSettings("()", " ", "|", "PFD", "Forward", "MFD");
37 var r = PresentationParser.Parse("(PFD|Forward|MFD)", g);
38 Assert.True(r.IsSuccess);
39 Assert.Equal(Unweighted(PresentationAnchorKind.Pfd, PresentationAnchorKind.Forward, PresentationAnchorKind.Mfd), r.Screens[0]);
40 }
41
42 [Fact]
43 public void DefaultZoneSeparator_Plus_PipeBetweenAnchors_IsInvalid()
44 {
45 var r = PresentationParser.Parse("(PFD|Forward|MFD)", Default);
46 Assert.False(r.IsSuccess);
47 }
48
49 [Fact]
50 public void TwoScreens_DedicatedMfd()
51 {
52 var r = PresentationParser.Parse("(PFD+Forward) (MFD)", FullWordGrammar);
53 Assert.True(r.IsSuccess);
54 Assert.Equal(2, r.Screens.Count);
55 Assert.Equal(Unweighted(PresentationAnchorKind.Pfd, PresentationAnchorKind.Forward), r.Screens[0]);
56 Assert.Equal(Unweighted(PresentationAnchorKind.Mfd), r.Screens[1]);
57 Assert.True(PresentationLayoutAnalyzer.TryGetMfdHostPresentationScreenIndex(r.Screens, out var mfdIdx));
58 Assert.Equal(1, mfdIdx);
59 }
60
61 [Fact]
62 public void ThreeScreens_Pfd_Forward_Mfd_Yields_MfdIndex2()
63 {
64 var r = PresentationParser.Parse("(PFD) (Forward) (MFD)", FullWordGrammar);
65 Assert.True(r.IsSuccess);
66 Assert.Equal(3, r.Screens.Count);
67 Assert.True(PresentationLayoutAnalyzer.IsTriplePfdForwardMfdPreset(r.Screens));
68 Assert.True(PresentationLayoutAnalyzer.IsTripleOneAnchorPerZonePreset(r.Screens));
69 Assert.True(PresentationLayoutAnalyzer.TryGetMfdHostPresentationScreenIndex(r.Screens, out var mfdIdx));
70 Assert.Equal(2, mfdIdx);
71 Assert.True(PresentationLayoutAnalyzer.TryGetPfdHostPresentationScreenIndex(r.Screens, out var pfdIdx));
72 Assert.Equal(0, pfdIdx);
73 }
74
75 [Fact]
76 public void ThreeScreens_permuted_M_F_P_resolves_anchor_screen_indices()
77 {
78 var g = PresentationGrammarTokens.FromSettings("()", " ", "+", "P", "F", "M");
79 var r = PresentationParser.Parse("(M) (F) (P)", g);
80 Assert.True(r.IsSuccess);
81 Assert.Equal(3, r.Screens.Count);
82 Assert.True(PresentationLayoutAnalyzer.IsTripleOneAnchorPerZonePreset(r.Screens));
83 Assert.False(PresentationLayoutAnalyzer.IsTriplePfdForwardMfdPreset(r.Screens));
84 Assert.True(PresentationLayoutAnalyzer.TryGetMfdHostPresentationScreenIndex(r.Screens, out var mIdx));
85 Assert.Equal(0, mIdx);
86 Assert.True(PresentationLayoutAnalyzer.TryGetPfdHostPresentationScreenIndex(r.Screens, out var pIdx));
87 Assert.Equal(2, pIdx);
88 }
89
90 [Fact]
91 public void TwoScreens_ShortIdentifiers_P_F_M()
92 {
93 var g = PresentationGrammarTokens.FromSettings("()", " ", "+", "P", "F", "M");
94 var r = PresentationParser.Parse("(P+F) (M)", g);
95 Assert.True(r.IsSuccess);
96 Assert.True(PresentationLayoutAnalyzer.IsDedicatedMfdSecondScreenPreset(r.Screens));
97 }
98
99 [Fact]
100 public void TwoScreens_Weighted_FirstGroup()
101 {
102 var g = PresentationGrammarTokens.FromSettings("()", " ", "+", "P", "F", "M");
103 var r = PresentationParser.Parse("(0.25P+0.75F)(M)", g);
104 Assert.True(r.IsSuccess);
105 Assert.Equal(2, r.Screens.Count);
106 Assert.Equal(
107 new[]
108 {
109 new PresentationAnchorSlot(PresentationAnchorKind.Pfd, 0.25),
110 new PresentationAnchorSlot(PresentationAnchorKind.Forward, 0.75),
111 },
112 r.Screens[0]);
113 Assert.Equal(Unweighted(PresentationAnchorKind.Mfd), r.Screens[1]);
114 Assert.True(PresentationLayoutAnalyzer.IsDedicatedMfdSecondScreenPreset(r.Screens));
115 }
116
117 [Fact]
118 public void TwoScreens_Weighted_FirstGroup_SpacesInsideScreenMarkers_NormalizedLikeCompactForm()
119 {
120 var g = PresentationGrammarTokens.FromSettings("()", " ", "+", "P", "F", "M");
121 var compact = PresentationParser.Parse("(0.25P+0.75F)(M)", g);
122 var spaced = PresentationParser.Parse("(0.25P + 0.75F) ( M )", g);
123 Assert.True(spaced.IsSuccess);
124 Assert.True(compact.IsSuccess);
125 Assert.Equal(compact.Screens, spaced.Screens);
126 }
127
128 [Fact]
129 public void SingleScreen_ThreeAnchors_Weighted()
130 {
131 var g = PresentationGrammarTokens.FromSettings("()", " ", "+", "P", "F", "M");
132 var r = PresentationParser.Parse("(0.2P+0.3F+0.5M)", g);
133 Assert.True(r.IsSuccess);
134 Assert.Equal(
135 new[]
136 {
137 new PresentationAnchorSlot(PresentationAnchorKind.Pfd, 0.2),
138 new PresentationAnchorSlot(PresentationAnchorKind.Forward, 0.3),
139 new PresentationAnchorSlot(PresentationAnchorKind.Mfd, 0.5),
140 },
141 r.Screens[0]);
142 }
143
144 [Fact]
145 public void Weighted_SumNotOne_Fails()
146 {
147 var g = PresentationGrammarTokens.FromSettings("()", " ", "+", "P", "F", "M");
148 var r = PresentationParser.Parse("(0.5P+0.5F+0.5M)", g);
149 Assert.False(r.IsSuccess);
150 Assert.Contains("Сумма коэффициентов", r.Error ?? "");
151 }
152
153 [Fact]
154 public void MixedWeightedAndUnweighted_Fails()
155 {
156 var g = PresentationGrammarTokens.FromSettings("()", " ", "+", "P", "F", "M");
157 var r = PresentationParser.Parse("(0.25P+F+M)", g);
158 Assert.False(r.IsSuccess);
159 Assert.Contains("Смешение", r.Error ?? "");
160 }
161
162 [Fact]
163 public void SingleAnchor_WithWeight_Fails()
164 {
165 var g = PresentationGrammarTokens.FromSettings("()", " ", "+", "P", "F", "M");
166 var r = PresentationParser.Parse("(1M)", g);
167 Assert.False(r.IsSuccess);
168 Assert.Contains("Один якорь", r.Error ?? "");
169 }
170
171 [Fact]
172 public void CustomScreenMarkers()
173 {
174 var g = PresentationGrammarTokens.FromSettings("[]", " ", "+", "PFD", "Forward", "MFD");
175 var r = PresentationParser.Parse("[PFD+Forward] [MFD]", g);
176 Assert.True(r.IsSuccess);
177 Assert.Equal(2, r.Screens.Count);
178 }
179
180 [Fact]
181 public void LegacySpellings_forward_Mfd_AreInvalid()
182 {
183 Assert.False(PresentationParser.Parse("(PFD+forward+MFD)", FullWordGrammar).IsSuccess);
184 Assert.False(PresentationParser.Parse("(PFD+Forward+Mfd)", FullWordGrammar).IsSuccess);
185 Assert.False(PresentationParser.Parse("(PFD+Forward+mfd)", FullWordGrammar).IsSuccess);
186 }
187
188 [Fact]
189 public void CustomZoneIdentifiers_FromSettings()
190 {
191 var g = PresentationGrammarTokens.FromSettings(
192 "()", " ", "+",
193 pfdZoneIdentifier: "Pfd",
194 forwardZoneIdentifier: "Lob",
195 mfdZoneIdentifier: "Mfd");
196 var r = PresentationParser.Parse("(Pfd+Lob+Mfd)", g);
197 Assert.True(r.IsSuccess);
198 Assert.Equal(Unweighted(PresentationAnchorKind.Pfd, PresentationAnchorKind.Forward, PresentationAnchorKind.Mfd), r.Screens[0]);
199 }
200
201 [Fact]
202 public void ShortZoneIdentifiers_SingleLetter()
203 {
204 var g = PresentationGrammarTokens.FromSettings(
205 "()", " ", "+",
206 pfdZoneIdentifier: "p",
207 forwardZoneIdentifier: "l",
208 mfdZoneIdentifier: "m");
209 var r = PresentationParser.Parse("(p+l+m)", g);
210 Assert.True(r.IsSuccess);
211 Assert.Equal(Unweighted(PresentationAnchorKind.Pfd, PresentationAnchorKind.Forward, PresentationAnchorKind.Mfd), r.Screens[0]);
212 }
213
214 [Fact]
215 public void DuplicateZoneIdentifiers_FallbackToDefaultIdentifiers()
216 {
217 var g = PresentationGrammarTokens.FromSettings(
218 "()", " ", "+",
219 pfdZoneIdentifier: "P",
220 forwardZoneIdentifier: "P",
221 mfdZoneIdentifier: "MFD");
222 var r = PresentationParser.Parse("(P+F+M)", g);
223 Assert.True(r.IsSuccess);
224 }
225
226 [Fact]
227 public void Invalid_UnknownToken()
228 {
229 var r = PresentationParser.Parse("(PFD+oops)", FullWordGrammar);
230 Assert.False(r.IsSuccess);
231 Assert.NotNull(r.Error);
232 }
233}
234
View only · write via MCP/CIDE