Skip to content

Commit

Permalink
bug fixing
Browse files Browse the repository at this point in the history
  • Loading branch information
OFFICE\yanisimov committed Feb 28, 2017
1 parent 92c9292 commit d1f9552
Show file tree
Hide file tree
Showing 8 changed files with 298 additions and 71 deletions.
6 changes: 3 additions & 3 deletions ExpressMapper NET40/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.9.0.0")]
[assembly: AssemblyFileVersion("1.9.0.0")]
[assembly: AssemblyInformationalVersion("1.9.0")]
[assembly: AssemblyVersion("1.9.1.0")]
[assembly: AssemblyFileVersion("1.9.1.0")]
[assembly: AssemblyInformationalVersion("1.9.1")]
6 changes: 3 additions & 3 deletions ExpressMapper NETCORE/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("969e6614-0489-4174-a735-cc66f51d8746")]

[assembly: AssemblyVersion("1.9.0.0")]
[assembly: AssemblyFileVersion("1.9.0.0")]
[assembly: AssemblyInformationalVersion("1.9.0")]
[assembly: AssemblyVersion("1.9.1.0")]
[assembly: AssemblyFileVersion("1.9.1.0")]
[assembly: AssemblyInformationalVersion("1.9.1")]
61 changes: 47 additions & 14 deletions ExpressMapper NETCORE/TypeMapperBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public void Compile(CompilationTypes compilationType, bool forceByDemand = false
catch (Exception ex)
{
throw new ExpressmapperException(
$"Error error occured trying to compile mapping for: source {typeof (T).FullName}, destination {typeof (TN).FullName}. See the inner exception for details.",
$"Error error occured trying to compile mapping for: source {typeof(T).FullName}, destination {typeof(TN).FullName}. See the inner exception for details.",
ex);
}
}
Expand Down Expand Up @@ -179,18 +179,18 @@ public Func<object, object, object> GetNonGenericMapFunc()
var dstAssigned = Expression.Assign(dstTypedExp, dstConverted);

var customGenericType = typeof(ITypeMapper<,>).MakeGenericType(typeof(T), typeof(TN));
var castToCustomGeneric = Expression.Convert(Expression.Constant((ITypeMapper) this), customGenericType);
var castToCustomGeneric = Expression.Convert(Expression.Constant((ITypeMapper)this), customGenericType);
var genVariable = Expression.Variable(customGenericType);
var assignExp = Expression.Assign(genVariable, castToCustomGeneric);
var methodInfo = customGenericType.GetInfo().GetMethod("MapTo", new[] {typeof(T), typeof(TN)});
var methodInfo = customGenericType.GetInfo().GetMethod("MapTo", new[] { typeof(T), typeof(TN) });

var mapCall = Expression.Call(genVariable, methodInfo, srcTypedExp, dstTypedExp);
var resultVarExp = Expression.Variable(typeof(object), "result");
var convertToObj = Expression.Convert(mapCall, typeof(object));
var assignResult = Expression.Assign(resultVarExp, convertToObj);

var blockExpression = Expression.Block(new[] {srcTypedExp, dstTypedExp, genVariable, resultVarExp},
new Expression[] {srcAssigned, dstAssigned, assignExp, assignResult, resultVarExp});
var blockExpression = Expression.Block(new[] { srcTypedExp, dstTypedExp, genVariable, resultVarExp },
new Expression[] { srcAssigned, dstAssigned, assignExp, assignResult, resultVarExp });
var lambda =
Expression.Lambda<Func<object, object, object>>(blockExpression, parameterExpression, destParameterExp);
NonGenericMapFunc = lambda.Compile();
Expand All @@ -200,8 +200,8 @@ public Func<object, object, object> GetNonGenericMapFunc()

protected void AutoMapProperty(MemberInfo propertyGet, MemberInfo propertySet)
{
var callSetPropMethod = Expression.PropertyOrField(DestFakeParameter, propertySet.Name);
var callGetPropMethod = Expression.PropertyOrField(SourceParameter, propertyGet.Name);
var callSetPropMethod = propertySet.MemberType == MemberTypes.Field ? Expression.Field(DestFakeParameter, propertySet as FieldInfo) : Expression.Property(DestFakeParameter, propertySet as PropertyInfo);
var callGetPropMethod = propertyGet.MemberType == MemberTypes.Field ? Expression.Field(SourceParameter, propertyGet as FieldInfo) : Expression.Property(SourceParameter, propertyGet as PropertyInfo);

MapMember(callSetPropMethod, callGetPropMethod);
}
Expand Down Expand Up @@ -282,6 +282,7 @@ protected void ProcessAutoProperties()
var getProps =
typeof(T).GetInfo()
.GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public);

