Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion PanoramicData.Mapper.Test/AfterMapTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public void Process(SimpleSource source, SimpleDestination destination, Resoluti
}
}

private class AfterMapGenericProfile : Profile
private sealed class AfterMapGenericProfile : Profile
{
public AfterMapGenericProfile()
{
Expand Down
4 changes: 2 additions & 2 deletions PanoramicData.Mapper.Test/BeforeMapTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public void BeforeMap_MappingAction_ExecutesBeforeMapping()
dest.Tag.Should().Be("action-tag");
}

private class BeforeMapLambdaProfile : Profile
private sealed class BeforeMapLambdaProfile : Profile
{
public BeforeMapLambdaProfile()
{
Expand All @@ -51,7 +51,7 @@ public void Process(BeforeMapSource _source, BeforeMapDest destination, Resoluti
}
}

private class BeforeMapActionProfile : Profile
private sealed class BeforeMapActionProfile : Profile
{
public BeforeMapActionProfile()
{
Expand Down
2 changes: 1 addition & 1 deletion PanoramicData.Mapper.Test/CollectionMappingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public void Map_NoElementTypeMap_ThrowsAutoMapperMappingException()
act.Should().Throw<AutoMapperMappingException>();
}

private class ElementProfile : Profile
private sealed class ElementProfile : Profile
{
public ElementProfile()
{
Expand Down
4 changes: 2 additions & 2 deletions PanoramicData.Mapper.Test/ConditionalMappingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public void PreCondition_WhenTrue_MapsValue()
dest.Age.Should().Be(30);
}

private class ConditionProfile : Profile
private sealed class ConditionProfile : Profile
{
public ConditionProfile()
{
Expand All @@ -69,7 +69,7 @@ public ConditionProfile()
}
}

private class PreConditionProfile : Profile
private sealed class PreConditionProfile : Profile
{
public PreConditionProfile()
{
Expand Down
4 changes: 2 additions & 2 deletions PanoramicData.Mapper.Test/ConstructionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public void ForCtorParam_MapsConstructorParameters()
dest.Age.Should().Be(30);
}

private class ConstructUsingProfile : Profile
private sealed class ConstructUsingProfile : Profile
{
public ConstructUsingProfile()
{
Expand All @@ -41,7 +41,7 @@ public ConstructUsingProfile()
}
}

private class CtorParamProfile : Profile
private sealed class CtorParamProfile : Profile
{
public CtorParamProfile()
{
Expand Down
93 changes: 90 additions & 3 deletions PanoramicData.Mapper.Test/FlatteningTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,27 +114,114 @@ public void AssertConfigurationIsValid_DeepFlatten_DoesNotThrow()
act.Should().NotThrow();
}

private class FlattenProfile : Profile
[Fact]
public void Map_Flattening_CalledTwice_ReturnsSameResult()
{
// Maps the same type pair twice; the second call hits the flattened accessor cache.
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new FlattenProfile());
});
var mapper = config.CreateMapper();

var source = new CustomerSource { Id = 7, Customer = new CustomerNameSource { Name = "Bob", Age = 25 } };

var first = mapper.Map<FlatCustomerDest>(source);
var second = mapper.Map<FlatCustomerDest>(source);

second.CustomerName.Should().Be(first.CustomerName);
second.CustomerAge.Should().Be(first.CustomerAge);
}

[Fact]
public void Map_Flattening_DifferentSourceTypes_SameDestPropertyName_MapsIndependently()
{
// CustomerSourceA and CustomerSourceB both flatten to CustomerName,
// verifying the cache key is (destPropName, sourceType) not just destPropName.
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new FlattenAProfile());
cfg.AddProfile(new FlattenBProfile());
});
var mapper = config.CreateMapper();

var sourceA = new CustomerSourceA { Id = 1, Customer = new CustomerNameSourceA { Name = "Alpha" } };
var sourceB = new CustomerSourceB { Id = 2, Customer = new CustomerNameSourceB { Name = "Beta" } };

var destA = mapper.Map<FlatCustomerDestAB>(sourceA);
var destB = mapper.Map<FlatCustomerDestAB>(sourceB);

destA.CustomerName.Should().Be("Alpha");
destB.CustomerName.Should().Be("Beta");
}

