Skip to content

Commit 77e953f

Browse files
authored
test: harden context map and gateway routing coverage (#473)
1 parent 273d99f commit 77e953f

2 files changed

Lines changed: 177 additions & 0 deletions

File tree

‎test/PatternKit.Generators.Tests/ContextMapDescriptorGeneratorTests.cs‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,48 @@ public void Reports_Context_Map_Diagnostics(string source, string expected)
6363
ScenarioExpect.Equal(expected, diagnostic.Id);
6464
}
6565

66+
[Scenario("Generates context map descriptor for struct host and all relationship kinds")]
67+
[Fact]
68+
public void Generates_Context_Map_Descriptor_For_Struct_Host_And_All_Relationship_Kinds()
69+
{
70+
var source = """
71+
using PatternKit.Generators.ContextMaps;
72+
73+
[GenerateContextMapDescriptor("Enterprise", FactoryMethodName = "CreateEnterprise")]
74+
[ContextMapRelationship("A", "B", ContextMapRelationshipKind.Partnership, "AB")]
75+
[ContextMapRelationship("B", "C", ContextMapRelationshipKind.SharedKernel, "BC")]
76+
[ContextMapRelationship("C", "D", ContextMapRelationshipKind.CustomerSupplier, "CD")]
77+
[ContextMapRelationship("D", "E", ContextMapRelationshipKind.Conformist, "DE")]
78+
[ContextMapRelationship("E", "F", ContextMapRelationshipKind.AntiCorruptionLayer, "EF")]
79+
[ContextMapRelationship("F", "G", ContextMapRelationshipKind.OpenHostService, "FG")]
80+
[ContextMapRelationship("G", "H", ContextMapRelationshipKind.PublishedLanguage, "GH")]
81+
[ContextMapRelationship("H", "I", ContextMapRelationshipKind.SeparateWays, "HI")]
82+
[ContextMapRelationship("I", "J", (ContextMapRelationshipKind)99, "IJ")]
83+
public partial struct EnterpriseMap;
84+
""";
85+
86+
var comp = CreateCompilation(source, nameof(Generates_Context_Map_Descriptor_For_Struct_Host_And_All_Relationship_Kinds));
87+
var gen = new ContextMapDescriptorGenerator();
88+
_ = RoslynTestHelpers.Run(comp, gen, out var run, out var updated);
89+
90+
ScenarioExpect.All(run.Results, result => ScenarioExpect.Empty(result.Diagnostics));
91+
var generated = ScenarioExpect.Single(run.Results.SelectMany(static result => result.GeneratedSources));
92+
ScenarioExpect.Equal("EnterpriseMap.ContextMapDescriptor.g.cs", generated.HintName);
93+
var text = generated.SourceText.ToString();
94+
ScenarioExpect.Contains("partial struct EnterpriseMap", text);
95+
ScenarioExpect.Contains("CreateEnterprise()", text);
96+
ScenarioExpect.Contains("ContextRelationshipKind.Partnership", text);
97+
ScenarioExpect.Contains("ContextRelationshipKind.SharedKernel", text);
98+
ScenarioExpect.Contains("ContextRelationshipKind.CustomerSupplier", text);
99+
ScenarioExpect.Contains("ContextRelationshipKind.Conformist", text);
100+
ScenarioExpect.Contains("ContextRelationshipKind.AntiCorruptionLayer", text);
101+
ScenarioExpect.Contains("ContextRelationshipKind.OpenHostService", text);
102+
ScenarioExpect.Contains("ContextRelationshipKind.PublishedLanguage", text);
103+
ScenarioExpect.Contains("ContextRelationshipKind.SeparateWays", text);
104+
ScenarioExpect.DoesNotContain("namespace Demo;", text);
105+
ScenarioExpect.True(updated.Emit(Stream.Null).Success);
106+
}
107+
66108
private static CSharpCompilation CreateCompilation(string source, string assemblyName)
67109
=> RoslynTestHelpers.CreateCompilation(
68110
source,

‎test/PatternKit.Generators.Tests/GatewayRoutingGeneratorTests.cs‎

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,130 @@ public static partial class GatewayHost
148148
})
149149
.AssertPassed();
150150

