Пример #1
0
        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());
        }
Пример #2
0
        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);
        }
Пример #4
0
        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));
        }
Пример #6
0
        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));
        }
Пример #7
0
        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);
        }
Пример #8
0
        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>());
        }
Пример #9
0
        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));
        }
Пример #10
0
        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);
        }
Пример #11
0
        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);
        }
Пример #12
0
        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));
        }
Пример #13
0
        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));
        }
Пример #14
0
        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);
        }
Пример #15
0
        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));
        }
Пример #17
0
        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));
        }
Пример #18
0
        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;