[Fact]
public void Map_Flattening_NoMatchingNestedProperty_LeavesDestinationDefault()
{
// Destination has a property that has no flattened match; result should be default.
// Also verifies a null/miss is cached and doesn't cause a second lookup to misbehave.
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new FlattenIgnoredProfile());
});
var mapper = config.CreateMapper();

var source = new CustomerSource { Id = 3, Customer = new CustomerNameSource { Name = "Carol", Age = 40 } };

var first = mapper.Map<FlatCustomerDest>(source);
var second = mapper.Map<FlatCustomerDest>(source);

first.CustomerName.Should().BeNullOrEmpty();
second.CustomerName.Should().BeNullOrEmpty();
}

private sealed class FlattenProfile : Profile
{
public FlattenProfile()
{
CreateMap<CustomerSource, FlatCustomerDest>();
}
}

private class DeepFlattenProfile : Profile
private sealed class DeepFlattenProfile : Profile
{
public DeepFlattenProfile()
{
CreateMap<DeepSource, DeepFlatDest>();
}
}

private class GetterProfile : Profile
private sealed class GetterProfile : Profile
{
public GetterProfile()
{
CreateMap<GetterSource, GetterDest>();
}
}

private sealed class FlattenAProfile : Profile
{
public FlattenAProfile()
{
CreateMap<CustomerSourceA, FlatCustomerDestAB>();
}
}

private sealed class FlattenBProfile : Profile
{
public FlattenBProfile()
{
CreateMap<CustomerSourceB, FlatCustomerDestAB>();
}
}

private sealed class FlattenIgnoredProfile : Profile
{
public FlattenIgnoredProfile()
{
CreateMap<CustomerSource, FlatCustomerDest>()
.ForMember(d => d.CustomerName, opt => opt.Ignore())
.ForMember(d => d.CustomerAge, opt => opt.Ignore());
}
}
}
2 changes: 1 addition & 1 deletion PanoramicData.Mapper.Test/ForPathTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void ForPath_ConfigurationIsValid_DoesNotThrow()
config.AssertConfigurationIsValid();
}