var setProps =
typeof(TN).GetInfo()
.GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public);
Expand All @@ -293,7 +294,7 @@ protected void ProcessAutoProperties()

var comparer = CultureInfo.CurrentCulture.CompareInfo.GetStringComparer(CompareOptions.OrdinalIgnoreCase);
//var comparer = StringComparer.Create(CultureInfo.CurrentCulture,
// stringComparison == StringComparison.OrdinalIgnoreCase);
// stringComparison == StringComparison.OrdinalIgnoreCase);

foreach (var prop in sourceMembers)
{
Expand All @@ -302,18 +303,48 @@ protected void ProcessAutoProperties()
{
continue;
}
var setprop = destMembers.FirstOrDefault(x => string.Equals(x.Name, prop.Name, stringComparison));

var notUniqueDestMembers = destMembers.Where(x => string.Equals(x.Name, prop.Name, stringComparison));
var notUniqueSrcMembers = sourceMembers.Where(x => string.Equals(x.Name, prop.Name, stringComparison));

var getprop = GetTopMostMemberOfHierarchy(notUniqueSrcMembers);
if (AutoMembers.ContainsKey(getprop))
{
continue;
}

var setprop = GetTopMostMemberOfHierarchy(notUniqueDestMembers);

var propertyInfo = setprop as PropertyInfo;
if ((propertyInfo == null && setprop == null) ||
(propertyInfo != null && (!propertyInfo.CanWrite || !propertyInfo.GetSetMethod(true).IsPublic)))
{
IgnoreMemberList.Add(prop.Name);
IgnoreMemberList.Add(getprop.Name);
continue;
}
AutoMembers[prop] = setprop;
AutoMapProperty(prop, setprop);
AutoMembers[getprop] = setprop;
AutoMapProperty(getprop, setprop);
}
}

private static MemberInfo GetTopMostMemberOfHierarchy(IEnumerable<MemberInfo> notUniqueMembers)
{
MemberInfo chosen = null;

foreach (var notUniqueMember in notUniqueMembers)
{
if (chosen == null)
{
chosen = notUniqueMember;
}
else
{
chosen = chosen.DeclaringType.GetInfo().IsAssignableFrom(notUniqueMember.DeclaringType)
? notUniqueMember
: chosen;
}
}
return chosen;
}

internal StringComparison GetStringCase()
Expand Down Expand Up @@ -474,8 +505,10 @@ public void ImportMemberConfigParameters(IMemberConfigParameters baseClassConfig

// todo : implement visitor to replace base type to the subclass' type
CustomFunctionMembers =
new List<KeyValuePair<MemberExpression, Expression>>(baseClassConfiguration.CustomFunctionMembers.Count);
CustomMembers = new List<KeyValuePair<MemberExpression, Expression>>(baseClassConfiguration.CustomMembers.Count);
new List<KeyValuePair<MemberExpression, Expression>>(baseClassConfiguration.CustomFunctionMembers
.Count);
CustomMembers =
new List<KeyValuePair<MemberExpression, Expression>>(baseClassConfiguration.CustomMembers.Count);
FlattenMembers =
new List<KeyValuePair<MemberExpression, Expression>>(baseClassConfiguration.FlattenMembers.Count);

Expand Down
2 changes: 1 addition & 1 deletion ExpressMapper NETCORE/project.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "1.0.0-*",
"version": "1.9.1.0",
"buildOptions": {
"outputName": "ExpressMapper",
"xmlDoc": true
Expand Down
109 changes: 90 additions & 19 deletions ExpressMapper.Tests NET40/BasicTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void EnumToAnotherEnumMapTest()
};

var unitOfWorkViewModel = unitOfWork.Map<UnitOfWork, UnitOfWorkViewModel>();
Assert.AreEqual((int)unitOfWork.State, (int)unitOfWorkViewModel.State);
Assert.AreEqual((int) unitOfWork.State, (int) unitOfWorkViewModel.State);
Assert.AreEqual(unitOfWork.Id, unitOfWorkViewModel.Id);
}

Expand Down Expand Up @@ -60,7 +60,7 @@ public void DefaultPrimitiveTypePropertyToStringTest()
.Member(dest => dest.TestString, src => src.TestDecimal);
Mapper.RegisterCustom<decimal, string>(src => src.ToString("#0.00", CultureInfo.InvariantCulture));
Mapper.Compile();
var test = new TestDefaultDecimal() { TestDecimal = default(decimal) };
var test = new TestDefaultDecimal() {TestDecimal = default(decimal)};
test.TestDecimal = default(decimal);
var result = Mapper.Map<TestDefaultDecimal, TestDefaultDecimalToStringViewModel>(test);
//This is where the mapping fails
Expand All @@ -74,9 +74,9 @@ public void MemberMappingsHasHigherPriorityThanCaseSensetiveTest()
.Member(t => t.Enabled, s => s.enabled == "Y");
Mapper.Compile();

