-
Notifications
You must be signed in to change notification settings - Fork 0
Implement WithCompileTimeConstants for fluent method body builders #98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feature/metehod_template
Are you sure you want to change the base?
Changes from all commits
96c0fbe
b1e1836
bc5266c
b4f9ea7
062a992
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| using EasySourceGenerators.Generators.DataBuilding; | ||
| using EasySourceGenerators.Generators.IncrementalGenerators; | ||
|
|
||
| namespace EasySourceGenerators.GeneratorTests; | ||
|
|
||
| [TestFixture] | ||
| public class BodyGenerationDataExtractorTests | ||
| { | ||
| [Test] | ||
| public void Extract_WithCompileTimeConstants_BodyReturningConstant_InvokesWithConstants() | ||
| { | ||
| DataMethodBodyGenerator generator = new DataMethodBodyGenerator( | ||
| new BodyGenerationData( | ||
| ReturnType: typeof(string), | ||
| ParametersTypes: [], | ||
| CompileTimeConstants: 42, | ||
| ReturnConstantValueFactory: (Func<int, string>)(constants => $"value_{constants}"))); | ||
|
|
||
| FluentBodyResult result = BodyGenerationDataExtractor.Extract(generator, false); | ||
|
|
||
| Assert.That(result.ReturnValue, Is.EqualTo("value_42")); | ||
| Assert.That(result.IsVoid, Is.False); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Extract_WithCompileTimeConstants_RuntimeBodyNoArgs_InvokesWithConstants() | ||
| { | ||
| DataMethodBodyGenerator generator = new DataMethodBodyGenerator( | ||
| new BodyGenerationData( | ||
| ReturnType: typeof(string), | ||
| ParametersTypes: [], | ||
| CompileTimeConstants: 10, | ||
| RuntimeDelegateBody: (Func<int, string>)(constants => $"body_{constants}"))); | ||
|
|
||
| FluentBodyResult result = BodyGenerationDataExtractor.Extract(generator, false); | ||
|
|
||
| Assert.That(result.ReturnValue, Is.EqualTo("body_10")); | ||
| Assert.That(result.IsVoid, Is.False); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Extract_WithCompileTimeConstants_RuntimeBodyWithAdditionalParams_ReturnsNullValue() | ||
| { | ||
| DataMethodBodyGenerator generator = new DataMethodBodyGenerator( | ||
| new BodyGenerationData( | ||
| ReturnType: typeof(string), | ||
| ParametersTypes: [typeof(int)], | ||
| CompileTimeConstants: 10, | ||
| RuntimeDelegateBody: (Func<int, int, string>)((constants, param) => $"{constants}_{param}"))); | ||
|
|
||
| FluentBodyResult result = BodyGenerationDataExtractor.Extract(generator, false); | ||
|
|
||
| Assert.That(result.ReturnValue, Is.Null); | ||
| Assert.That(result.IsVoid, Is.False); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Extract_WithoutConstants_BodyReturningConstant_InvokesWithoutArgs() | ||
| { | ||
| DataMethodBodyGenerator generator = new DataMethodBodyGenerator( | ||
| new BodyGenerationData( | ||
| ReturnType: typeof(int), | ||
| ParametersTypes: [], | ||
| ReturnConstantValueFactory: (Func<int>)(() => 99))); | ||
|
|
||
| FluentBodyResult result = BodyGenerationDataExtractor.Extract(generator, false); | ||
|
|
||
| Assert.That(result.ReturnValue, Is.EqualTo("99")); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Extract_WithoutConstants_RuntimeBodyNoParams_InvokesDirectly() | ||
| { | ||
| DataMethodBodyGenerator generator = new DataMethodBodyGenerator( | ||
| new BodyGenerationData( | ||
| ReturnType: typeof(string), | ||
| ParametersTypes: [], | ||
| RuntimeDelegateBody: (Func<string>)(() => "hello"))); | ||
|
|
||
| FluentBodyResult result = BodyGenerationDataExtractor.Extract(generator, false); | ||
|
|
||
| Assert.That(result.ReturnValue, Is.EqualTo("hello")); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Extract_VoidReturnType_WithConstants_RuntimeBody_InvokesWithConstants() | ||
| { | ||
| string captured = ""; | ||
| DataMethodBodyGenerator generator = new DataMethodBodyGenerator( | ||
| new BodyGenerationData( | ||
| ReturnType: typeof(void), | ||
| ParametersTypes: [], | ||
| CompileTimeConstants: "test", | ||
| RuntimeDelegateBody: (Action<string>)(constants => { captured = constants; }))); | ||
|
|
||
| FluentBodyResult result = BodyGenerationDataExtractor.Extract(generator, true); | ||
|
|
||
| Assert.That(result.IsVoid, Is.True); | ||
| Assert.That(captured, Is.EqualTo("test")); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Extract_NullBodyGenerationData_ReturnsNullReturnValue() | ||
| { | ||
| DataMethodBodyGenerator generator = new DataMethodBodyGenerator( | ||
| new BodyGenerationData(ReturnType: typeof(string))); | ||
|
|
||
| FluentBodyResult result = BodyGenerationDataExtractor.Extract(generator, false); | ||
|
|
||
| Assert.That(result.ReturnValue, Is.Null); | ||
| } | ||
|
|
||
| [Test] | ||
| public void Extract_WithCompileTimeConstants_ConstantFactoryTakesPriority() | ||
| { | ||
| DataMethodBodyGenerator generator = new DataMethodBodyGenerator( | ||
| new BodyGenerationData( | ||
| ReturnType: typeof(string), | ||
| ParametersTypes: [], | ||
| CompileTimeConstants: 5, | ||
| ReturnConstantValueFactory: (Func<int, string>)(constants => $"factory_{constants}"), | ||
| RuntimeDelegateBody: (Func<int, string>)(constants => $"body_{constants}"))); | ||
|
|
||
| FluentBodyResult result = BodyGenerationDataExtractor.Extract(generator, false); | ||
|
|
||
| Assert.That(result.ReturnValue, Is.EqualTo("factory_5")); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -189,4 +189,198 @@ public void FullFluentChain_UseProvidedBody_ProducesCorrectData() | |||||||||||||||
| object? bodyValue = generator.Data.RuntimeDelegateBody!.DynamicInvoke(); | ||||||||||||||||
| Assert.That(bodyValue, Is.EqualTo(42)); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| [Test] | ||||||||||||||||
| public void WithCompileTimeConstants_WithParam_ReturnsStage5WithConstants() | ||||||||||||||||
| { | ||||||||||||||||
| DataMethodBodyBuilderStage4<int, string> stage4 = new DataMethodBodyBuilderStage4<int, string>( | ||||||||||||||||
| new BodyGenerationData(ReturnType: typeof(string), ParametersTypes: [typeof(int)])); | ||||||||||||||||
|
|
||||||||||||||||
| IMethodBodyBuilderStage5WithConstants<int, string, int> result = stage4.WithCompileTimeConstants(() => 42); | ||||||||||||||||
|
|
||||||||||||||||
| Assert.That(result, Is.TypeOf<DataMethodBodyBuilderStage5WithConstants<int, string, int>>()); | ||||||||||||||||
| DataMethodBodyBuilderStage5WithConstants<int, string, int> stage5 = (DataMethodBodyBuilderStage5WithConstants<int, string, int>)result; | ||||||||||||||||
| Assert.That(stage5.Data.CompileTimeConstants, Is.EqualTo(42)); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| [Test] | ||||||||||||||||
| public void WithCompileTimeConstants_NoArg_ReturnsStage5NoArgWithConstants() | ||||||||||||||||
| { | ||||||||||||||||
| DataMethodBodyBuilderStage4NoArg<string> stage4 = new DataMethodBodyBuilderStage4NoArg<string>( | ||||||||||||||||
| new BodyGenerationData(ReturnType: typeof(string), ParametersTypes: [])); | ||||||||||||||||
|
|
||||||||||||||||
| IMethodBodyBuilderStage5NoArgWithConstants<string, int> result = stage4.WithCompileTimeConstants(() => 99); | ||||||||||||||||
|
|
||||||||||||||||
| Assert.That(result, Is.TypeOf<DataMethodBodyBuilderStage5NoArgWithConstants<string, int>>()); | ||||||||||||||||
| DataMethodBodyBuilderStage5NoArgWithConstants<string, int> stage5 = (DataMethodBodyBuilderStage5NoArgWithConstants<string, int>)result; | ||||||||||||||||
| Assert.That(stage5.Data.CompileTimeConstants, Is.EqualTo(99)); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| [Test] | ||||||||||||||||
| public void WithCompileTimeConstants_ReturnVoid_ReturnsStage5ReturnVoidWithConstants() | ||||||||||||||||
| { | ||||||||||||||||
| DataMethodBodyBuilderStage4ReturnVoid<int> stage4 = new DataMethodBodyBuilderStage4ReturnVoid<int>( | ||||||||||||||||
| new BodyGenerationData(ReturnType: typeof(void), ParametersTypes: [typeof(int)])); | ||||||||||||||||
|
|
||||||||||||||||
| IMethodBodyBuilderStage5ReturnVoidWithConstants<int, string> result = stage4.WithCompileTimeConstants(() => "test"); | ||||||||||||||||
|
|
||||||||||||||||
| Assert.That(result, Is.TypeOf<DataMethodBodyBuilderStage5ReturnVoidWithConstants<int, string>>()); | ||||||||||||||||
| DataMethodBodyBuilderStage5ReturnVoidWithConstants<int, string> stage5 = (DataMethodBodyBuilderStage5ReturnVoidWithConstants<int, string>)result; | ||||||||||||||||
| Assert.That(stage5.Data.CompileTimeConstants, Is.EqualTo("test")); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| [Test] | ||||||||||||||||
| public void WithCompileTimeConstants_ReturnVoidNoArg_ReturnsStage5ReturnVoidNoArgWithConstants() | ||||||||||||||||
| { | ||||||||||||||||
| DataMethodBodyBuilderStage4ReturnVoidNoArg stage4 = new DataMethodBodyBuilderStage4ReturnVoidNoArg( | ||||||||||||||||
| new BodyGenerationData(ReturnType: typeof(void), ParametersTypes: [])); | ||||||||||||||||
|
|
||||||||||||||||
| IMethodBodyBuilderStage5ReturnVoidNoArgWithConstants<int> result = stage4.WithCompileTimeConstants(() => 7); | ||||||||||||||||
|
|
||||||||||||||||
| Assert.That(result, Is.TypeOf<DataMethodBodyBuilderStage5ReturnVoidNoArgWithConstants<int>>()); | ||||||||||||||||
| DataMethodBodyBuilderStage5ReturnVoidNoArgWithConstants<int> stage5 = (DataMethodBodyBuilderStage5ReturnVoidNoArgWithConstants<int>)result; | ||||||||||||||||
| Assert.That(stage5.Data.CompileTimeConstants, Is.EqualTo(7)); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| [Test] | ||||||||||||||||
| public void Stage5WithConstants_UseProvidedBody_SetsRuntimeDelegateBody() | ||||||||||||||||
| { | ||||||||||||||||
| DataMethodBodyBuilderStage5WithConstants<int, string, int> stage5 = new DataMethodBodyBuilderStage5WithConstants<int, string, int>( | ||||||||||||||||
| new BodyGenerationData(ReturnType: typeof(string), ParametersTypes: [typeof(int)], CompileTimeConstants: 42)); | ||||||||||||||||
|
|
||||||||||||||||
| IMethodBodyGenerator result = stage5.UseProvidedBody((constants, param) => $"{constants}_{param}"); | ||||||||||||||||
|
|
||||||||||||||||
| Assert.That(result, Is.TypeOf<DataMethodBodyGenerator>()); | ||||||||||||||||
| DataMethodBodyGenerator generator = (DataMethodBodyGenerator)result; | ||||||||||||||||
| Assert.That(generator.Data.RuntimeDelegateBody, Is.Not.Null); | ||||||||||||||||
| Assert.That(generator.Data.CompileTimeConstants, Is.EqualTo(42)); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| [Test] | ||||||||||||||||
| public void Stage5WithConstants_BodyReturningConstant_SetsReturnConstantValueFactory() | ||||||||||||||||
| { | ||||||||||||||||
| DataMethodBodyBuilderStage5WithConstants<int, string, int> stage5 = new DataMethodBodyBuilderStage5WithConstants<int, string, int>( | ||||||||||||||||
| new BodyGenerationData(ReturnType: typeof(string), ParametersTypes: [typeof(int)], CompileTimeConstants: 42)); | ||||||||||||||||
|
|
||||||||||||||||
| IMethodBodyGenerator result = stage5.BodyReturningConstant(constants => $"value_{constants}"); | ||||||||||||||||
|
|
||||||||||||||||
| Assert.That(result, Is.TypeOf<DataMethodBodyGenerator>()); | ||||||||||||||||
| DataMethodBodyGenerator generator = (DataMethodBodyGenerator)result; | ||||||||||||||||
| Assert.That(generator.Data.ReturnConstantValueFactory, Is.Not.Null); | ||||||||||||||||
| Assert.That(generator.Data.CompileTimeConstants, Is.EqualTo(42)); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| [Test] | ||||||||||||||||
| public void Stage5NoArgWithConstants_UseProvidedBody_SetsRuntimeDelegateBody() | ||||||||||||||||
| { | ||||||||||||||||
| DataMethodBodyBuilderStage5NoArgWithConstants<string, int> stage5 = new DataMethodBodyBuilderStage5NoArgWithConstants<string, int>( | ||||||||||||||||
| new BodyGenerationData(ReturnType: typeof(string), ParametersTypes: [], CompileTimeConstants: 10)); | ||||||||||||||||
|
|
||||||||||||||||
| IMethodBodyGenerator result = stage5.UseProvidedBody(constants => $"value_{constants}"); | ||||||||||||||||
|
|
||||||||||||||||
| Assert.That(result, Is.TypeOf<DataMethodBodyGenerator>()); | ||||||||||||||||
| DataMethodBodyGenerator generator = (DataMethodBodyGenerator)result; | ||||||||||||||||
| Assert.That(generator.Data.RuntimeDelegateBody, Is.Not.Null); | ||||||||||||||||
| Assert.That(generator.Data.CompileTimeConstants, Is.EqualTo(10)); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| [Test] | ||||||||||||||||
| public void Stage5NoArgWithConstants_BodyReturningConstant_SetsReturnConstantValueFactory() | ||||||||||||||||
| { | ||||||||||||||||
| DataMethodBodyBuilderStage5NoArgWithConstants<string, int> stage5 = new DataMethodBodyBuilderStage5NoArgWithConstants<string, int>( | ||||||||||||||||
| new BodyGenerationData(ReturnType: typeof(string), ParametersTypes: [], CompileTimeConstants: 10)); | ||||||||||||||||
|
|
||||||||||||||||
| IMethodBodyGenerator result = stage5.BodyReturningConstant(constants => $"const_{constants}"); | ||||||||||||||||
|
|
||||||||||||||||
| Assert.That(result, Is.TypeOf<DataMethodBodyGenerator>()); | ||||||||||||||||
| DataMethodBodyGenerator generator = (DataMethodBodyGenerator)result; | ||||||||||||||||
| Assert.That(generator.Data.ReturnConstantValueFactory, Is.Not.Null); | ||||||||||||||||
| Assert.That(generator.Data.CompileTimeConstants, Is.EqualTo(10)); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| [Test] | ||||||||||||||||
| public void Stage5ReturnVoidWithConstants_UseProvidedBody_SetsRuntimeDelegateBody() | ||||||||||||||||
| { | ||||||||||||||||
| DataMethodBodyBuilderStage5ReturnVoidWithConstants<int, string> stage5 = new DataMethodBodyBuilderStage5ReturnVoidWithConstants<int, string>( | ||||||||||||||||
| new BodyGenerationData(ReturnType: typeof(void), ParametersTypes: [typeof(int)], CompileTimeConstants: "ctx")); | ||||||||||||||||
|
|
||||||||||||||||
| IMethodBodyGenerator result = stage5.UseProvidedBody((constants, param) => { }); | ||||||||||||||||
|
|
||||||||||||||||
| Assert.That(result, Is.TypeOf<DataMethodBodyGenerator>()); | ||||||||||||||||
| DataMethodBodyGenerator generator = (DataMethodBodyGenerator)result; | ||||||||||||||||
| Assert.That(generator.Data.RuntimeDelegateBody, Is.Not.Null); | ||||||||||||||||
| Assert.That(generator.Data.CompileTimeConstants, Is.EqualTo("ctx")); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| [Test] | ||||||||||||||||
| public void Stage5ReturnVoidNoArgWithConstants_UseProvidedBody_SetsRuntimeDelegateBody() | ||||||||||||||||
| { | ||||||||||||||||
| DataMethodBodyBuilderStage5ReturnVoidNoArgWithConstants<string> stage5 = new DataMethodBodyBuilderStage5ReturnVoidNoArgWithConstants<string>( | ||||||||||||||||
| new BodyGenerationData(ReturnType: typeof(void), ParametersTypes: [], CompileTimeConstants: "ctx")); | ||||||||||||||||
|
|
||||||||||||||||
| IMethodBodyGenerator result = stage5.UseProvidedBody(constants => { }); | ||||||||||||||||
|
|
||||||||||||||||
| Assert.That(result, Is.TypeOf<DataMethodBodyGenerator>()); | ||||||||||||||||
| DataMethodBodyGenerator generator = (DataMethodBodyGenerator)result; | ||||||||||||||||
| Assert.That(generator.Data.RuntimeDelegateBody, Is.Not.Null); | ||||||||||||||||
| Assert.That(generator.Data.CompileTimeConstants, Is.EqualTo("ctx")); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| [Test] | ||||||||||||||||
| public void FullFluentChain_WithConstants_NoArg_BodyReturningConstant_ProducesCorrectData() | ||||||||||||||||
| { | ||||||||||||||||
| DataGeneratorsFactory factory = new DataGeneratorsFactory(); | ||||||||||||||||
|
|
||||||||||||||||
| IMethodBodyGenerator result = factory.StartFluentApiBuilderForBody() | ||||||||||||||||
| .ForMethod() | ||||||||||||||||
| .WithReturnType<string>() | ||||||||||||||||
| .WithNoParameters() | ||||||||||||||||
| .WithCompileTimeConstants(() => 42) | ||||||||||||||||
| .BodyReturningConstant(constants => $"value_{constants}"); | ||||||||||||||||
|
|
||||||||||||||||
| Assert.That(result, Is.TypeOf<DataMethodBodyGenerator>()); | ||||||||||||||||
| DataMethodBodyGenerator generator = (DataMethodBodyGenerator)result; | ||||||||||||||||
| Assert.That(generator.Data.ReturnType, Is.EqualTo(typeof(string))); | ||||||||||||||||
| Assert.That(generator.Data.ParametersTypes, Is.Empty); | ||||||||||||||||
| Assert.That(generator.Data.CompileTimeConstants, Is.EqualTo(42)); | ||||||||||||||||
| Assert.That(generator.Data.ReturnConstantValueFactory, Is.Not.Null); | ||||||||||||||||
| object? constantValue = generator.Data.ReturnConstantValueFactory!.DynamicInvoke(42); | ||||||||||||||||
| Assert.That(constantValue, Is.EqualTo("value_42")); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| [Test] | ||||||||||||||||
| public void FullFluentChain_WithConstants_WithParam_UseProvidedBody_ProducesCorrectData() | ||||||||||||||||
| { | ||||||||||||||||
| DataGeneratorsFactory factory = new DataGeneratorsFactory(); | ||||||||||||||||
|
|
||||||||||||||||
| IMethodBodyGenerator result = factory.StartFluentApiBuilderForBody() | ||||||||||||||||
| .ForMethod() | ||||||||||||||||
| .WithReturnType<int>() | ||||||||||||||||
| .WithParameter<int>() | ||||||||||||||||
| .WithCompileTimeConstants(() => new { Offset = 100 }) | ||||||||||||||||
| .UseProvidedBody((constants, param) => constants.Offset + param); | ||||||||||||||||
|
|
||||||||||||||||
| Assert.That(result, Is.TypeOf<DataMethodBodyGenerator>()); | ||||||||||||||||
| DataMethodBodyGenerator generator = (DataMethodBodyGenerator)result; | ||||||||||||||||
| Assert.That(generator.Data.ReturnType, Is.EqualTo(typeof(int))); | ||||||||||||||||
| Assert.That(generator.Data.ParametersTypes, Is.EqualTo(new[] { typeof(int) })); | ||||||||||||||||
| Assert.That(generator.Data.CompileTimeConstants, Is.Not.Null); | ||||||||||||||||
| Assert.That(generator.Data.RuntimeDelegateBody, Is.Not.Null); | ||||||||||||||||
|
||||||||||||||||
| Assert.That(generator.Data.RuntimeDelegateBody, Is.Not.Null); | |
| Assert.That(generator.Data.RuntimeDelegateBody, Is.Not.Null); | |
| // Execute the runtime body with the stored constants and a sample parameter | |
| object? constants = generator.Data.CompileTimeConstants; | |
| object? runtimeResult = generator.Data.RuntimeDelegateBody!.DynamicInvoke(constants, 23); | |
| Assert.That(runtimeResult, Is.EqualTo(123)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test currently asserts that a constants-aware delegate with additional method parameters yields ReturnValue == null. That behavior will cause the generator to emit a default/empty implementation without diagnostics (since HasDelegateBody is also forced false when constants exist). Consider changing the expected behavior to either trigger syntax extraction (HasDelegateBody=true) or to fail with a clear diagnostic so this scenario can’t silently succeed.