private class ForPathProfile : Profile
private sealed class ForPathProfile : Profile
{
public ForPathProfile()
{
Expand Down
4 changes: 2 additions & 2 deletions PanoramicData.Mapper.Test/IgnoreInaccessibleSetterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private class InaccessibleDest
public int Value { get; set; }
}

private class InaccessibleSetterProfile : Profile
private sealed class InaccessibleSetterProfile : Profile
{
public InaccessibleSetterProfile()
{
Expand All @@ -80,7 +80,7 @@ private class InitOnlyDest
public string InitOnly { get; init; } = "init-default";
}

private class InitOnlyProfile : Profile
private sealed class InitOnlyProfile : Profile
{
public InitOnlyProfile()
{
Expand Down
2 changes: 1 addition & 1 deletion PanoramicData.Mapper.Test/IgnoreTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public void IgnoreAttribute_SkipsProperty()
dest.Secret.Should().Be("original");
}

private class TestProfile : Profile
private sealed class TestProfile : Profile
{
public TestProfile()
{
Expand Down
6 changes: 3 additions & 3 deletions PanoramicData.Mapper.Test/InheritanceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void IncludeAllDerived_AutomaticallyMapsDerivedTypes()
dest.Breed.Should().Be("Poodle");
}

private class IncludeProfile : Profile
private sealed class IncludeProfile : Profile
{
public IncludeProfile()
{
Expand All @@ -60,7 +60,7 @@ public IncludeProfile()
}
}

private class IncludeBaseProfile : Profile
private sealed class IncludeBaseProfile : Profile
{
public IncludeBaseProfile()
{
Expand All @@ -71,7 +71,7 @@ public IncludeBaseProfile()
}
}

private class IncludeAllDerivedProfile : Profile
private sealed class IncludeAllDerivedProfile : Profile
{
public IncludeAllDerivedProfile()
{
Expand Down
2 changes: 1 addition & 1 deletion PanoramicData.Mapper.Test/MaxDepthTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public void MaxDepth_WithinLimit_MapsFullDepth()
dest.Child.Child.Should().BeNull();
}

private class MaxDepthProfile : Profile
private sealed class MaxDepthProfile : Profile
{
public MaxDepthProfile()
{
Expand Down
32 changes: 32 additions & 0 deletions PanoramicData.Mapper.Test/Models/TestModels.cs
Original file line number Diff line number Diff line change
Expand Up @@ -504,4 +504,36 @@ public class EnumToEnumSource
public class EnumToEnumDestination
{
public MyStatus Status { get; set; }
}

// --- Flattening cache tests ---

// Two different source types that both have a nested "Customer.Name" shape,
// used to verify the cache key includes the source type.
public class CustomerSourceA
{
public int Id { get; set; }
public CustomerNameSourceA Customer { get; set; } = new();
}

public class CustomerNameSourceA
{
public string Name { get; set; } = string.Empty;
}

public class CustomerSourceB
{
public int Id { get; set; }
public CustomerNameSourceB Customer { get; set; } = new();
}

public class CustomerNameSourceB
{
public string Name { get; set; } = string.Empty;
}

public class FlatCustomerDestAB
{
public int Id { get; set; }
public string CustomerName { get; set; } = string.Empty;
}
4 changes: 2 additions & 2 deletions PanoramicData.Mapper.Test/NestedMappingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public void AssertConfigurationIsValid_NestedMapping_DoesNotThrow()
act.Should().NotThrow();
}

private class NestedProfile : Profile
private sealed class NestedProfile : Profile
{
public NestedProfile()
{
Expand All @@ -100,7 +100,7 @@ public NestedProfile()
}
}

private class NestedCollectionProfile : Profile
private sealed class NestedCollectionProfile : Profile
{
public NestedCollectionProfile()
{
Expand Down
2 changes: 1 addition & 1 deletion PanoramicData.Mapper.Test/NullSubstituteTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public void NullSubstitute_WhenSourceNotNull_UsesSourceValue()
dest.Email.Should().Be("alice@test.com");
}

private class NullSubProfile : Profile
private sealed class NullSubProfile : Profile
{
public NullSubProfile()
{
Expand Down
2 changes: 1 addition & 1 deletion PanoramicData.Mapper.Test/OpenGenericTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public void OpenGeneric_DifferentClosedTypes_MapIndependently()
stringDest.Label.Should().Be("String");
}

private class OpenGenericProfile : Profile
private sealed class OpenGenericProfile : Profile
{
public OpenGenericProfile()
{
Expand Down
6 changes: 3 additions & 3 deletions PanoramicData.Mapper.Test/ProjectToTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,15 @@ private static void SeedData(TestDbContext context)
context.SaveChanges();
}

private class SimpleProjectProfile : Profile
private sealed class SimpleProjectProfile : Profile
{
public SimpleProjectProfile()
{
CreateMap<SimpleSource, SimpleDestination>();
}
}

private class PersonProjectProfile : Profile
private sealed class PersonProjectProfile : Profile
{
public PersonProjectProfile()
{
Expand All @@ -112,7 +112,7 @@ public PersonProjectProfile()
}
}

private class IgnoreProjectProfile : Profile
private sealed class IgnoreProjectProfile : Profile
{
public IgnoreProjectProfile()
{
Expand Down
2 changes: 1 addition & 1 deletion PanoramicData.Mapper.Test/ReverseMapTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void ReverseMap_ConfigurationIsValid_DoesNotThrow()
config.AssertConfigurationIsValid();
}

private class ReverseMapProfile : Profile
private sealed class ReverseMapProfile : Profile
{
public ReverseMapProfile()
{
Expand Down
6 changes: 3 additions & 3 deletions PanoramicData.Mapper.Test/TypeConverterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public ConverterDest Convert(ConverterSource source, ConverterDest _destination,
=> new() { Result = string.Concat(Enumerable.Repeat(source.Value, source.Multiplier)) };
}

private class LambdaConverterProfile : Profile
private sealed class LambdaConverterProfile : Profile
{
public LambdaConverterProfile()
{
Expand All @@ -71,7 +71,7 @@ public LambdaConverterProfile()
}
}

private class TypeConverterProfile : Profile
private sealed class TypeConverterProfile : Profile
{
public TypeConverterProfile()
{
Expand All @@ -80,7 +80,7 @@ public TypeConverterProfile()
}
}

private class ConverterInstanceProfile : Profile
private sealed class ConverterInstanceProfile : Profile
{
public ConverterInstanceProfile()
{
Expand Down
Loading