var source = new Source { enabled = "N" };
var result = Mapper.Map<Source, TargetViewModel>(source);
Assert.AreEqual(result.Enabled, false);
var source = new Source {enabled = "N"};
var result = Mapper.Map<Source, TargetViewModel>(source);
Assert.AreEqual(result.Enabled, false);
}

[Test]
Expand Down Expand Up @@ -293,7 +293,7 @@ public void HiddenInheritedMemberMap()
Assert.AreEqual(result, srcDst.Value);
}

private void MapBaseMember<T, TN>(IMemberConfiguration<T,TN> mapConfig)
private void MapBaseMember<T, TN>(IMemberConfiguration<T, TN> mapConfig)
where T : Gift
where TN : GiftViewModel
{
Expand Down Expand Up @@ -421,7 +421,8 @@ public void BeforeMapDuplicateTest()
.Before((src, dest) => dest.Name = src.Name)
.Before((src, dest) => dest.Name = src.Name)
.Ignore(dest => dest.Name));
Assert.That(exception.Message, Is.EqualTo("BeforeMap already registered for ExpressMapper.Tests.Model.Models.Size"));
Assert.That(exception.Message,
Is.EqualTo("BeforeMap already registered for ExpressMapper.Tests.Model.Models.Size"));

var sizeResult = Functional.BeforeMap();
var result = Mapper.Map<Size, SizeViewModel>(sizeResult.Key);
Expand All @@ -445,7 +446,8 @@ public void AfterMapDuplicateTest()
var exception = Assert.Throws<InvalidOperationException>(() => Mapper.Register<Size, SizeViewModel>()
.After((src, dest) => dest.Name = "OVERRIDE BY AFTER MAP")
.After((src, dest) => dest.Name = "Duplicate map"));
Assert.That(exception.Message, Is.EqualTo("AfterMap already registered for ExpressMapper.Tests.Model.Models.Size"));
Assert.That(exception.Message,
Is.EqualTo("AfterMap already registered for ExpressMapper.Tests.Model.Models.Size"));
var sizeResult = Functional.AfterMap();
var result = Mapper.Map<Size, SizeViewModel>(sizeResult.Key);
Assert.AreEqual(result, sizeResult.Value);
Expand Down Expand Up @@ -754,7 +756,8 @@ public void NonGenericSimpleWithDestinationMap()
var test = Functional.AutoMemberMap();

var resultInstanceHash = test.Value.GetHashCode();
var testViewModel = Mapper.Map(test.Key, test.Value, typeof(TestModel), typeof(TestViewModel)) as TestViewModel;
var testViewModel =
Mapper.Map(test.Key, test.Value, typeof(TestModel), typeof(TestViewModel)) as TestViewModel;

Assert.AreEqual(testViewModel.GetHashCode(), resultInstanceHash);
Assert.AreEqual(testViewModel, test.Value);
Expand Down Expand Up @@ -873,7 +876,7 @@ public void ExistingDestCollEqualsWithNullElement()
var testItemHash = testResult.Item2.GetHashCode();
var arrayHash = testResult.Item2.Array.GetHashCode();
var testArr = new List<int?>(testResult.Item2.Array.Length);
testArr.AddRange(testResult.Item2.Array.Select(tc => tc == null ? (int?)null : tc.GetHashCode()));
testArr.AddRange(testResult.Item2.Array.Select(tc => tc == null ? (int?) null : tc.GetHashCode()));

var result = Mapper.Map(testResult.Item1, testResult.Item2);
Assert.AreEqual(result, testResult.Item2);
Expand Down Expand Up @@ -950,7 +953,7 @@ public void ExistingSrcCollGreater()
Assert.AreEqual(result.Collection.ElementAt(i), testResult.Item3.Collection.ElementAt(i));
}
}

