Skip to content

Commit 1b87e03

Browse files
samtrionCopilot
andauthored
feat: Extended the API (#20)
* feat: Extended the API * fix: Update tests/NetEvolve.CodeBuilder.Tests.Unit/CSharpCodeBuilderTests.Clear.cs Co-authored-by: Copilot <[email protected]> Signed-off-by: Martin Stühmer <[email protected]> * fix: Update tests/NetEvolve.CodeBuilder.Tests.Unit/CSharpCodeBuilderTests.Clear.cs Co-authored-by: Copilot <[email protected]> Signed-off-by: Martin Stühmer <[email protected]> * fix: Update tests/NetEvolve.CodeBuilder.Tests.Unit/CSharpCodeBuilderTests.Scope.cs Co-authored-by: Copilot <[email protected]> Signed-off-by: Martin Stühmer <[email protected]> * fix: Update tests/NetEvolve.CodeBuilder.Tests.Unit/CSharpCodeBuilderTests.Clear.cs Co-authored-by: Copilot <[email protected]> Signed-off-by: Martin Stühmer <[email protected]> * fix: Update src/NetEvolve.CodeBuilder/CSharpCodeBuilder.Clear.cs Co-authored-by: Copilot <[email protected]> Signed-off-by: Martin Stühmer <[email protected]> --------- Signed-off-by: Martin Stühmer <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent 3907ae8 commit 1b87e03

File tree

4 files changed

+567
-1
lines changed

4 files changed

+567
-1
lines changed

src/NetEvolve.CodeBuilder/CSharpCodeBuilder.Clear.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,22 @@ public CSharpCodeBuilder Clear()
1717

1818
return this;
1919
}
20+
21+
/// <summary>
22+
/// Appends a single indentation unit to the current builder without affecting the indentation level.
23+
/// </summary>
24+
/// <returns>The current <see cref="CSharpCodeBuilder"/> instance to allow for method chaining.</returns>
25+
/// <remarks>
26+
/// This method adds one indentation unit directly to the builder based on the <see cref="CodeBuilderBase.UseTabs"/> setting.
27+
/// If <see cref="CodeBuilderBase.UseTabs"/> is <see langword="true"/>, a tab character is appended.
28+
/// If <see cref="CodeBuilderBase.UseTabs"/> is <see langword="false"/>, four space characters are appended.
29+
/// Unlike automatic indentation that occurs at the start of new lines, this method provides manual control
30+
/// over indentation placement and does not modify the current indentation level.
31+
/// </remarks>
32+
public CSharpCodeBuilder Intend()
33+
{
34+
_ = _builder.Append(UseTabs ? '\t' : ' ', UseTabs ? 1 : 4);
35+
36+
return this;
37+
}
2038
}

src/NetEvolve.CodeBuilder/CSharpCodeBuilder.Scope.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace NetEvolve.CodeBuilder;
1+
namespace NetEvolve.CodeBuilder;
22

33
using System;
44

@@ -23,6 +23,32 @@ public partial record CSharpCodeBuilder
2323
/// </example>
2424
public IDisposable Scope() => new ScopeHandler(this);
2525

26+
/// <summary>
27+
/// Appends a line of text and creates a scope that automatically manages indentation levels with braces.
28+
/// </summary>
29+
/// <param name="value">The string value to append before creating the scope. Can be <see langword="null"/>.</param>
30+
/// <returns>A <see cref="ScopeHandler"/> that appends an opening brace, increments indentation on creation, and appends a closing brace with decremented indentation on disposal.</returns>
31+
/// <remarks>
32+
/// This method combines <see cref="AppendLine(string?)"/> with <see cref="Scope()"/> functionality.
33+
/// The returned scope handler implements <see cref="IDisposable"/> and is designed for use with the using statement.
34+
/// When the scope is created, an opening brace is appended and indentation is incremented by one level.
35+
/// When the scope is disposed, indentation is decremented and a closing brace is appended.
36+
/// </remarks>
37+
/// <example>
38+
/// <code>
39+
/// var builder = new CSharpCodeBuilder();
40+
/// using (builder.ScopeLine("public class MyClass"))
41+
/// {
42+
/// builder.AppendLine("public string Name { get; set; }");
43+
/// }
44+
/// </code>
45+
/// </example>
46+
public IDisposable ScopeLine(string? value)
47+
{
48+
_ = AppendLine(value);
49+
return new ScopeHandler(this);
50+
}
51+
2652
/// <summary>
2753
/// A disposable struct that manages indentation scope for a <see cref="CSharpCodeBuilder"/>.
2854
/// </summary>

