Skip to content

Commit 45354b4

Browse files
Copilotsamtrion
andauthored
test: Create integration test project for NetEvolve.CodeBuilder library (#13)
* chore: Create integration test project with TUnit framework and basic end-to-end tests Co-authored-by: samtrion <[email protected]> * chore: Complete integration test project with documentation and snapshot test placeholders Co-authored-by: samtrion <[email protected]> * chore(test): Updated tests * style: Reformatted code * fix: Warnings from the Code Review --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: samtrion <[email protected]> Co-authored-by: Martin Stühmer <[email protected]>
1 parent 089d524 commit 45354b4

File tree

21 files changed

+656
-2
lines changed

21 files changed

+656
-2
lines changed

CodeBuilder.slnx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@
2020
</Folder>
2121
<Folder Name="/tests/">
2222
<Project Path="tests/NetEvolve.CodeBuilder.Tests.Unit/NetEvolve.CodeBuilder.Tests.Unit.csproj" />
23+
<Project Path="tests/NetEvolve.CodeBuilder.Tests.Integration/NetEvolve.CodeBuilder.Tests.Integration.csproj" />
2324
</Folder>
2425
</Solution>

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<CopyrightYearStart>2024</CopyrightYearStart>
1010
<_DefaultTargetFrameworks>net8.0;net9.0;net10.0</_DefaultTargetFrameworks>
1111
<_ProjectTargetFrameworks>netstandard2.0;netstandard2.1;$(_DefaultTargetFrameworks)</_ProjectTargetFrameworks>
12-
<_TestTargetFrameworks>net6.0;net7.0;$(_DefaultTargetFrameworks)</_TestTargetFrameworks>
12+
<_TestTargetFrameworks>$(_DefaultTargetFrameworks)</_TestTargetFrameworks>
1313
<CheckEolTargetFramework>false</CheckEolTargetFramework>
1414
</PropertyGroup>
1515
<PropertyGroup>

Directory.Packages.props

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,7 @@
1818
<PackageVersion Include="NetEvolve.Extensions.TUnit" Version="2.7.0" />
1919
<PackageVersion Include="System.Memory" Version="4.6.3" />
2020
<PackageVersion Include="TUnit" Version="0.57.1" />
21+
<PackageVersion Include="Verify.ParametersHashing" Version="1.0.0" />
22+
<PackageVersion Include="Verify.TUnit" Version="30.7.3" />
2123
</ItemGroup>
2224
</Project>

src/NetEvolve.CodeBuilder/CSharpCodeBuilder.Documentation.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
namespace NetEvolve.CodeBuilder;
22

3-
using System;
43
using System.Collections.Generic;
54
using System.Runtime.CompilerServices;
65

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
namespace NetEvolve.CodeBuilder.Tests.Integration;
2+
3+
public partial class CSharpCodeBuilderTests
4+
{
5+
[Test]
6+
public async Task GenerateCompleteClass_Should_ProduceCorrectOutput()
7+
{
8+
// Build a complete class with using statements, namespace, and methods
9+
var builder = new CSharpCodeBuilder()
10+
.AppendLine("using System;")
11+
.AppendLine("using System.Collections.Generic;")
12+
.AppendLine()
13+
.AppendLine("namespace MyApplication.Models")
14+
.Append("{")
15+
.AppendLine("/// <summary>")
16+
.AppendLine("/// Represents a customer entity.")
17+
.AppendLine("/// </summary>")
18+
.AppendLine("public class Customer")
19+
.Append("{")
20+
.AppendLine("private readonly string _id;")
21+
.AppendLine()
22+
.AppendLine("/// <summary>")
23+
.AppendLine("/// Initializes a new instance of the Customer class.")
24+
.AppendLine("/// </summary>")
25+
.AppendLine("/// <param name=\"id\">The customer identifier.</param>")
26+
.AppendLine("public Customer(string id)")
27+
.Append("{")
28+
.AppendLine("_id = id ?? throw new ArgumentNullException(nameof(id));")
29+
.Append("}")
30+
.AppendLine()
31+
.AppendLine("/// <summary>")
32+
.AppendLine("/// Gets the customer identifier.")
33+
.AppendLine("/// </summary>")
34+
.AppendLine("public string Id => _id;")
35+
.AppendLine()
36+
.AppendLine("/// <summary>")
37+
.AppendLine("/// Gets or sets the customer name.")
38+
.AppendLine("/// </summary>")
39+
.AppendLine("public string? Name { get; set; }")
40+
.AppendLine()
41+
.AppendLine("/// <summary>")
42+
.AppendLine("/// Gets or sets the customer email address.")
43+
.AppendLine("/// </summary>")
44+
.Append("public string? Email { get; set; }")
45+
.Append("}")
46+
.Append("}");
47+
48+
var result = builder.ToString();
49+
50+
_ = await Verify(result);
51+
}
52+
53+
[Test]
54+
public async Task GenerateInterface_WithMultipleMethods_Should_ProduceCorrectOutput()
55+
{
56+
var builder = new CSharpCodeBuilder()
57+
.AppendLine("using System;")
58+
.AppendLine("using System.Threading.Tasks;")
59+
.AppendLine()
60+
.AppendLine("namespace MyApplication.Services")
61+
.Append("{")
62+
.AppendXmlDocSummary("Defines the contract for customer service operations.")
63+
.AppendLine("public interface ICustomerService")
64+
.Append("{")
65+
.AppendXmlDocSummary("Gets a customer by their identifier.")
66+
.AppendXmlDocParam("id", "The customer identifier.")
67+
.AppendXmlDocReturns("The customer if found; otherwise, null.")
68+
.AppendLine("Task<Customer?> GetCustomerAsync(string id);")
69+
.AppendLine()
70+
.AppendXmlDocSummary("Creates a new customer.")
71+
.AppendXmlDocParam("customer", "The customer to create.")
72+
.AppendXmlDocReturns("A task representing the asynchronous operation.")
73+
.AppendLine("Task CreateCustomerAsync(Customer customer);")
74+
.AppendLine()
75+
.AppendXmlDocSummary("Updates an existing customer.")
76+
.AppendXmlDocParam("customer", "The customer to update.")
77+
.AppendXmlDocReturns("A task representing the asynchronous operation.")
78+
.Append("Task UpdateCustomerAsync(Customer customer);")
79+
.Append("}")
80+
.Append("}");
81+
82+
var result = builder.ToString();
83+
84+
_ = await Verify(result);
85+
}
86+
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
namespace NetEvolve.CodeBuilder.Tests.Integration;
2+
3+
using System.Globalization;
4+
using System.Linq;
5+
6+
public partial class CSharpCodeBuilderTests
7+
{
8+
[Test]
9+
public async Task GenerateMethodWithConditionalContent_Should_ProduceCorrectOutput()
10+
{
11+
var builder = new CSharpCodeBuilder();
12+
13+
var includeLogging = true;
14+
var includeValidation = false;
15+
var isAsync = true;
16+
17+
_ = builder.AppendLine("public class ServiceClass").Append("{");
18+
19+
if (isAsync)
20+
{
21+
_ = builder.Append("public async Task");
22+
}
23+
else
24+
{
25+
_ = builder.Append("public void");
26+
}
27+
28+
_ = builder
29+
.Append(" ProcessDataAsync(string input)")
30+
.Append("{")
31+
.AppendLineIf(includeValidation, "if (string.IsNullOrEmpty(input))")
32+
.AppendLineIf(includeValidation, "{")
33+
.AppendLineIf(
34+
includeValidation,
35+
" throw new ArgumentException(\"Input cannot be null or empty\", nameof(input));"
36+
)
37+
.AppendLineIf(includeValidation, "}")
38+
.AppendLineIf(includeValidation, "")
39+
.AppendLineIf(includeLogging, "Console.WriteLine($\"Processing input: {input}\");")
40+
.AppendLine("var result = input.ToUpperInvariant();")
41+
.AppendLineIf(includeLogging, "Console.WriteLine($\"Processing complete: {result}\");")
42+
.AppendLineIf(isAsync, "await Task.CompletedTask;")
43+
.AppendLine("return result;")
44+
.Append("}")
45+
.Append("}");
46+
47+
var result = builder.ToString();
48+
49+
_ = await Verify(result);
50+
}
51+
52+
[Test]
53+
public async Task GenerateReflectionBasedCode_Should_ProduceCorrectOutput()
54+
{
55+
var builder = new CSharpCodeBuilder();
56+
57+
var properties = new[]
58+
{
59+
new
60+
{
61+
Name = "Id",
62+
Type = "int",
63+
HasGetter = true,
64+
HasSetter = false,
65+
},
66+
new
67+
{
68+
Name = "Name",
69+
Type = "string?",
70+
HasGetter = true,
71+
HasSetter = true,
72+
},
73+
new
74+
{
75+
Name = "Email",
76+
Type = "string?",
77+
HasGetter = true,
78+
HasSetter = true,
79+
},
80+
new
81+
{
82+
Name = "CreatedAt",
83+
Type = "DateTime",
84+
HasGetter = true,
85+
HasSetter = false,
86+
},
87+
};
88+
89+
_ = builder.AppendLine("using System;").AppendLine().AppendLine("public class GeneratedEntity").Append("{");
90+
91+
// Generate backing fields for properties without setters
92+
foreach (var prop in properties.Where(p => !p.HasSetter))
93+
{
94+
_ = builder
95+
.AppendFormat(
96+
CultureInfo.InvariantCulture,
97+
"private readonly {0} _{1};",
98+
prop.Type,
99+
prop.Name.ToUpperInvariant()
100+
)
101+
.AppendLine();
102+
}
103+
104+
if (properties.Any(p => !p.HasSetter))
105+
{
106+
_ = builder.AppendLine();
107+
}
108+
109+
// Generate constructor
110+
var readOnlyProps = properties.Where(p => !p.HasSetter).ToArray();
111+
if (readOnlyProps.Length > 0)
112+
{
113+
_ = builder.Append("public GeneratedEntity(");
114+
for (var i = 0; i < readOnlyProps.Length; i++)
115+
{
116+
if (i > 0)
117+
{
118+
_ = builder.Append(", ");
119+
}
120+
121+
_ = builder.AppendFormat(
122+
CultureInfo.InvariantCulture,
123+
"{0} {1}",
124+
readOnlyProps[i].Type,
125+
readOnlyProps[i].Name.ToUpperInvariant()
126+
);
127+
}
128+
_ = builder.AppendLine(")").Append("{");
129+
130+
foreach (var propertyName in readOnlyProps.Select(x => x.Name.ToUpperInvariant()))
131+
{
132+
_ = builder
133+
.AppendFormat(CultureInfo.InvariantCulture, "_{0} = {1};", propertyName, propertyName)
134+
.AppendLine();
135+
}
136+
137+
_ = builder.Append("}").AppendLine();
138+
}
139+
140+
// Generate properties
141+
foreach (var prop in properties)
142+
{
143+
_ = builder.AppendFormat(CultureInfo.InvariantCulture, "public {0} {1}", prop.Type, prop.Name);
144+
145+
if (prop.HasGetter && prop.HasSetter)
146+
{
147+
_ = builder.AppendLine(" { get; set; }");
148+
}
149+
else if (prop.HasGetter && !prop.HasSetter)
150+
{
151+
_ = builder
152+
.AppendFormat(CultureInfo.InvariantCulture, " => _{0};", prop.Name.ToUpperInvariant())
153+
.AppendLine();
154+
}
155+
156+
_ = builder.AppendLine();
157+
}
158+
159+
_ = builder.Append("}");
160+
161+
var result = builder.ToString();
162+
163+
_ = await Verify(result);
164+
}
165+
}

0 commit comments

Comments
 (0)