MapTo/test/MapTo.Tests/MapPropertyTests.cs

202 lines
6.6 KiB
C#
Raw Permalink Normal View History

2021-01-30 11:59:39 +03:00
using System;
using System.Collections.Generic;
2021-01-30 11:59:39 +03:00
using System.Linq;
using MapTo.Sources;
using MapTo.Tests.Extensions;
using MapTo.Tests.Infrastructure;
using Microsoft.CodeAnalysis;
2021-04-09 09:48:23 +03:00
using Microsoft.CodeAnalysis.CSharp;
2021-01-30 11:59:39 +03:00
using Xunit;
using static MapTo.Tests.Common;
namespace MapTo.Tests
{
public class MapPropertyTests
{
[Theory]
[InlineData(NullableContextOptions.Disable)]
[InlineData(NullableContextOptions.Enable)]
public void VerifyMapPropertyAttribute(NullableContextOptions nullableContextOptions)
{
// Arrange
const string source = "";
var nullableSyntax = nullableContextOptions == NullableContextOptions.Enable ? "?" : string.Empty;
2021-04-09 09:48:23 +03:00
var languageVersion = nullableContextOptions == NullableContextOptions.Enable ? LanguageVersion.CSharp8 : LanguageVersion.CSharp7_3;
2021-01-30 11:59:39 +03:00
var expectedInterface = $@"
{Constants.GeneratedFilesHeader}
{(nullableContextOptions == NullableContextOptions.Enable ? $"#nullable enable{Environment.NewLine}" : string.Empty)}
using System;
namespace MapTo
{{
2021-06-30 21:16:28 +03:00
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = true)]
2021-01-30 11:59:39 +03:00
public sealed class MapPropertyAttribute : Attribute
{{
public string{nullableSyntax} SourcePropertyName {{ get; set; }}
}}
}}
".Trim();
// Act
2021-04-09 09:48:23 +03:00
var (compilation, diagnostics) = CSharpGenerator.GetOutputCompilation(source, analyzerConfigOptions: DefaultAnalyzerOptions, nullableContextOptions: nullableContextOptions, languageVersion: languageVersion);
2021-01-30 11:59:39 +03:00
2021-04-09 09:48:23 +03:00
2021-01-30 11:59:39 +03:00
// Assert
diagnostics.ShouldBeSuccessful();
compilation.SyntaxTrees.ShouldContainSource(MapPropertyAttributeSource.AttributeName, expectedInterface);
}
[Fact]
public void When_MapPropertyFound_Should_UseItToMapToSourceProperty()
{
// Arrange
var source = GetSourceText(new SourceGeneratorOptions(
true,
PropertyBuilder: builder =>
{
builder
.WriteLine("[MapProperty(SourcePropertyName = nameof(Baz.Prop3))]")
.WriteLine("public int Prop4 { get; set; }");
2021-01-30 11:59:39 +03:00
},
SourcePropertyBuilder: builder => builder.WriteLine("public int Prop4 { get; set; }")));
2021-01-30 11:59:39 +03:00
var expectedResult = @"
partial class Foo
{
2021-07-02 11:24:46 +03:00
public Foo(Test.Models.Baz baz)
2021-04-09 09:48:23 +03:00
: this(new MappingContext(), baz) { }
2021-07-02 11:24:46 +03:00
private protected Foo(MappingContext context, Test.Models.Baz baz)
2021-01-30 11:59:39 +03:00
{
2021-04-09 09:48:23 +03:00
if (context == null) throw new ArgumentNullException(nameof(context));
2021-01-30 11:59:39 +03:00
if (baz == null) throw new ArgumentNullException(nameof(baz));
2021-04-09 09:48:23 +03:00
context.Register(baz, this);
2021-01-30 11:59:39 +03:00
Prop1 = baz.Prop1;
Prop2 = baz.Prop2;
Prop3 = baz.Prop3;
Prop4 = baz.Prop3;
}
".Trim();
// Act
var (compilation, diagnostics) = CSharpGenerator.GetOutputCompilation(source, analyzerConfigOptions: DefaultAnalyzerOptions);
// Assert
diagnostics.ShouldBeSuccessful();
2021-02-13 14:27:32 +03:00
compilation.SyntaxTrees.Last().ShouldContainPartialSource(expectedResult);
2021-01-30 11:59:39 +03:00
}
[Theory]
[MemberData(nameof(MapPropertyWithImplicitConversionFoundData))]
public void When_MapPropertyWithImplicitConversionFound_Should_UseItToMapToSourceProperty(string source, string expectedResult, LanguageVersion languageVersion)
{
// Arrange
source = source.Trim();
// Act
var (compilation, diagnostics) = CSharpGenerator.GetOutputCompilation(source, analyzerConfigOptions: DefaultAnalyzerOptions, languageVersion: languageVersion);
// Assert
diagnostics.ShouldBeSuccessful();
compilation.SyntaxTrees.Last().ShouldContainPartialSource(expectedResult);
}
public static IEnumerable<object[]> MapPropertyWithImplicitConversionFoundData => new List<object[]>
{
new object[]
{
@"
2021-07-02 16:55:50 +03:00
namespace Test
{
using System.Collections.Generic;
public class InnerClass { public int Prop1 { get; set; } }
2021-07-02 16:55:50 +03:00
public class OuterClass
{
public int Id { get; set; }
public List<InnerClass> InnerProp { get; set; }
}
}
namespace Test.Models
{
using MapTo;
using System.Collections.Generic;
[MapFrom(typeof(Test.InnerClass))]
public partial class InnerClass { public int Prop1 { get; set; } }
[MapFrom(typeof(Test.OuterClass))]
2021-07-02 16:55:50 +03:00
public partial class OuterClass
{
public int Id { get; set; }
public IReadOnlyList<InnerClass> InnerProp { get; set; }
}
}
",
@"
private protected OuterClass(MappingContext context, Test.OuterClass outerClass)
{
if (context == null) throw new ArgumentNullException(nameof(context));
if (outerClass == null) throw new ArgumentNullException(nameof(outerClass));
context.Register(outerClass, this);
Id = outerClass.Id;
InnerProp = outerClass.InnerProp.Select(context.MapFromWithContext<Test.InnerClass, InnerClass>).ToList();
}
",
LanguageVersion.CSharp7_3
},
new object[]
{
@"
namespace Test
{
2021-07-02 16:55:50 +03:00
using System;
using System.Collections.Generic;
2021-07-02 16:55:50 +03:00
public class InnerClass
{
public int Id { get; set; }
public string Name { get; set; }
}
public class OuterClass
{
public int Id { get; set; }
public List<InnerClass> InnerClasses { get; set; }
public DateTime? SomeDate { get; set; }
}
}
namespace Test.Models
{
using MapTo;
2021-07-02 16:55:50 +03:00
using System;
using System.Collections.Generic;
[MapFrom(typeof(Test.InnerClass))]
2021-07-02 16:55:50 +03:00
public partial record InnerClass(int Id, string Name);
[MapFrom(typeof(Test.OuterClass))]
2021-07-02 16:55:50 +03:00
public partial record OuterClass(int Id, DateTime? SomeDate, IReadOnlyList<InnerClass> InnerClasses);
}
",
@"
private protected OuterClass(MappingContext context, Test.OuterClass outerClass)
2021-07-02 16:55:50 +03:00
: this(Id: outerClass.Id, SomeDate: outerClass.SomeDate, InnerClasses: outerClass.InnerClasses.Select(context.MapFromWithContext<Test.InnerClass, InnerClass>).ToList())
{
if (context == null) throw new ArgumentNullException(nameof(context));
if (outerClass == null) throw new ArgumentNullException(nameof(outerClass));
context.Register(outerClass, this);
}
",
LanguageVersion.CSharp9
}
};
2021-01-30 11:59:39 +03:00
}
}