[Test]
public void ExistingDestDestCollGreater()
{
Expand Down Expand Up @@ -1086,15 +1089,20 @@ public void ExistingDestinationComplex()
for (var i = 0; i < result.SubItems.Length; i++)
{
Assert.AreEqual(result.SubItems[i].GetHashCode(), subItemsHashes[i]);
Assert.AreEqual(result.SubItems[i].Units.GetHashCode(), subItemUnitsCollHashes[result.SubItems[i].GetHashCode()]);
Assert.AreEqual(result.SubItems[i].Units.GetHashCode(),
subItemUnitsCollHashes[result.SubItems[i].GetHashCode()]);

for (var j = 0; j < 4; j++)
{
Assert.AreEqual(result.SubItems[i].Units[j].GetHashCode(), subItemUnitsHashes[result.SubItems[i].GetHashCode()][j]);
Assert.AreEqual(result.SubItems[i].Units[j].SubUnits.GetHashCode(), subItemUnitSubUnitCollHashes[result.SubItems[i].GetHashCode()][j]);
Assert.AreEqual(result.SubItems[i].Units[j].GetHashCode(),
subItemUnitsHashes[result.SubItems[i].GetHashCode()][j]);
Assert.AreEqual(result.SubItems[i].Units[j].SubUnits.GetHashCode(),
subItemUnitSubUnitCollHashes[result.SubItems[i].GetHashCode()][j]);
for (var k = 0; k < 3; k++)
{
Assert.AreEqual(result.SubItems[i].Units[j].SubUnits[k].GetHashCode(), subItemUnitSubUnitsHashes[result.SubItems[i].GetHashCode()][result.SubItems[i].Units[j].GetHashCode()][k]);
Assert.AreEqual(result.SubItems[i].Units[j].SubUnits[k].GetHashCode(),
subItemUnitSubUnitsHashes[result.SubItems[i].GetHashCode()][
result.SubItems[i].Units[j].GetHashCode()][k]);
}
}
}
Expand Down Expand Up @@ -1144,7 +1152,7 @@ public void EnumMap()

Assert.AreEqual(GenderTypes.Men, testViewModel.Gender);
Assert.AreEqual(GenderTypes.Women.ToString(), testViewModel.NullableGender);
Assert.AreEqual((int)GenderTypes.Women, testViewModel.GenderIndex);
Assert.AreEqual((int) GenderTypes.Women, testViewModel.GenderIndex);
}

[Test]
Expand Down Expand Up @@ -1203,7 +1211,7 @@ public void MemberCaseSensitivityGlobalMapTest()
};

var typoCaseViewModel = Mapper.Map<TypoCase, TypoCaseViewModel>(typoCase);

Assert.AreEqual(typoCaseViewModel.Id, Guid.Empty);
Assert.AreEqual(typoCaseViewModel.Name, null);
Assert.AreEqual(typoCase.TestId, typoCaseViewModel.TestId);
Expand Down Expand Up @@ -1416,7 +1424,7 @@ public void NestedInheritanceIncludeTest()
Assert.AreEqual(uiViewModel.ControlViewModel.Description, textBox.Description);
Assert.AreEqual(uiViewModel.ControlViewModel.id_ctrl, textBox.Id);
Assert.AreEqual(uiViewModel.ControlViewModel.name_ctrl, textBox.Name);
Assert.AreEqual(((TextBoxViewModel)uiViewModel.ControlViewModel).Text, textBox.Text);
Assert.AreEqual(((TextBoxViewModel) uiViewModel.ControlViewModel).Text, textBox.Text);
}

[Test]
Expand All @@ -1426,7 +1434,70 @@ public void MapNullSourceReturnNullDest()
Mapper.Compile();

Assert.IsNull(Mapper.Map<object, object>(null));
Assert.IsNull(Mapper.Map<object, object>(null, (object)null));
Assert.IsNull(Mapper.Map<object, object>(null, (object) null));
}

#region Duplicate property names in the class hierarchy

[Test]
public void MapDuplicatePropertyNamesInHierarchyTest()
{
Mapper.Register<A, AN>();
Mapper.Register<AN, A>();

Mapper.Register<T, TNT>();
Mapper.Register<TNT, T>();
Mapper.Compile();


var tnt = new TNT
{
Foo = new AN
{
Id = 4
}
};

var t = new T
{
Foo = new A
{
Id = 5
}
};

var tntResult = t.Map<T, TNT>();
var tResult = tnt.Map<TNT, T>();

Assert.AreEqual(tntResult.Foo.Id, 5);
Assert.AreEqual(tResult.Foo.Id, 4);
}

class A
{
public int Id { get; set; }
}

class AN : A
{
public new int Id { get; set; }
}

class T
{
public A Foo { get; set; }
}

class TN : T
{
public new AN Foo { get; set; }
}

class TNT : TN
{
public new AN Foo { get; set; }
}

#endregion
}
}
Loading

0 comments on commit d1f9552

Please sign in to comment.