151+
[Scenario("Generates Gateway Routing factories for abstract and sealed hosts")]
152+
[Fact]
153+
public Task Generates_Gateway_Routing_Factories_For_Abstract_And_Sealed_Hosts()
154+
=> Given("Gateway Routing declarations on abstract and sealed hosts", () => Compile("""
155+
using PatternKit.Generators.GatewayRouting;
156+
namespace Demo;
157+
public sealed record GatewayRequest(string Path);
158+
public sealed record GatewayResponse(string Body);
159+
160+
[GenerateGatewayRouting(typeof(GatewayRequest), typeof(GatewayResponse), FactoryMethodName = "CreateAbstract")]
161+
public abstract partial class AbstractGateway
162+
{
163+
[GatewayRoute("inventory")]
164+
private static bool IsInventory(GatewayRequest request) => true;
165+
[GatewayRouteHandler("inventory")]
166+
private static GatewayResponse Inventory(GatewayRequest request) => new("inventory");
167+
[GatewayRouteFallback]
168+
private static GatewayResponse Fallback(GatewayRequest request) => new("fallback");
169+
}
170+
171+
[GenerateGatewayRouting(typeof(GatewayRequest), typeof(GatewayResponse), FactoryMethodName = "CreateSealed")]
172+
public sealed partial class SealedGateway
173+
{
174+
[GatewayRoute("billing")]
175+
private static bool IsBilling(GatewayRequest request) => true;
176+
[GatewayRouteHandler("billing")]
177+
private static GatewayResponse Billing(GatewayRequest request) => new("billing");
178+
[GatewayRouteFallback]
179+
private static GatewayResponse Fallback(GatewayRequest request) => new("fallback");
180+
}
181+
"""))
182+
.Then("the generated source preserves host shape", result =>
183+
{
184+
ScenarioExpect.Empty(result.Diagnostics);
185+
ScenarioExpect.Equal(2, result.GeneratedSources.Count);
186+
var generatedText = string.Join(Environment.NewLine, result.GeneratedSources);
187+
ScenarioExpect.Contains("public abstract partial class AbstractGateway", generatedText);
188+
ScenarioExpect.Contains("CreateAbstract()", generatedText);
189+
ScenarioExpect.Contains("public sealed partial class SealedGateway", generatedText);
190+
ScenarioExpect.Contains("CreateSealed()", generatedText);
191+
ScenarioExpect.True(result.EmitSuccess, string.Join(Environment.NewLine, result.EmitDiagnostics));
192+
})
193+
.AssertPassed();
194+
195+
[Scenario("Generates Gateway Routing source for struct and nested accessibility variants")]
196+
[Fact]
197+
public Task Generates_Gateway_Routing_Source_For_Struct_And_Nested_Accessibility_Variants()
198+
=> Given("Gateway Routing declarations with struct and nested host accessibility", () => CompileWithoutEmit("""
199+
using PatternKit.Generators.GatewayRouting;
200+
namespace Demo;
201+
public sealed record GatewayRequest(string Path);
202+
public sealed record GatewayResponse(string Body);
203+
204+
[GenerateGatewayRouting(typeof(GatewayRequest), typeof(GatewayResponse), FactoryMethodName = "CreateInternal")]
205+
internal partial struct InternalGateway
206+
{
207+
[GatewayRoute("internal")]
208+
private static bool IsInternal(GatewayRequest request) => true;
209+
[GatewayRouteHandler("internal")]
210+
private static GatewayResponse Handle(GatewayRequest request) => new("internal");
211+
[GatewayRouteFallback]
212+
private static GatewayResponse Fallback(GatewayRequest request) => new("fallback");
213+
}
214+
215+
public partial class Outer
216+
{
217+
[GenerateGatewayRouting(typeof(GatewayRequest), typeof(GatewayResponse), FactoryMethodName = "CreatePrivate")]
218+
private partial class PrivateGateway
219+
{
220+
[GatewayRoute("private")]
221+
private static bool IsPrivate(GatewayRequest request) => true;
222+
[GatewayRouteHandler("private")]
223+
private static GatewayResponse Handle(GatewayRequest request) => new("private");
224+
[GatewayRouteFallback]
225+
private static GatewayResponse Fallback(GatewayRequest request) => new("fallback");
226+
}
227+
228+
[GenerateGatewayRouting(typeof(GatewayRequest), typeof(GatewayResponse), FactoryMethodName = "CreateProtected")]
229+
protected partial class ProtectedGateway
230+
{
231+
[GatewayRoute("protected")]
232+
private static bool IsProtected(GatewayRequest request) => true;
233+
[GatewayRouteHandler("protected")]
234+
private static GatewayResponse Handle(GatewayRequest request) => new("protected");
235+
[GatewayRouteFallback]
236+
private static GatewayResponse Fallback(GatewayRequest request) => new("fallback");
237+
}
238+
239+
[GenerateGatewayRouting(typeof(GatewayRequest), typeof(GatewayResponse), FactoryMethodName = "CreateProtectedInternal")]
240+
protected internal partial class ProtectedInternalGateway
241+
{
242+
[GatewayRoute("protected-internal")]
243+
private static bool IsProtectedInternal(GatewayRequest request) => true;
244+
[GatewayRouteHandler("protected-internal")]
245+
private static GatewayResponse Handle(GatewayRequest request) => new("protected-internal");
246+
[GatewayRouteFallback]
247+
private static GatewayResponse Fallback(GatewayRequest request) => new("fallback");
248+
}
249+
250+
[GenerateGatewayRouting(typeof(GatewayRequest), typeof(GatewayResponse), FactoryMethodName = "CreatePrivateProtected")]
251+
private protected partial class PrivateProtectedGateway
252+
{
253+
[GatewayRoute("private-protected")]
254+
private static bool IsPrivateProtected(GatewayRequest request) => true;
255+
[GatewayRouteHandler("private-protected")]
256+
private static GatewayResponse Handle(GatewayRequest request) => new("private-protected");
257+
[GatewayRouteFallback]
258+
private static GatewayResponse Fallback(GatewayRequest request) => new("fallback");
259+
}
260+
}
261+
"""))
262+
.Then("the generated source preserves accessibility", result =>
263+
{
264+
ScenarioExpect.Empty(result.Diagnostics);
265+
ScenarioExpect.Equal(5, result.GeneratedSources.Count);
266+
var generatedText = string.Join(Environment.NewLine, result.GeneratedSources);
267+
ScenarioExpect.Contains("internal partial struct InternalGateway", generatedText);
268+
ScenarioExpect.Contains("private partial class PrivateGateway", generatedText);
269+
ScenarioExpect.Contains("protected partial class ProtectedGateway", generatedText);
270+
ScenarioExpect.Contains("protected internal partial class ProtectedInternalGateway", generatedText);
271+
ScenarioExpect.Contains("private protected partial class PrivateProtectedGateway", generatedText);
272+
})
273+
.AssertPassed();
274+
151275
private static GeneratorResult Compile(string source)
152276
{
153277
var compilation = RoslynTestHelpers.CreateCompilation(
@@ -160,5 +284,16 @@ private static GeneratorResult Compile(string source)
160284
return new(result.Diagnostics.ToArray(), result.GeneratedSources.Select(static source => source.SourceText.ToString()).ToArray(), emit.Success, emit.Diagnostics.Select(static diagnostic => diagnostic.ToString()).ToArray());
161285
}
162286

287+
private static GeneratorResult CompileWithoutEmit(string source)
288+
{
289+
var compilation = RoslynTestHelpers.CreateCompilation(
290+
source,
291+
"GatewayRoutingGeneratorTests",
292+
extra: MetadataReference.CreateFromFile(typeof(GatewayRouting<,>).Assembly.Location));
293+
_ = RoslynTestHelpers.Run(compilation, new GatewayRoutingGenerator(), out var run, out _);
294+
var result = run.Results.Single();
295+
return new(result.Diagnostics.ToArray(), result.GeneratedSources.Select(static source => source.SourceText.ToString()).ToArray(), EmitSuccess: true, EmitDiagnostics: []);
296+
}
297+
163298
private sealed record GeneratorResult(IReadOnlyList<Diagnostic> Diagnostics, IReadOnlyList<string> GeneratedSources, bool EmitSuccess, IReadOnlyList<string> EmitDiagnostics);
164299
}

0 commit comments

Comments
 (0)