Skip to content

Commit 8ed34d2

Browse files
Copilotsamtrion
andcommitted
Create integration test project with TUnit framework and basic end-to-end tests
Co-authored-by: samtrion <[email protected]>
1 parent 5e587f6 commit 8ed34d2

9 files changed

+486
-0
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.Packages.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@
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.TUnit" Version="30.7.3" />
2122
</ItemGroup>
2223
</Project>

GitVersion.yml.backup

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"major-version-bump-message": "breaking:",
3+
"minor-version-bump-message": "feat:",
4+
"patch-version-bump-message": "fix:",
5+
"no-bump-message": ".*"
6+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFrameworks>$(_ProjectTargetFrameworks)</TargetFrameworks>
4+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
5+
</PropertyGroup>
6+
<ItemGroup Condition=" '$([MSBuild]::GetTargetFrameworkIdentifier($(TargetFramework)))' == '.NETStandard' ">
7+
<PackageReference Include="System.Memory" />
8+
</ItemGroup>
9+
</Project>
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
namespace NetEvolve.CodeBuilder.Tests.Integration;
2+
3+
using System;
4+
using System.Globalization;
5+
6+
public partial class CSharpCodeBuilderIntegrationTests
7+
{
8+
[Test]
9+
public async Task GenerateCompleteClass_Should_ProduceCorrectOutput()
10+
{
11+
var builder = new CSharpCodeBuilder();
12+
13+
// Build a complete class with using statements, namespace, and methods
14+
builder
15+
.AppendLine("using System;")
16+
.AppendLine("using System.Collections.Generic;")
17+
.AppendLine()
18+
.AppendLine("namespace MyApplication.Models")
19+
.Append("{")
20+
.AppendLine("/// <summary>")
21+
.AppendLine("/// Represents a customer entity.")
22+
.AppendLine("/// </summary>")
23+
.AppendLine("public class Customer")
24+
.Append("{")
25+
.AppendLine("private readonly string _id;")
26+
.AppendLine()
27+
.AppendLine("/// <summary>")
28+
.AppendLine("/// Initializes a new instance of the Customer class.")
29+
.AppendLine("/// </summary>")
30+
.AppendLine("/// <param name=\"id\">The customer identifier.</param>")
31+
.AppendLine("public Customer(string id)")
32+
.Append("{")
33+
.AppendLine("_id = id ?? throw new ArgumentNullException(nameof(id));")
34+
.Append("}")
35+
.AppendLine()
36+
.AppendLine("/// <summary>")
37+
.AppendLine("/// Gets the customer identifier.")
38+
.AppendLine("/// </summary>")
39+
.AppendLine("public string Id => _id;")
40+
.AppendLine()
41+
.AppendLine("/// <summary>")
42+
.AppendLine("/// Gets or sets the customer name.")
43+
.AppendLine("/// </summary>")
44+
.AppendLine("public string? Name { get; set; }")
45+
.AppendLine()
46+
.AppendLine("/// <summary>")
47+
.AppendLine("/// Gets or sets the customer email address.")
48+
.AppendLine("/// </summary>")
49+
.AppendLine("public string? Email { get; set; }")
50+
.Append("}")
51+
.Append("}");
52+
53+
var result = builder.ToString();
54+
55+
// Basic verification - check that the output contains expected elements
56+
_ = await Assert.That(result).Contains("using System;");
57+
_ = await Assert.That(result).Contains("namespace MyApplication.Models");
58+
_ = await Assert.That(result).Contains("public class Customer");
59+
_ = await Assert.That(result).Contains("public Customer(string id)");
60+
_ = await Assert.That(result).Contains("public string Id => _id;");
61+
_ = await Assert.That(result).Contains("public string? Name { get; set; }");
62+
_ = await Assert.That(result).Contains("public string? Email { get; set; }");
63+
64+
// Ensure proper indentation is applied
65+
_ = await Assert.That(result).Contains(" public class Customer");
66+
_ = await Assert.That(result).Contains(" private readonly string _id;");
67+
}
68+
69+
[Test]
70+
public async Task GenerateInterface_WithMultipleMethods_Should_ProduceCorrectOutput()
71+
{
72+
var builder = new CSharpCodeBuilder();
73+
74+
builder
75+
.AppendLine("using System;")
76+
.AppendLine("using System.Threading.Tasks;")
77+
.AppendLine()
78+
.AppendLine("namespace MyApplication.Services")
79+
.Append("{")
80+
.AppendLine("/// <summary>")
81+
.AppendLine("/// Defines the contract for customer service operations.")
82+
.AppendLine("/// </summary>")
83+
.AppendLine("public interface ICustomerService")
84+
.Append("{")
85+
.AppendLine("/// <summary>")
86+
.AppendLine("/// Gets a customer by their identifier.")
87+
.AppendLine("/// </summary>")
88+
.AppendLine("/// <param name=\"id\">The customer identifier.</param>")
89+
.AppendLine("/// <returns>The customer if found; otherwise, null.</returns>")
90+
.AppendLine("Task<Customer?> GetCustomerAsync(string id);")
91+
.AppendLine()
92+
.AppendLine("/// <summary>")
93+
.AppendLine("/// Creates a new customer.")
94+
.AppendLine("/// </summary>")
95+
.AppendLine("/// <param name=\"customer\">The customer to create.</param>")
96+
.AppendLine("/// <returns>A task representing the asynchronous operation.</returns>")
97+
.AppendLine("Task CreateCustomerAsync(Customer customer);")
98+
.AppendLine()
99+
.AppendLine("/// <summary>")
100+
.AppendLine("/// Updates an existing customer.")
101+
.AppendLine("/// </summary>")
102+
.AppendLine("/// <param name=\"customer\">The customer to update.</param>")
103+
.AppendLine("/// <returns>A task representing the asynchronous operation.</returns>")
104+
.AppendLine("Task UpdateCustomerAsync(Customer customer);")
105+
.Append("}")
106+
.Append("}");
107+
108+
var result = builder.ToString();
109+
110+
// Basic verification - check that the output contains expected elements
111+
_ = await Assert.That(result).Contains("using System.Threading.Tasks;");
112+
_ = await Assert.That(result).Contains("namespace MyApplication.Services");
113+
_ = await Assert.That(result).Contains("public interface ICustomerService");
114+
_ = await Assert.That(result).Contains("Task<Customer?> GetCustomerAsync(string id);");
115+
_ = await Assert.That(result).Contains("Task CreateCustomerAsync(Customer customer);");
116+
_ = await Assert.That(result).Contains("Task UpdateCustomerAsync(Customer customer);");
117+
118+
// Ensure proper indentation is applied
119+
_ = await Assert.That(result).Contains(" public interface ICustomerService");
120+
_ = await Assert.That(result).Contains(" Task<Customer?> GetCustomerAsync(string id);");
121+
}
122+
}
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
namespace NetEvolve.CodeBuilder.Tests.Integration;
2+
3+
using System;
4+
using System.Globalization;
5+
using System.Linq;
6+
7+
public partial class CSharpCodeBuilderIntegrationTests
8+
{
9+
[Test]
10+
public async Task GenerateMethodWithConditionalContent_Should_ProduceCorrectOutput()
11+
{
12+
var builder = new CSharpCodeBuilder();
13+
14+
var includeLogging = true;
15+
var includeValidation = false;
16+
var isAsync = true;
17+
18+
builder.AppendLine("public class ServiceClass").Append("{");
19+
20+
if (isAsync)
21+
{
22+
builder.Append("public async Task");
23+
}
24+
else
25+
{
26+
builder.Append("public void");
27+
}
28+
29+
builder
30+
.Append(" ProcessDataAsync(string input)")
31+
.Append("{")
32+
.AppendLineIf(includeValidation, "if (string.IsNullOrEmpty(input))")
33+
.AppendLineIf(includeValidation, "{")
34+
.AppendLineIf(
35+
includeValidation,
36+
" throw new ArgumentException(\"Input cannot be null or empty\", nameof(input));"
37+
)
38+
.AppendLineIf(includeValidation, "}")
39+
.AppendLineIf(includeValidation, "")
40+
.AppendLineIf(includeLogging, "Console.WriteLine($\"Processing input: {input}\");")
41+
.AppendLine("var result = input.ToUpperInvariant();")
42+
.AppendLineIf(includeLogging, "Console.WriteLine($\"Processing complete: {result}\");")
43+
.AppendLineIf(isAsync, "await Task.CompletedTask;")
44+
.AppendLine("return result;")
45+
.Append("}")
46+
.Append("}");
47+
48+
var result = builder.ToString();
49+
50+
// Verify conditional content was applied correctly
51+
_ = await Assert.That(result).Contains("public async Task ProcessDataAsync(string input)"); // async version
52+
_ = await Assert.That(result).Contains("Console.WriteLine($\"Processing input: {input}\");"); // logging included
53+
_ = await Assert.That(result).Contains("await Task.CompletedTask;"); // async included
54+
_ = await Assert.That(result).DoesNotContain("if (string.IsNullOrEmpty(input))"); // validation excluded
55+
_ = await Assert.That(result).Contains("input.ToUpperInvariant()"); // proper string case conversion
56+
}
57+
58+
[Test]
59+
public async Task GenerateReflectionBasedCode_Should_ProduceCorrectOutput()
60+
{
61+
var builder = new CSharpCodeBuilder();
62+
63+
var properties = new[]
64+
{
65+
new
66+
{
67+
Name = "Id",
68+
Type = "int",
69+
HasGetter = true,
70+
HasSetter = false,
71+
},
72+
new
73+
{
74+
Name = "Name",
75+
Type = "string?",
76+
HasGetter = true,
77+
HasSetter = true,
78+
},
79+
new
80+
{
81+
Name = "Email",
82+
Type = "string?",
83+
HasGetter = true,
84+
HasSetter = true,
85+
},
86+
new
87+
{
88+
Name = "CreatedAt",
89+
Type = "DateTime",
90+
HasGetter = true,
91+
HasSetter = false,
92+
},
93+
};
94+
95+
builder.AppendLine("using System;").AppendLine().AppendLine("public class GeneratedEntity").Append("{");
96+
97+
// Generate backing fields for properties without setters
98+
foreach (var prop in properties.Where(p => !p.HasSetter))
99+
{
100+
builder
101+
.AppendFormat(
102+
CultureInfo.InvariantCulture,
103+
"private readonly {0} _{1};",
104+
prop.Type,
105+
prop.Name.ToUpperInvariant()
106+
)
107+
.AppendLine();
108+
}
109+
110+
if (properties.Any(p => !p.HasSetter))
111+
{
112+
builder.AppendLine();
113+
}
114+
115+
// Generate constructor
116+
var readOnlyProps = properties.Where(p => !p.HasSetter).ToArray();
117+
if (readOnlyProps.Length > 0)
118+
{
119+
builder.Append("public GeneratedEntity(");
120+
for (int i = 0; i < readOnlyProps.Length; i++)
121+
{
122+
if (i > 0)
123+
builder.Append(", ");
124+
builder.AppendFormat(
125+
CultureInfo.InvariantCulture,
126+
"{0} {1}",
127+
readOnlyProps[i].Type,
128+
readOnlyProps[i].Name.ToUpperInvariant()
129+
);
130+
}
131+
builder.AppendLine(")").Append("{");
132+
133+
foreach (var prop in readOnlyProps)
134+
{
135+
builder
136+
.AppendFormat(
137+
CultureInfo.InvariantCulture,
138+
"_{0} = {1};",
139+
prop.Name.ToUpperInvariant(),
140+
prop.Name.ToUpperInvariant()
141+
)
142+
.AppendLine();
143+
}
144+
145+
builder.Append("}").AppendLine();
146+
}
147+
148+
// Generate properties
149+
foreach (var prop in properties)
150+
{
151+
builder.AppendFormat(CultureInfo.InvariantCulture, "public {0} {1}", prop.Type, prop.Name);
152+
153+
if (prop.HasGetter && prop.HasSetter)
154+
{
155+
builder.AppendLine(" { get; set; }");
156+
}
157+
else if (prop.HasGetter && !prop.HasSetter)
158+
{
159+
builder
160+
.AppendFormat(CultureInfo.InvariantCulture, " => _{0};", prop.Name.ToUpperInvariant())
161+
.AppendLine();
162+
}
163+
164+
builder.AppendLine();
165+
}
166+
167+
builder.Append("}");
168+
169+
var result = builder.ToString();
170+
171+
// Basic verification for reflection-based code generation
172+
_ = await Assert.That(result).Contains("public class GeneratedEntity");
173+
_ = await Assert.That(result).Contains("private readonly int _ID;");
174+
_ = await Assert.That(result).Contains("private readonly DateTime _CREATEDAT;");
175+
_ = await Assert.That(result).Contains("public GeneratedEntity(int ID, DateTime CREATEDAT)");
176+
_ = await Assert.That(result).Contains("public int Id => _ID;");
177+
_ = await Assert.That(result).Contains("public string? Name { get; set; }");
178+
_ = await Assert.That(result).Contains("public string? Email { get; set; }");
179+
_ = await Assert.That(result).Contains("public DateTime CreatedAt => _CREATEDAT;");
180+
}
181+
}

0 commit comments

Comments
 (0)