tests/NetEvolve.CodeBuilder.Tests.Unit/CSharpCodeBuilderTests.Clear.cs

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,196 @@ public async Task Clear_Should_Preserve_Capacity()
9393

9494
_ = await Assert.That(builder.Capacity).IsEqualTo(originalCapacity);
9595
}
96+
97+
[Test]
98+
public async Task Intend_Should_Append_Single_Indentation()
99+
{
100+
var builder = new CSharpCodeBuilder();
101+
102+
_ = builder.Intend().Append("Hello");
103+
104+
var result = builder.ToString();
105+
_ = await Assert.That(result).IsEqualTo(" Hello");
106+
}
107+
108+
[Test]
109+
public async Task Intend_Should_Not_Affect_Indentation_Level()
110+
{
111+
var builder = new CSharpCodeBuilder();
112+
113+
_ = builder.Intend().AppendLine("First");
114+
_ = builder.Append("Second");
115+
116+
var result = builder.ToString();
117+
// Second line should not be indented because Intend() doesn't change the level
118+
_ = await Assert.That(result).IsEqualTo(" First" + Environment.NewLine + "Second");
119+
}
120+
121+
[Test]
122+
public async Task Intend_With_Tabs_Should_Append_Tab_Character()
123+
{
124+
var builder = new CSharpCodeBuilder { UseTabs = true };
125+
126+
_ = builder.Intend().Append("Hello");
127+
128+
var result = builder.ToString();
129+
_ = await Assert.That(result).IsEqualTo("\tHello");
130+
}
131+
132+
[Test]
133+
public async Task Intend_With_Spaces_Should_Append_Four_Spaces()
134+
{
135+
var builder = new CSharpCodeBuilder { UseTabs = false };
136+
137+
_ = builder.Intend().Append("Hello");
138+
139+
var result = builder.ToString();
140+
_ = await Assert.That(result).IsEqualTo(" Hello");
141+
}
142+
143+
[Test]
144+
public async Task Intend_Multiple_Calls_Should_Append_Multiple_Indentations()
145+
{
146+
var builder = new CSharpCodeBuilder();
147+
148+
_ = builder.Intend().Intend().Intend().Append("Hello");
149+
150+
var result = builder.ToString();
151+
_ = await Assert.That(result).IsEqualTo(" Hello"); // 12 spaces (3 * 4)
152+
}
153+
154+
[Test]
155+
public async Task Intend_Multiple_With_Tabs_Should_Append_Multiple_Tabs()
156+
{
157+
var builder = new CSharpCodeBuilder { UseTabs = true };
158+
159+
_ = builder.Intend().Intend().Intend().Append("Hello");
160+
161+
var result = builder.ToString();
162+
_ = await Assert.That(result).IsEqualTo("\t\t\tHello");
163+
}
164+
165+
[Test]
166+
public async Task Intend_Should_Return_Builder_For_Chaining()
167+
{
168+
var builder = new CSharpCodeBuilder();
169+
170+
var result = builder.Intend();
171+
172+
_ = await Assert.That(result).IsEqualTo(builder);
173+
}
174+
175+
[Test]
176+
public async Task Intend_In_Middle_Of_Line_Should_Append_Indentation()
177+
{
178+
var builder = new CSharpCodeBuilder();
179+
180+
_ = builder.Append("Hello").Intend().Append("World");
181+
182+
var result = builder.ToString();
183+
_ = await Assert.That(result).IsEqualTo("Hello World");
184+
}
185+
186+
[Test]
187+
public async Task Intend_After_NewLine_Should_Add_Manual_Indentation()
188+
{
189+
var builder = new CSharpCodeBuilder();
190+
191+
_ = builder.AppendLine("First");
192+
_ = builder.Intend().Append("Second");
193+
194+
var result = builder.ToString();
195+
_ = await Assert.That(result).IsEqualTo("First" + Environment.NewLine + " Second");
196+
}
197+
198+
[Test]
199+
public async Task Intend_With_Automatic_Indentation_Should_Stack()
200+
{
201+
var builder = new CSharpCodeBuilder();
202+
builder.IncrementIndent(); // Set automatic indentation level to 1
203+
204+
_ = builder.AppendLine().Intend().Append("Hello");
205+
206+
var result = builder.ToString();
207+
// Should have both automatic (4 spaces) and manual (4 spaces) indentation
208+
_ = await Assert.That(result).IsEqualTo(Environment.NewLine + " Hello");
209+
}
210+
211+
[Test]
212+
public async Task Intend_Multiple_Mixed_With_Content_Should_Work()
213+
{
214+
var builder = new CSharpCodeBuilder();
215+
216+
_ = builder
217+
.Intend()
218+
.Append("Level 1")
219+
.AppendLine()
220+
.Intend()
221+
.Intend()
222+
.Append("Level 2")
223+
.AppendLine()
224+
.Intend()
225+
.Intend()
226+
.Intend()
227+
.Append("Level 3");
228+
229+
var result = builder.ToString();
230+
_ = await Assert.That(result).Contains(" Level 1");
231+
_ = await Assert.That(result).Contains(" Level 2");
232+
_ = await Assert.That(result).Contains(" Level 3");
233+
}
234+
235+
[Test]
236+
public async Task Intend_Should_Work_With_Empty_Builder()
237+
{
238+
var builder = new CSharpCodeBuilder();
239+
240+
_ = builder.Intend();
241+
242+
var result = builder.ToString();
243+
_ = await Assert.That(result).IsEqualTo(" ");
244+
}
245+
246+
[Test]
247+
public async Task Intend_Should_Work_After_Clear()
248+
{
249+
var builder = new CSharpCodeBuilder();
250+
_ = builder.Append("Hello");
251+
_ = builder.Clear();
252+
253+
_ = builder.Intend().Append("World");
254+
255+
var result = builder.ToString();
256+
_ = await Assert.That(result).IsEqualTo(" World");
257+
}
258+
259+
[Test]
260+
public async Task Intend_Combined_With_Scope_Should_Add_Extra_Indentation()
261+
{
262+
var builder = new CSharpCodeBuilder();
263+
264+
using (builder.Scope())
265+
{
266+
_ = builder.Intend().Append("Extra indented");
267+
}
268+
269+
var result = builder.ToString();
270+
// Should have both scope indentation (4 spaces) and manual indentation (4 spaces)
271+
_ = await Assert.That(result).Contains(" Extra indented"); // 8 spaces
272+
}
273+
274+
[Test]
275+
public async Task Intend_Combined_With_ScopeLine_Should_Add_Extra_Indentation()
276+
{
277+
var builder = new CSharpCodeBuilder();
278+
279+
using (builder.ScopeLine("public class MyClass"))
280+
{
281+
_ = builder.Intend().Append("// Extra indented comment");
282+
}
283+
284+
var result = builder.ToString();
285+
// Should have both scope indentation and manual indentation
286+
_ = await Assert.That(result).Contains(" // Extra indented comment"); // 8 spaces
287+
}
96288
}

0 commit comments

Comments
 (0)