Fix base constructor call issue.
This commit is contained in:
parent
1d7ca56916
commit
6ad7ea83f9
|
@ -20,9 +20,11 @@ namespace MapTo.Extensions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<ISymbol> GetAllMembers(this ITypeSymbol type)
|
public static IEnumerable<ISymbol> GetAllMembers(this ITypeSymbol type, bool includeBaseTypeMembers = true)
|
||||||
{
|
{
|
||||||
return type.GetBaseTypesAndThis().SelectMany(n => n.GetMembers());
|
return includeBaseTypeMembers
|
||||||
|
? type.GetBaseTypesAndThis().SelectMany(t => t.GetMembers())
|
||||||
|
: type.GetMembers();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CompilationUnitSyntax GetCompilationUnit(this SyntaxNode syntaxNode) => syntaxNode.Ancestors().OfType<CompilationUnitSyntax>().Single();
|
public static CompilationUnitSyntax GetCompilationUnit(this SyntaxNode syntaxNode) => syntaxNode.Ancestors().OfType<CompilationUnitSyntax>().Single();
|
||||||
|
|
|
@ -20,10 +20,6 @@
|
||||||
<RootNamespace>MapTo</RootNamespace>
|
<RootNamespace>MapTo</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
|
||||||
<DocumentationFile>bin\Debug\MapTo.xml</DocumentationFile>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||||
<DocumentationFile>bin\Release\MapTo.xml</DocumentationFile>
|
<DocumentationFile>bin\Release\MapTo.xml</DocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -57,8 +57,9 @@ namespace MapTo
|
||||||
|
|
||||||
var className = _classSyntax.GetClassName();
|
var className = _classSyntax.GetClassName();
|
||||||
var sourceClassName = sourceTypeSymbol.Name;
|
var sourceClassName = sourceTypeSymbol.Name;
|
||||||
|
var isClassInheritFromMappedBaseClass = IsClassInheritFromMappedBaseClass(semanticModel);
|
||||||
|
|
||||||
var mappedProperties = GetMappedProperties(classTypeSymbol, sourceTypeSymbol);
|
var mappedProperties = GetMappedProperties(classTypeSymbol, sourceTypeSymbol, isClassInheritFromMappedBaseClass);
|
||||||
if (!mappedProperties.Any())
|
if (!mappedProperties.Any())
|
||||||
{
|
{
|
||||||
ReportDiagnostic(DiagnosticProvider.NoMatchingPropertyFoundError(_classSyntax.GetLocation(), classTypeSymbol, sourceTypeSymbol));
|
ReportDiagnostic(DiagnosticProvider.NoMatchingPropertyFoundError(_classSyntax.GetLocation(), classTypeSymbol, sourceTypeSymbol));
|
||||||
|
@ -73,14 +74,24 @@ namespace MapTo
|
||||||
sourceTypeSymbol.ContainingNamespace.ToString(),
|
sourceTypeSymbol.ContainingNamespace.ToString(),
|
||||||
sourceClassName,
|
sourceClassName,
|
||||||
sourceTypeSymbol.ToString(),
|
sourceTypeSymbol.ToString(),
|
||||||
mappedProperties.ToImmutableArray());
|
mappedProperties.ToImmutableArray(),
|
||||||
|
isClassInheritFromMappedBaseClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImmutableArray<MappedProperty> GetMappedProperties(ITypeSymbol classSymbol, ITypeSymbol sourceTypeSymbol)
|
private bool IsClassInheritFromMappedBaseClass(SemanticModel semanticModel)
|
||||||
|
{
|
||||||
|
return _classSyntax.BaseList is not null && _classSyntax.BaseList.Types
|
||||||
|
.Select(t => semanticModel.GetTypeInfo(t.Type).Type)
|
||||||
|
.Any(t => t?.GetAttribute(_mapFromAttributeTypeSymbol) != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ImmutableArray<MappedProperty> GetMappedProperties(ITypeSymbol classSymbol, ITypeSymbol sourceTypeSymbol, bool isClassInheritFromMappedBaseClass)
|
||||||
{
|
{
|
||||||
var mappedProperties = new List<MappedProperty>();
|
var mappedProperties = new List<MappedProperty>();
|
||||||
var sourceProperties = sourceTypeSymbol.GetAllMembers().OfType<IPropertySymbol>().ToArray();
|
var sourceProperties = sourceTypeSymbol.GetAllMembers().OfType<IPropertySymbol>().ToArray();
|
||||||
var classProperties = classSymbol.GetAllMembers().OfType<IPropertySymbol>().Where(p => !p.HasAttribute(_ignorePropertyAttributeTypeSymbol));
|
var classProperties = classSymbol.GetAllMembers(!isClassInheritFromMappedBaseClass)
|
||||||
|
.OfType<IPropertySymbol>()
|
||||||
|
.Where(p => !p.HasAttribute(_ignorePropertyAttributeTypeSymbol));
|
||||||
|
|
||||||
foreach (var property in classProperties)
|
foreach (var property in classProperties)
|
||||||
{
|
{
|
||||||
|
@ -96,7 +107,7 @@ namespace MapTo
|
||||||
|
|
||||||
if (!_compilation.HasCompatibleTypes(sourceProperty, property))
|
if (!_compilation.HasCompatibleTypes(sourceProperty, property))
|
||||||
{
|
{
|
||||||
if (!TryGetMapTypeConverter(property, sourceProperty, out converterFullyQualifiedName, out converterParameters) &&
|
if (!TryGetMapTypeConverter(property, sourceProperty, out converterFullyQualifiedName, out converterParameters) &&
|
||||||
!TryGetNestedObjectMappings(property, out mappedSourcePropertyType))
|
!TryGetNestedObjectMappings(property, out mappedSourcePropertyType))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -104,11 +115,11 @@ namespace MapTo
|
||||||
}
|
}
|
||||||
|
|
||||||
mappedProperties.Add(new MappedProperty(
|
mappedProperties.Add(new MappedProperty(
|
||||||
property.Name,
|
property.Name,
|
||||||
property.Type.Name,
|
property.Type.Name,
|
||||||
converterFullyQualifiedName,
|
converterFullyQualifiedName,
|
||||||
converterParameters.ToImmutableArray(),
|
converterParameters.ToImmutableArray(),
|
||||||
sourceProperty.Name,
|
sourceProperty.Name,
|
||||||
mappedSourcePropertyType));
|
mappedSourcePropertyType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,12 +129,12 @@ namespace MapTo
|
||||||
private bool TryGetNestedObjectMappings(IPropertySymbol property, out string? mappedSourcePropertyType)
|
private bool TryGetNestedObjectMappings(IPropertySymbol property, out string? mappedSourcePropertyType)
|
||||||
{
|
{
|
||||||
mappedSourcePropertyType = null;
|
mappedSourcePropertyType = null;
|
||||||
|
|
||||||
if (!Diagnostics.IsEmpty)
|
if (!Diagnostics.IsEmpty)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var nestedSourceMapFromAttribute = property.Type.GetAttribute(_mapFromAttributeTypeSymbol);
|
var nestedSourceMapFromAttribute = property.Type.GetAttribute(_mapFromAttributeTypeSymbol);
|
||||||
if (nestedSourceMapFromAttribute is null)
|
if (nestedSourceMapFromAttribute is null)
|
||||||
{
|
{
|
||||||
|
@ -152,7 +163,7 @@ namespace MapTo
|
||||||
{
|
{
|
||||||
converterFullyQualifiedName = null;
|
converterFullyQualifiedName = null;
|
||||||
converterParameters = ImmutableArray<string>.Empty;
|
converterParameters = ImmutableArray<string>.Empty;
|
||||||
|
|
||||||
if (!Diagnostics.IsEmpty)
|
if (!Diagnostics.IsEmpty)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -204,7 +215,7 @@ namespace MapTo
|
||||||
? ImmutableArray<string>.Empty
|
? ImmutableArray<string>.Empty
|
||||||
: converterParameter.Values.Where(v => v.Value is not null).Select(v => v.Value!.ToSourceCodeString()).ToImmutableArray();
|
: converterParameter.Values.Where(v => v.Value is not null).Select(v => v.Value!.ToSourceCodeString()).ToImmutableArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReportDiagnostic(Diagnostic diagnostic)
|
private void ReportDiagnostic(Diagnostic diagnostic)
|
||||||
{
|
{
|
||||||
Diagnostics = Diagnostics.Add(diagnostic);
|
Diagnostics = Diagnostics.Add(diagnostic);
|
||||||
|
@ -219,7 +230,7 @@ namespace MapTo
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
semanticModel ??= _compilation.GetSemanticModel(attributeSyntax.SyntaxTree);
|
semanticModel ??= _compilation.GetSemanticModel(attributeSyntax.SyntaxTree);
|
||||||
var sourceTypeExpressionSyntax = attributeSyntax
|
var sourceTypeExpressionSyntax = attributeSyntax
|
||||||
.DescendantNodes()
|
.DescendantNodes()
|
||||||
|
|
|
@ -23,7 +23,8 @@ namespace MapTo
|
||||||
string SourceNamespace,
|
string SourceNamespace,
|
||||||
string SourceClassName,
|
string SourceClassName,
|
||||||
string SourceClassFullName,
|
string SourceClassFullName,
|
||||||
ImmutableArray<MappedProperty> MappedProperties
|
ImmutableArray<MappedProperty> MappedProperties,
|
||||||
|
bool HasMappedBaseClass
|
||||||
);
|
);
|
||||||
|
|
||||||
internal record SourceGenerationOptions(
|
internal record SourceGenerationOptions(
|
||||||
|
|
|
@ -61,8 +61,10 @@ namespace MapTo.Sources
|
||||||
.WriteLine($"/// <exception cref=\"ArgumentNullException\">{sourceClassParameterName} is null</exception>");
|
.WriteLine($"/// <exception cref=\"ArgumentNullException\">{sourceClassParameterName} is null</exception>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var baseConstructor = model.HasMappedBaseClass ? $" : base({sourceClassParameterName})" : string.Empty;
|
||||||
|
|
||||||
builder
|
builder
|
||||||
.WriteLine($"{model.Options.ConstructorAccessModifier.ToLowercaseString()} {model.ClassName}({model.SourceClassFullName} {sourceClassParameterName})")
|
.WriteLine($"{model.Options.ConstructorAccessModifier.ToLowercaseString()} {model.ClassName}({model.SourceClassFullName} {sourceClassParameterName}){baseConstructor}")
|
||||||
.WriteOpeningBracket()
|
.WriteOpeningBracket()
|
||||||
.WriteLine($"if ({sourceClassParameterName} == null) throw new ArgumentNullException(nameof({sourceClassParameterName}));")
|
.WriteLine($"if ({sourceClassParameterName} == null) throw new ArgumentNullException(nameof({sourceClassParameterName}));")
|
||||||
.WriteLine();
|
.WriteLine();
|
||||||
|
|
|
@ -34,6 +34,8 @@ namespace MapTo.Tests
|
||||||
builder.WriteLine("//");
|
builder.WriteLine("//");
|
||||||
builder.WriteLine();
|
builder.WriteLine();
|
||||||
|
|
||||||
|
options.Usings?.ForEach(s => builder.WriteLine($"using {s};"));
|
||||||
|
|
||||||
if (options.UseMapToNamespace)
|
if (options.UseMapToNamespace)
|
||||||
{
|
{
|
||||||
builder.WriteLine($"using {Constants.RootNamespace};");
|
builder.WriteLine($"using {Constants.RootNamespace};");
|
||||||
|
@ -94,6 +96,76 @@ namespace MapTo.Tests
|
||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static string[] GetEmployeeManagerSourceText(Func<string> employeeClassSource = null, Func<string> managerClassSource = null, Func<string> employeeViewModelSource = null, Func<string> managerViewModelSource = null)
|
||||||
|
{
|
||||||
|
return new[]
|
||||||
|
{
|
||||||
|
employeeClassSource?.Invoke() ?? @"
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Test.Data.Models
|
||||||
|
{
|
||||||
|
public class Employee
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string EmployeeCode { get; set; }
|
||||||
|
|
||||||
|
public Manager Manager { get; set; }
|
||||||
|
}
|
||||||
|
}".Trim(),
|
||||||
|
managerClassSource?.Invoke() ?? @"using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Test.Data.Models
|
||||||
|
{
|
||||||
|
public class Manager: Employee
|
||||||
|
{
|
||||||
|
public int Level { get; set; }
|
||||||
|
|
||||||
|
public IEnumerable<Employee> Employees { get; set; } = Array.Empty<Employee>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
".Trim(),
|
||||||
|
employeeViewModelSource?.Invoke() ?? @"
|
||||||
|
using MapTo;
|
||||||
|
using Test.Data.Models;
|
||||||
|
|
||||||
|
namespace Test.ViewModels
|
||||||
|
{
|
||||||
|
[MapFrom(typeof(Employee))]
|
||||||
|
public partial class EmployeeViewModel
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string EmployeeCode { get; set; }
|
||||||
|
|
||||||
|
public ManagerViewModel Manager { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
".Trim(),
|
||||||
|
managerViewModelSource?.Invoke() ?? @"
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MapTo;
|
||||||
|
using Test.Data.Models;
|
||||||
|
|
||||||
|
namespace Test.ViewModels
|
||||||
|
{
|
||||||
|
[MapFrom(typeof(Manager))]
|
||||||
|
public partial class ManagerViewModel : EmployeeViewModel
|
||||||
|
{
|
||||||
|
public int Level { get; set; }
|
||||||
|
|
||||||
|
public IEnumerable<EmployeeViewModel> Employees { get; set; } = Array.Empty<EmployeeViewModel>();
|
||||||
|
}
|
||||||
|
}".Trim()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
internal static PropertyDeclarationSyntax GetPropertyDeclarationSyntax(SyntaxTree syntaxTree, string targetPropertyName, string targetClass = "Foo")
|
internal static PropertyDeclarationSyntax GetPropertyDeclarationSyntax(SyntaxTree syntaxTree, string targetPropertyName, string targetClass = "Foo")
|
||||||
{
|
{
|
||||||
return syntaxTree.GetRoot()
|
return syntaxTree.GetRoot()
|
||||||
|
@ -120,6 +192,7 @@ namespace MapTo.Tests
|
||||||
int ClassPropertiesCount = 3,
|
int ClassPropertiesCount = 3,
|
||||||
int SourceClassPropertiesCount = 3,
|
int SourceClassPropertiesCount = 3,
|
||||||
Action<SourceBuilder> PropertyBuilder = null,
|
Action<SourceBuilder> PropertyBuilder = null,
|
||||||
Action<SourceBuilder> SourcePropertyBuilder = null);
|
Action<SourceBuilder> SourcePropertyBuilder = null,
|
||||||
|
IEnumerable<string> Usings = null);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,10 +21,17 @@ namespace MapTo.Tests.Extensions
|
||||||
syntax.ShouldBe(expectedSource, customMessage);
|
syntax.ShouldBe(expectedSource, customMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void ShouldBeSuccessful(this IEnumerable<Diagnostic> diagnostics, Compilation compilation = null)
|
internal static void ShouldContainPartialSource(this SyntaxTree syntaxTree, string expectedSource, string customMessage = null)
|
||||||
|
{
|
||||||
|
var syntax = syntaxTree.ToString();
|
||||||
|
syntax.ShouldNotBeNullOrWhiteSpace();
|
||||||
|
syntax.ShouldContainWithoutWhitespace(expectedSource, customMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void ShouldBeSuccessful(this IEnumerable<Diagnostic> diagnostics, Compilation compilation = null, IEnumerable<string> ignoreDiagnosticsIds = null)
|
||||||
{
|
{
|
||||||
var actual = diagnostics
|
var actual = diagnostics
|
||||||
.Where(d => !d.Id.StartsWith("MT") && (d.Severity == DiagnosticSeverity.Warning || d.Severity == DiagnosticSeverity.Error))
|
.Where(d => (ignoreDiagnosticsIds is null || ignoreDiagnosticsIds.All(i => !d.Id.StartsWith(i) )) && (d.Severity == DiagnosticSeverity.Warning || d.Severity == DiagnosticSeverity.Error))
|
||||||
.Select(c => $"{c.Severity}: {c.Location.GetLineSpan()} - {c.GetMessage()}").ToArray();
|
.Select(c => $"{c.Severity}: {c.Location.GetLineSpan()} - {c.GetMessage()}").ToArray();
|
||||||
|
|
||||||
if (!actual.Any())
|
if (!actual.Any())
|
||||||
|
|
|
@ -67,7 +67,7 @@ namespace MapTo
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
diagnostics.ShouldBeSuccessful();
|
diagnostics.ShouldBeSuccessful();
|
||||||
compilation.SyntaxTrees.Last().ToString().ShouldContain(expectedResult);
|
compilation.SyntaxTrees.Last().ShouldContainPartialSource(expectedResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -76,7 +76,7 @@ namespace MapTo
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
diagnostics.ShouldBeSuccessful();
|
diagnostics.ShouldBeSuccessful();
|
||||||
compilation.SyntaxTrees.Last().ToString().ShouldContain(expectedResult);
|
compilation.SyntaxTrees.Last().ShouldContainPartialSource(expectedResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -286,7 +286,7 @@ namespace Test
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
diagnostics.ShouldBeSuccessful();
|
diagnostics.ShouldBeSuccessful();
|
||||||
compilation.SyntaxTrees.Last().ToString().ShouldContain(expectedResult.Trim());
|
compilation.SyntaxTrees.Last().ShouldContainPartialSource(expectedResult.Trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -307,7 +307,7 @@ namespace Test
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
diagnostics.ShouldBeSuccessful();
|
diagnostics.ShouldBeSuccessful();
|
||||||
compilation.SyntaxTrees.Last().ToString().ShouldContain(expectedResult.Trim());
|
compilation.SyntaxTrees.Last().ShouldContainPartialSource(expectedResult.Trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -331,7 +331,7 @@ namespace Test
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
diagnostics.ShouldBeSuccessful();
|
diagnostics.ShouldBeSuccessful();
|
||||||
compilation.SyntaxTrees.Last().ToString().ShouldContain(expectedResult.Trim());
|
compilation.SyntaxTrees.Last().ShouldContainPartialSource(expectedResult.Trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -372,7 +372,7 @@ namespace Test
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
diagnostics.ShouldBeSuccessful();
|
diagnostics.ShouldBeSuccessful();
|
||||||
compilation.SyntaxTrees.ToArray()[^2].ToString().ShouldContain(expectedResult);
|
compilation.SyntaxTrees.ToArray()[^2].ShouldContainPartialSource(expectedResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -429,5 +429,59 @@ namespace Test
|
||||||
var expectedError = DiagnosticProvider.NoMatchingPropertyTypeFoundError(GetSourcePropertySymbol("InnerProp1", compilation));
|
var expectedError = DiagnosticProvider.NoMatchingPropertyTypeFoundError(GetSourcePropertySymbol("InnerProp1", compilation));
|
||||||
diagnostics.ShouldBeUnsuccessful(expectedError);
|
diagnostics.ShouldBeUnsuccessful(expectedError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void When_SourceTypeEnumerableProperties_Should_CreateConstructorAndAssignSrcToDest()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var source = GetSourceText(new SourceGeneratorOptions(
|
||||||
|
Usings: new[] { "System.Collections.Generic"},
|
||||||
|
PropertyBuilder: builder => builder.WriteLine("public IEnumerable<int> Prop4 { get; }"),
|
||||||
|
SourcePropertyBuilder: builder => builder.WriteLine("public IEnumerable<int> Prop4 { get; }")));
|
||||||
|
|
||||||
|
const string expectedResult = @"
|
||||||
|
partial class Foo
|
||||||
|
{
|
||||||
|
public Foo(Test.Models.Baz baz)
|
||||||
|
{
|
||||||
|
if (baz == null) throw new ArgumentNullException(nameof(baz));
|
||||||
|
|
||||||
|
Prop1 = baz.Prop1;
|
||||||
|
Prop2 = baz.Prop2;
|
||||||
|
Prop3 = baz.Prop3;
|
||||||
|
Prop4 = baz.Prop4;
|
||||||
|
}
|
||||||
|
";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var (compilation, diagnostics) = CSharpGenerator.GetOutputCompilation(source, analyzerConfigOptions: DefaultAnalyzerOptions);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
diagnostics.ShouldBeSuccessful();
|
||||||
|
compilation.SyntaxTrees.Last().ShouldContainPartialSource(expectedResult.Trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void When_DestinationTypeHasBaseClass_Should_CallBaseConstructor()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var sources = GetEmployeeManagerSourceText();
|
||||||
|
|
||||||
|
const string expectedResult = @"
|
||||||
|
public ManagerViewModel(Test.Data.Models.Manager manager) : base(manager)
|
||||||
|
{
|
||||||
|
if (manager == null) throw new ArgumentNullException(nameof(manager));
|
||||||
|
|
||||||
|
Level = manager.Level;
|
||||||
|
}
|
||||||
|
";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var (compilation, diagnostics) = CSharpGenerator.GetOutputCompilation(sources, analyzerConfigOptions: DefaultAnalyzerOptions);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
diagnostics.ShouldBeSuccessful();
|
||||||
|
compilation.SyntaxTrees.Last().ShouldContainPartialSource(expectedResult);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -168,7 +168,7 @@ namespace Test
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
diagnostics.ShouldBeSuccessful();
|
diagnostics.ShouldBeSuccessful();
|
||||||
compilation.SyntaxTrees.Last().ToString().ShouldContain(expectedSyntax);
|
compilation.SyntaxTrees.Last().ShouldContainPartialSource(expectedSyntax);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -204,7 +204,7 @@ namespace Test
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
diagnostics.ShouldBeSuccessful();
|
diagnostics.ShouldBeSuccessful();
|
||||||
compilation.SyntaxTrees.Last().ToString().ShouldContain(expectedSyntax);
|
compilation.SyntaxTrees.Last().ShouldContainPartialSource(expectedSyntax);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -235,7 +235,7 @@ namespace Test
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
diagnostics.ShouldBeSuccessful();
|
diagnostics.ShouldBeSuccessful();
|
||||||
compilation.SyntaxTrees.Last().ToString().ShouldContain(expectedResult);
|
compilation.SyntaxTrees.Last().ShouldContainPartialSource(expectedResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace TestConsoleApp.Data.Models
|
||||||
|
{
|
||||||
|
public class Employee
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string EmployeeCode { get; set; }
|
||||||
|
|
||||||
|
public Manager Manager { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace TestConsoleApp.Data.Models
|
||||||
|
{
|
||||||
|
public class Manager: Employee
|
||||||
|
{
|
||||||
|
public int Level { get; set; }
|
||||||
|
|
||||||
|
public IEnumerable<Employee> Employees { get; set; } = Array.Empty<Employee>();
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,45 @@ namespace TestConsoleApp
|
||||||
internal class Program
|
internal class Program
|
||||||
{
|
{
|
||||||
private static void Main(string[] args)
|
private static void Main(string[] args)
|
||||||
|
{
|
||||||
|
//UserTest();
|
||||||
|
var manager1 = new Manager
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
EmployeeCode = "M001",
|
||||||
|
Level = 100
|
||||||
|
};
|
||||||
|
|
||||||
|
var manager2 = new Manager
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
EmployeeCode = "M002",
|
||||||
|
Level = 100,
|
||||||
|
Manager = manager1
|
||||||
|
};
|
||||||
|
|
||||||
|
var employee1 = new Employee
|
||||||
|
{
|
||||||
|
Id = 101,
|
||||||
|
EmployeeCode = "E101",
|
||||||
|
Manager = manager1
|
||||||
|
};
|
||||||
|
|
||||||
|
var employee2 = new Employee
|
||||||
|
{
|
||||||
|
Id = 102,
|
||||||
|
EmployeeCode = "E102",
|
||||||
|
Manager = manager2
|
||||||
|
};
|
||||||
|
|
||||||
|
manager1.Employees = new[] { employee1, manager2 };
|
||||||
|
manager2.Employees = new[] { employee2 };
|
||||||
|
|
||||||
|
var manager1ViewModel = manager1.ToManagerViewModel();
|
||||||
|
int a = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UserTest()
|
||||||
{
|
{
|
||||||
var user = new User
|
var user = new User
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
using MapTo;
|
||||||
|
using TestConsoleApp.Data.Models;
|
||||||
|
|
||||||
|
namespace TestConsoleApp.ViewModels
|
||||||
|
{
|
||||||
|
[MapFrom(typeof(Employee))]
|
||||||
|
public partial class EmployeeViewModel
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string EmployeeCode { get; set; }
|
||||||
|
|
||||||
|
public ManagerViewModel Manager { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MapTo;
|
||||||
|
using TestConsoleApp.Data.Models;
|
||||||
|
|
||||||
|
namespace TestConsoleApp.ViewModels
|
||||||
|
{
|
||||||
|
[MapFrom(typeof(Manager))]
|
||||||
|
public partial class ManagerViewModel : EmployeeViewModel
|
||||||
|
{
|
||||||
|
public int Level { get; set; }
|
||||||
|
|
||||||
|
public IEnumerable<EmployeeViewModel> Employees { get; set; } = Array.Empty<EmployeeViewModel>();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue