public void MultipleInnerType_Generate_ReturnsWrappedMultipleInnerType() { (Compilation inputCompilation, SyntaxTree tree) = SourceBuilder.Compile(SimpleTestCode); var walker = Substitute.For <IPatchParametersWalker>(); walker.Process(Arg.Any <SyntaxNode>(), Arg.Any <SemanticModel>()).Returns(new[] { Substitute.For <ITypeSymbol>() }); var typeBuilder = Substitute.For <ITypeBuilder>(); typeBuilder.BuildWrapperType(Arg.Any <ITypeSymbol>(), Arg.Any <string>()) .Returns( new GeneratedWrapper() { ToProcessTypes = new List <ITypeSymbol>() { Substitute.For <ITypeSymbol>(), Substitute.For <ITypeSymbol>() } }, new GeneratedWrapper() { ToProcessTypes = new List <ITypeSymbol>() }, new GeneratedWrapper() { ToProcessTypes = new List <ITypeSymbol>() }); var sut = new MultiTypeBuilder(new[] { tree }, inputCompilation, typeBuilder, walker); var results = sut.Generate(); Assert.Equal(3, results.Count()); }
public async Task Returns_ReadJsonPatchAsync_Types() { string code = @" using LaDeak.JsonMergePatch.Http; public class Controller { public class SomeType { } public async System.Threading.Tasks.Task TestMethodAsync() { var client = new System.Net.Http.HttpClient(); var response = await client.GetAsync(""https://test.com""); await response.Content.ReadJsonPatchAsync<SomeType>(); } }"; var compilation = SourceBuilder.Compile(code, new[] { MetadataReference.CreateFromFile(typeof(PatchParameterWalkerTests).Assembly.Location), MetadataReference.CreateFromFile(typeof(Patch <>).Assembly.Location), MetadataReference.CreateFromFile(typeof(HttpClient).Assembly.Location), MetadataReference.CreateFromFile(typeof(Uri).Assembly.Location), MetadataReference.CreateFromFile(typeof(HttpContentExtensions).Assembly.Location), MetadataReference.CreateFromFile(typeof(JsonSerializerOptions).Assembly.Location) }); var sut = new PatchParametersWalker(); var result = sut.Process(await compilation.Tree.GetRootAsync(), compilation.Compilation.GetSemanticModel(compilation.Tree)); Assert.Equal("SomeType", result.First().Name); }
private static Compilation CreateInputOutputCompilation(string sourceCode) { Compilation inputCompilation = SourceBuilder.Compile(sourceCode).Compilation; JsonMergePatchSourceGenerator generator = new JsonMergePatchSourceGenerator(); GeneratorDriver driver = CSharpGeneratorDriver.Create(generator); driver.RunGeneratorsAndUpdateCompilation(inputCompilation, out var outputCompilation, out var diagnostics); return(outputCompilation); }
public void WrappedDtoType_Ctr_CreatesObject() { Compilation outputCompilation = CreateWrappedTypeCompilation(); var assembly = SourceBuilder.EmitToAssembly(outputCompilation); var sut = assembly.GetType("LaDeak.JsonMergePatch.Generated.SafeTestCode.Dto2Wrapped").GetConstructor(new Type[0]).Invoke(null); Assert.NotNull(sut); }
public void ApplyPatch_PropertyToDelete_SetsNullOnTarget( string sourceCode, bool hasTargetParent, bool hasTargetSub, string parentStringPropertyInput, string parentStringPropertyExpected, int numberPropInput, int numberPropExpected, DateTime?nullableDateTimePropertyInput, DateTime?nullableDateTimePropertyExpected, double camelCasePropertyInput, double camelCasePropertyExpected, int[] valuesInput, int[] valuesExpected, string jsonInput) { var compilation = CreateInputOutputCompilation(sourceCode); var outputAssembly = SourceBuilder.EmitToAssembly(compilation); var parentDtoWrappedMetadata = outputAssembly.GetType("LaDeak.JsonMergePatch.Generated.SafeTestCode.ParentDtoWrapped"); var targetParentMetadata = outputAssembly.GetType("TestCode.ParentDto"); var targetSubMetadata = outputAssembly.GetType("TestCode.SubDto"); var sut = JsonSerializer.Deserialize(jsonInput, parentDtoWrappedMetadata); object targetParent = null; if (hasTargetParent) { var ctor = targetParentMetadata.GetConstructors().OrderByDescending(x => x.GetParameters().Count()).First(); targetParent = ctor.Invoke(new object[ctor.GetParameters().Count()]); targetParentMetadata.GetProperty("ParentStringProperty").SetValue(targetParent, parentStringPropertyInput); targetParentMetadata.GetProperty("Values").SetValue(targetParent, valuesInput); } if (hasTargetSub) { var ctor = targetSubMetadata.GetConstructors().OrderByDescending(x => x.GetParameters().Count()).First(); var targetSub = ctor.Invoke(new object[ctor.GetParameters().Count()]); targetParentMetadata.GetProperty("OtherDto").SetValue(targetParent, targetSub); targetSubMetadata.GetProperty("NumberProp").SetValue(targetSub, numberPropInput); targetSubMetadata.GetProperty("NullableDateTimeProperty").SetValue(targetSub, nullableDateTimePropertyInput); targetSubMetadata.GetProperty("CamelCaseProperty").SetValue(targetSub, camelCasePropertyInput); } var patchedParent = parentDtoWrappedMetadata.GetMethod("ApplyPatch").Invoke(sut, new[] { targetParent }); var patchedSub = targetParentMetadata.GetProperty("OtherDto").GetValue(patchedParent); Assert.Equal(parentStringPropertyExpected, targetParentMetadata.GetProperty("ParentStringProperty").GetValue(patchedParent)); Assert.Equal(valuesExpected, targetParentMetadata.GetProperty("Values").GetValue(patchedParent)); Assert.Equal(numberPropExpected, targetSubMetadata.GetProperty("NumberProp").GetValue(patchedSub)); Assert.Equal(nullableDateTimePropertyExpected, targetSubMetadata.GetProperty("NullableDateTimeProperty").GetValue(patchedSub)); Assert.Equal(camelCasePropertyExpected, targetSubMetadata.GetProperty("CamelCaseProperty").GetValue(patchedSub)); }
public void WrappedSubDtoType_Sets_GeneratedProperties() { Compilation outputCompilation = CreateWrappedTypeCompilation(); var assembly = SourceBuilder.EmitToAssembly(outputCompilation); var wrappedTypeMetadata = assembly.GetType("LaDeak.JsonMergePatch.Generated.SafeTestCode.Dto1Wrapped"); var sut = wrappedTypeMetadata.GetConstructor(new Type[0]).Invoke(null); wrappedTypeMetadata.GetProperty("NumberProp").SetValue(sut, 100); Assert.Equal(100, wrappedTypeMetadata.GetProperty("NumberProp").GetValue(sut)); }
public void NullArgument_ApplyPatch_ReturnsObject() { Compilation outputCompilation = CreateWrappedTypeCompilation(); var assembly = SourceBuilder.EmitToAssembly(outputCompilation); var wrappedSubDtoMetadata = assembly.GetType("LaDeak.JsonMergePatch.Generated.SafeTestCode.Dto1Wrapped"); var sut = wrappedSubDtoMetadata.GetConstructor(new Type[0]).Invoke(null); var result = wrappedSubDtoMetadata.GetMethod("ApplyPatch").Invoke(sut, new object[] { null }); Assert.NotNull(result); }
public void WalkerReturnsNoFinding_Generate_ReturnsEmptyResults() { (Compilation inputCompilation, SyntaxTree tree) = SourceBuilder.Compile(SimpleTestCode); var walker = Substitute.For <IPatchParametersWalker>(); walker.Process(Arg.Any <SyntaxNode>(), Arg.Any <SemanticModel>()).Returns(Enumerable.Empty <ITypeSymbol>()); var typeBuilder = Substitute.For <ITypeBuilder>(); var sut = new MultiTypeBuilder(new[] { tree }, inputCompilation, typeBuilder, walker); var results = sut.Generate(); Assert.Empty(results); typeBuilder.DidNotReceive().BuildWrapperType(Arg.Any <ITypeSymbol>(), Arg.Any <string>()); }
public void WrappedDtoType_Sets_SubDtoProperty() { Compilation outputCompilation = CreateWrappedTypeCompilation(); var assembly = SourceBuilder.EmitToAssembly(outputCompilation); var wrappedDtoMetadata = assembly.GetType("LaDeak.JsonMergePatch.Generated.SafeTestCode.Dto2Wrapped"); var wrappedSubDtoMetadata = assembly.GetType("LaDeak.JsonMergePatch.Generated.SafeTestCode.Dto1Wrapped"); var sut = wrappedDtoMetadata.GetConstructor(new Type[0]).Invoke(null); var subDto = wrappedSubDtoMetadata.GetConstructor(new Type[0]).Invoke(null); wrappedDtoMetadata.GetProperty("OtherDto").SetValue(sut, subDto); Assert.Same(subDto, wrappedDtoMetadata.GetProperty("OtherDto").GetValue(sut)); }
public async Task No_PatchedType_EmptyResult() { string code = @" public class Controller { public void TestMethod1(SomeType input) { } }"; var compilation = SourceBuilder.Compile(code, new[] { MetadataReference.CreateFromFile(typeof(PatchParameterWalkerTests).Assembly.Location), MetadataReference.CreateFromFile(typeof(Patch <>).Assembly.Location) }); var sut = new PatchParametersWalker(); var result = sut.Process(await compilation.Tree.GetRootAsync(), compilation.Compilation.GetSemanticModel(compilation.Tree)); Assert.Empty(result); }
public async Task ReturnsGeneric_TypeOf_Patch() { string code = @" public class Controller { public class SomeType { } public void TestMethod(LaDeak.JsonMergePatch.Abstractions.Patch<SomeType> input) { } }"; var compilation = SourceBuilder.Compile(code, new[] { MetadataReference.CreateFromFile(typeof(PatchParameterWalkerTests).Assembly.Location), MetadataReference.CreateFromFile(typeof(Patch <>).Assembly.Location) }); var sut = new PatchParametersWalker(); var result = sut.Process(await compilation.Tree.GetRootAsync(), compilation.Compilation.GetSemanticModel(compilation.Tree)); Assert.Equal("SomeType", result.Single().Name); }
public void ApplyPatch_DoesNotSet_ReferencePropertyWithoutValue() { var compilation = CreateWrappedTypeCompilation(); var outputAssembly = SourceBuilder.EmitToAssembly(compilation); var wrappedTypeMetadata = outputAssembly.GetType("LaDeak.JsonMergePatch.Generated.SafeTestCode.Dto2Wrapped"); var sut = wrappedTypeMetadata.GetConstructor(new Type[0]).Invoke(null); var targetTypeMetadata = outputAssembly.GetType("TestCode.Dto2"); var targetObject = targetTypeMetadata.GetConstructor(new Type[0]).Invoke(null); targetTypeMetadata.GetProperty("Property").SetValue(targetObject, "hello world"); wrappedTypeMetadata.GetMethod("ApplyPatch").Invoke(sut, new[] { targetObject }); Assert.Equal("hello world", targetTypeMetadata.GetProperty("Property").GetValue(targetObject)); }
public void ApplyPatch_SetsPropertiesWithValues_ToTargetObject() { var compilation = CreateWrappedTypeCompilation(); var outputAssembly = SourceBuilder.EmitToAssembly(compilation); var wrappedTypeMetadata = outputAssembly.GetType("LaDeak.JsonMergePatch.Generated.SafeTestCode.Dto1Wrapped"); var sut = wrappedTypeMetadata.GetConstructor(new Type[0]).Invoke(null); wrappedTypeMetadata.GetProperty("NumberProp").SetValue(sut, 100); var targetTypeMetadata = outputAssembly.GetType("TestCode.Dto1"); var targetObject = targetTypeMetadata.GetConstructor(new Type[0]).Invoke(null); wrappedTypeMetadata.GetMethod("ApplyPatch").Invoke(sut, new[] { targetObject }); Assert.Equal(100, targetTypeMetadata.GetProperty("NumberProp").GetValue(targetObject)); }
public async Task RecordTypeWithPatchableArgument_Patch_ReturnsType() { string code = @" public class Controller { [LaDeak.JsonMergePatch.Abstractions.Patchable] public record SomeType(int Param); public record SomeOtherType(int Param); }"; var compilation = SourceBuilder.Compile(code, new[] { MetadataReference.CreateFromFile(typeof(PatchParameterWalkerTests).Assembly.Location), MetadataReference.CreateFromFile(typeof(Patch <>).Assembly.Location) }); var sut = new PatchParametersWalker(); var result = sut.Process(await compilation.Tree.GetRootAsync(), compilation.Compilation.GetSemanticModel(compilation.Tree)); Assert.Equal("SomeType", result.Single().Name); }
public async Task Returns_Multiple_PatchTypes() { string code = @" public class Controller { public class SomeType { } public void TestMethod1(LaDeak.JsonMergePatch.Abstractions.Patch<SomeType> input) { } public void TestMethod2(LaDeak.JsonMergePatch.Abstractions.Patch<bool> input) { } }"; var compilation = SourceBuilder.Compile(code, new[] { MetadataReference.CreateFromFile(typeof(PatchParameterWalkerTests).Assembly.Location), MetadataReference.CreateFromFile(typeof(Patch <>).Assembly.Location) }); var sut = new PatchParametersWalker(); var result = sut.Process(await compilation.Tree.GetRootAsync(), compilation.Compilation.GetSemanticModel(compilation.Tree)); Assert.Equal("SomeType", result.First().Name); Assert.Equal("Boolean", result.Last().Name); Assert.Equal("System", result.Last().ContainingNamespace.Name); }
public void ApplyPatch_PropertyToDelete_SetsNullOnTarget( string source, object input, object expected, string jsonInput) { var compilation = CreateWrappedTypeCompilation(source); var outputAssembly = SourceBuilder.EmitToAssembly(compilation); var dtoWrappedMetadata = outputAssembly.GetType("LaDeak.JsonMergePatch.Generated.SafeTestCode.DtoWrapped"); var targetMetadata = outputAssembly.GetType("TestCode.Dto"); var target = targetMetadata.GetConstructor(new Type[0]).Invoke(null); targetMetadata.GetProperty("Values").SetValue(target, input); var sut = JsonSerializer.Deserialize(jsonInput, dtoWrappedMetadata); var patchedParent = dtoWrappedMetadata.GetMethod("ApplyPatch").Invoke(sut, new[] { target }); Assert.Equal(expected, targetMetadata.GetProperty("Values").GetValue(patchedParent)); }
public void ApplyPatch_CallsApplyPath_OnSubDto() { Compilation outputCompilation = CreateWrappedTypeCompilation(); var assembly = SourceBuilder.EmitToAssembly(outputCompilation); var wrappedDtoMetadata = assembly.GetType("LaDeak.JsonMergePatch.Generated.SafeTestCode.Dto2Wrapped"); var wrappedSubDtoMetadata = assembly.GetType("LaDeak.JsonMergePatch.Generated.SafeTestCode.Dto1Wrapped"); var sut = wrappedDtoMetadata.GetConstructor(new Type[0]).Invoke(null); var subDto = wrappedSubDtoMetadata.GetConstructor(new Type[0]).Invoke(null); wrappedDtoMetadata.GetProperty("OtherDto").SetValue(sut, subDto); wrappedSubDtoMetadata.GetProperty("NumberProp").SetValue(subDto, 100); var result = wrappedDtoMetadata.GetMethod("ApplyPatch").Invoke(sut, new object[] { null }); var targetDtoMetadata = assembly.GetType("TestCode.Dto2"); var targetSubDtoMetadata = assembly.GetType("TestCode.Dto1"); var subDtoResult = targetDtoMetadata.GetProperty("OtherDto").GetValue(result); Assert.NotNull(subDtoResult); Assert.Equal(100, targetSubDtoMetadata.GetProperty("NumberProp").GetValue(subDtoResult)); }
public void GeneratedWrappersSource_SameAsReturnedByTypeBuilder() { (Compilation inputCompilation, SyntaxTree tree) = SourceBuilder.Compile(SimpleTestCode); var walker = Substitute.For <IPatchParametersWalker>(); walker.Process(Arg.Any <SyntaxNode>(), Arg.Any <SemanticModel>()).Returns(new[] { Substitute.For <ITypeSymbol>() }); var typeBuilder = Substitute.For <ITypeBuilder>(); var typeBuilderResult = new GeneratedWrapper() { ToProcessTypes = new List <ITypeSymbol>(), FileName = "file.cs", SourceCode = "namespace TestNameSpace { }", SourceTypeFullName = "Source.FullName", TargetTypeFullName = "Target.FullName" }; typeBuilder.BuildWrapperType(Arg.Any <ITypeSymbol>(), Arg.Any <string>()).Returns(typeBuilderResult); var sut = new MultiTypeBuilder(new[] { tree }, inputCompilation, typeBuilder, walker); var result = sut.Generate().Single(); Assert.Equal(typeBuilderResult.FileName, result.FileName); Assert.Equal(typeBuilderResult.SourceCode, result.SourceCode); Assert.Equal(typeBuilderResult.SourceTypeFullName, result.SourceTypeFullName); Assert.Equal(typeBuilderResult.TargetTypeFullName, result.TargetTypeFullName); }
private static Compilation CreateCompilation(string source) => SourceBuilder.Compile(source).Compilation;