Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a5b2f9c
Bugs/unused constructor members (#140)
SteveWilkes May 9, 2019
8104bc3
Updating version numbers
SteveWilkes May 9, 2019
52e4afc
Features/root enum pairing (#141)
SteveWilkes May 10, 2019
6c6db83
Support for mapping (not projecting) queryables (#142)
SteveWilkes May 13, 2019
aada3e8
v1.5 preview 1 release notes and NuGet package
SteveWilkes May 14, 2019
f73677b
Features/entity key mapping refinements (#144)
SteveWilkes May 17, 2019
82e3e9d
Handling null nested members in .ToTarget() data sources, fixes #145
SteveWilkes Jun 14, 2019
e11f398
Bugs/issue146 (#146, #147)
SteveWilkes Jun 15, 2019
f9887a1
Mapping to target interface members' implemented interface members, r…
SteveWilkes Jun 15, 2019
44982cf
Features/coverage optimisations (#148)
SteveWilkes Jun 15, 2019
b13f9c8
Updating to v1.5-preview2
SteveWilkes Jun 16, 2019
58623d9
v1.5-preview 2 NuGet package
SteveWilkes Jun 16, 2019
f115d2e
Allowing configured condition type tests if mapping from an interface…
SteveWilkes Jun 17, 2019
1b5b10d
Support for custom DateTime format strings with nullable DateTimes, r…
SteveWilkes Jun 23, 2019
74545db
Accounting for a conflicting member check being checked against Quali…
SteveWilkes Jun 26, 2019
676ee23
Support for zero-configuration mapping of interfaces to strings, fixe…
SteveWilkes Jun 26, 2019
71d4bd1
Updating to preview3, updating release notes, adding NuGet package
SteveWilkes Jun 26, 2019
7ee9b30
Bugs/simple to complex to target (#154)
SteveWilkes Jul 2, 2019
5e13dd9
Features/tidying (#156)
SteveWilkes Aug 3, 2019
063bbb8
Tidying
SteveWilkes Aug 3, 2019
f646619
Features/data source improvements (#158)
SteveWilkes Aug 20, 2019
bfeb4da
Features/ignore data sources (#160)
SteveWilkes Sep 14, 2019
0b2e755
Updating to v1.5
SteveWilkes Sep 14, 2019
4c46b7c
Adding v1.5 NuGet package
SteveWilkes Sep 14, 2019
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
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
<Reference Include="AgileObjects.NetStandardPolyfills, Version=1.4.0.0, Culture=neutral, PublicKeyToken=06131ac1c008ad4e, processorArchitecture=MSIL">
<HintPath>..\packages\AgileObjects.NetStandardPolyfills.1.4.0\lib\net40\AgileObjects.NetStandardPolyfills.dll</HintPath>
</Reference>
<Reference Include="AgileObjects.ReadableExpressions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=9f54ad81db69da8e, processorArchitecture=MSIL">
<HintPath>..\packages\AgileObjects.ReadableExpressions.2.1.1\lib\net40\AgileObjects.ReadableExpressions.dll</HintPath>
<Reference Include="AgileObjects.ReadableExpressions, Version=2.3.2.0, Culture=neutral, PublicKeyToken=9f54ad81db69da8e, processorArchitecture=MSIL">
<HintPath>..\packages\AgileObjects.ReadableExpressions.2.3.2\lib\net40\AgileObjects.ReadableExpressions.dll</HintPath>
</Reference>
<Reference Include="AutoMapper, Version=7.0.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.7.0.1\lib\net45\AutoMapper.dll</HintPath>
Expand Down
2 changes: 1 addition & 1 deletion AgileMapper.PerformanceTester.Net45/packages.config
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AgileObjects.NetStandardPolyfills" version="1.4.0" targetFramework="net452" />
<package id="AgileObjects.ReadableExpressions" version="2.1.1" targetFramework="net452" />
<package id="AgileObjects.ReadableExpressions" version="2.3.2" targetFramework="net452" />
<package id="AutoMapper" version="7.0.1" targetFramework="net452" />
<package id="Expressmapper" version="1.9.1" targetFramework="net452" />
<package id="Mapster" version="3.3.1" targetFramework="net452" />
Expand Down
18 changes: 12 additions & 6 deletions AgileMapper.UnitTests.Common/ShouldExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ public static void ShouldBe<TActual, TExpected>(this TActual value, TExpected ex
{
if (!AreEqual(expectedValue, value))
{
Asplode(expectedValue.ToString(), value?.ToString());
Asplode(
expectedValue?.ToString() ?? (typeof(TExpected).CanBeNull() ? "null" : "default"),
value?.ToString() ?? (typeof(TActual).CanBeNull() ? "null" : "default"));
}
}

Expand Down Expand Up @@ -405,14 +407,18 @@ public static IDictionary<TKey, TValue> ShouldContainKeyAndValue<TKey, TValue>(
return dictionary;
}

public static void ShouldBeOfType<TExpected>(this object actual)
public static TExpected ShouldBeOfType<TExpected>(this object actual)
{
if (!(actual is TExpected))
if (actual is TExpected expected)
{
Asplode(
"An object of type " + typeof(TExpected).GetFriendlyName(),
actual.GetType().GetFriendlyName());
return expected;
}

Asplode(
"An object of type " + typeof(TExpected).GetFriendlyName(),
actual.GetType().GetFriendlyName());

return default(TExpected);
}

public static void ShouldContain<T>(this IList<T> actual, T expected)
Expand Down
599 changes: 595 additions & 4 deletions AgileMapper.UnitTests.Net35/AgileMapper.UnitTests.Net35.csproj

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion AgileMapper.UnitTests.Net35/packages.config
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AgileObjects.NetStandardPolyfills" version="1.4.0" targetFramework="net35" />
<package id="AgileObjects.ReadableExpressions" version="2.1.1" targetFramework="net35" />
<package id="AgileObjects.ReadableExpressions" version="2.3.2" targetFramework="net35" />
<package id="DynamicLanguageRuntime" version="1.1.2" targetFramework="net35" />
<package id="NUnit" version="3.6.1" targetFramework="net35" />
<package id="NUnit3TestAdapter" version="3.10.0" targetFramework="net35" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
<Reference Include="AgileObjects.NetStandardPolyfills, Version=1.4.0.0, Culture=neutral, PublicKeyToken=06131ac1c008ad4e, processorArchitecture=MSIL">
<HintPath>..\packages\AgileObjects.NetStandardPolyfills.1.4.0\lib\net40\AgileObjects.NetStandardPolyfills.dll</HintPath>
</Reference>
<Reference Include="AgileObjects.ReadableExpressions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=9f54ad81db69da8e, processorArchitecture=MSIL">
<HintPath>..\packages\AgileObjects.ReadableExpressions.2.1.1\lib\net40\AgileObjects.ReadableExpressions.dll</HintPath>
<Reference Include="AgileObjects.ReadableExpressions, Version=2.3.2.0, Culture=neutral, PublicKeyToken=9f54ad81db69da8e, processorArchitecture=MSIL">
<HintPath>..\packages\AgileObjects.ReadableExpressions.2.3.2\lib\net40\AgileObjects.ReadableExpressions.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
Expand Down
2 changes: 1 addition & 1 deletion AgileMapper.UnitTests.NonParallel/packages.config
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AgileObjects.NetStandardPolyfills" version="1.4.0" targetFramework="net461" />
<package id="AgileObjects.ReadableExpressions" version="2.1.1" targetFramework="net461" />
<package id="AgileObjects.ReadableExpressions" version="2.3.2" targetFramework="net461" />
<package id="xunit" version="2.4.1" targetFramework="net461" />
<package id="xunit.abstractions" version="2.0.3" targetFramework="net461" />
<package id="xunit.analyzers" version="0.10.0" targetFramework="net461" />
Expand Down
19 changes: 19 additions & 0 deletions AgileMapper.UnitTests.Orms.EfCore2/WhenCreatingProjections.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
namespace AgileObjects.AgileMapper.UnitTests.Orms.EfCore2
{
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Common;
using Infrastructure;
Expand Down Expand Up @@ -49,5 +51,22 @@ public Task ShouldReuseACachedProjectionMapper()
mapper.RootMapperCountShouldBeOne();
});
}

[Fact]
public Task ShouldMapAQueryableAsAnEnumerable()
{
return RunTest(async (context, mapper) =>
{
await context.BoolItems.AddRangeAsync(new PublicBool { Value = true }, new PublicBool { Value = false });
await context.SaveChangesAsync();

var result = mapper
.Map(context.BoolItems.Where(bi => bi.Value))
.ToANew<List<PublicBoolDto>>();

result.ShouldNotBeNull();
result.ShouldHaveSingleItem().Value.ShouldBeTrue();
});
}
}
}
17 changes: 15 additions & 2 deletions AgileMapper.UnitTests/AgileMapper.UnitTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
<Reference Include="AgileObjects.NetStandardPolyfills, Version=1.4.0.0, Culture=neutral, PublicKeyToken=06131ac1c008ad4e, processorArchitecture=MSIL">
<HintPath>..\packages\AgileObjects.NetStandardPolyfills.1.4.0\lib\net40\AgileObjects.NetStandardPolyfills.dll</HintPath>
</Reference>
<Reference Include="AgileObjects.ReadableExpressions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=9f54ad81db69da8e, processorArchitecture=MSIL">
<HintPath>..\packages\AgileObjects.ReadableExpressions.2.1.1\lib\net40\AgileObjects.ReadableExpressions.dll</HintPath>
<Reference Include="AgileObjects.ReadableExpressions, Version=2.3.2.0, Culture=neutral, PublicKeyToken=9f54ad81db69da8e, processorArchitecture=MSIL">
<HintPath>..\packages\AgileObjects.ReadableExpressions.2.3.2\lib\net40\AgileObjects.ReadableExpressions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Primitives, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Primitives.2.0.0\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll</HintPath>
Expand Down Expand Up @@ -103,6 +103,9 @@
<Compile Include="Configuration\Inline\WhenConfiguringTypeIdentifiersInline.cs" />
<Compile Include="Configuration\Inline\WhenIgnoringMembersInline.cs" />
<Compile Include="Configuration\Inline\WhenIgnoringMembersInlineIncorrectly.cs" />
<Compile Include="Configuration\Inline\WhenIgnoringSourceMemberInlineIncorrectly.cs" />
<Compile Include="Configuration\Inline\WhenIgnoringSourceMembersByValueFilterInline.cs" />
<Compile Include="Configuration\Inline\WhenIgnoringSourceMembersInline.cs" />
<Compile Include="Configuration\Inline\WhenMappingToNullInline.cs" />
<Compile Include="Configuration\Inline\WhenValidatingMappingsInline.cs" />
<Compile Include="Configuration\Inline\WhenViewingMappingPlans.cs" />
Expand All @@ -111,6 +114,12 @@
<Compile Include="Configuration\WhenConfiguringEntityMapping.cs" />
<Compile Include="Configuration\WhenConfiguringReverseDataSources.cs" />
<Compile Include="Configuration\WhenConfiguringReverseDataSourcesIncorrectly.cs" />
<Compile Include="Configuration\WhenIgnoringSourceMembers.cs" />
<Compile Include="Configuration\WhenIgnoringSourceMembersByFilter.cs" />
<Compile Include="Configuration\WhenIgnoringSourceMembersByGlobalFilter.cs" />
<Compile Include="Configuration\WhenIgnoringSourceMembersByValueFilter.cs" />
<Compile Include="Configuration\WhenIgnoringSourceMembersByValueFilterIncorrectly.cs" />
<Compile Include="Configuration\WhenIgnoringSourceMembersIncorrectly.cs" />
<Compile Include="Configuration\WhenResolvingServices.cs" />
<Compile Include="Configuration\WhenViewingMappingPlans.cs" />
<Compile Include="Dictionaries\WhenMappingFromDictionariesOnToComplexTypes.cs" />
Expand Down Expand Up @@ -144,6 +153,7 @@
<Compile Include="Extensions\WhenUnflatteningFromQueryStringsViaExtensionMethods.cs" />
<Compile Include="Extensions\WhenUnflatteningViaExtensionMethods.cs" />
<Compile Include="MapperCloning\WhenCloningConstructorDataSources.cs" />
<Compile Include="MapperCloning\WhenCloningDictionarySettings.cs" />
<Compile Include="MapperCloning\WhenCloningMemberIgnores.cs" />
<Compile Include="Configuration\WhenConfiguringObjectTracking.cs" />
<Compile Include="Configuration\WhenConfiguringObjectTrackingIncorrectly.cs" />
Expand Down Expand Up @@ -219,7 +229,9 @@
<Compile Include="TestClasses\PaymentTypeUk.cs" />
<Compile Include="TestClasses\PaymentTypeUs.cs" />
<Compile Include="TestClasses\PublicCtorStruct.cs" />
<Compile Include="TestClasses\PublicEnumerable.cs" />
<Compile Include="TestClasses\PublicImplementation.cs" />
<Compile Include="TestClasses\PublicIndex.cs" />
<Compile Include="TestClasses\PublicSealed.cs" />
<Compile Include="TestClasses\PublicPropertyStruct.cs" />
<Compile Include="TestClasses\PublicTwoFields.cs" />
Expand Down Expand Up @@ -301,6 +313,7 @@
<Compile Include="WhenMappingToNewEnumerableMembers.cs" />
<Compile Include="WhenMappingToNewEnumerables.cs" />
<Compile Include="Members\WhenMatchingSourceToTargetMembers.cs" />
<Compile Include="WhenWorkingWithQueryStrings.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
using Common;
using TestClasses;
#if !NET35
using NetStandardPolyfills;
using Xunit;
using static System.Linq.Expressions.Expression;
#else
using Fact = NUnit.Framework.TestAttribute;

Expand Down Expand Up @@ -317,6 +319,194 @@ public void ShouldApplyDifferingTargetTypeInlineDataSourceMemberConfig()
}
}

[Fact]
public void ShouldApplyAnInlineNullCheckedArrayIndexDataSource()
{
using (var mapper = Mapper.CreateNew())
{
var source = new PublicProperty<PublicField<Address>[]>
{
Value = new[]
{
new PublicField<Address> { Value = new Address { Line1 = "1.1" } },
new PublicField<Address> { Value = new Address { Line1 = "1.2" } }
}
};

var result = mapper.Map(source).ToANew<PublicProperty<Address>>(cfg => cfg
.Map(s => s.Value[1].Value, t => t.Value));

result.Value.ShouldNotBeNull();
result.Value.Line1.ShouldBe("1.2");

var nullArraySource = new PublicProperty<PublicField<Address>[]> { Value = null };

var nullArrayResult = mapper.Map(nullArraySource).ToANew<PublicProperty<Address>>(cfg => cfg
.Map(s => s.Value[1].Value, t => t.Value));

nullArrayResult.Value.ShouldBeNull();

var tooSmallArraySource = new PublicProperty<PublicField<Address>[]>
{
Value = new[]
{
new PublicField<Address> { Value = new Address { Line1 = "1.1" } }
}
};

var tooSmallArrayResult = mapper.Map(tooSmallArraySource).ToANew<PublicProperty<Address>>(cfg => cfg
.Map(s => s.Value[1].Value, t => t.Value));

tooSmallArrayResult.Value.ShouldBeNull();

var nullArrayObjectSource = new PublicProperty<PublicField<Address>[]>
{
Value = new[]
{
new PublicField<Address> { Value = new Address { Line1 = "1.1" } },
new PublicField<Address> { Value = null }
}
};

var nullArrayObjectResult = mapper.Map(nullArrayObjectSource).ToANew<PublicProperty<Address>>(cfg => cfg
.Map(s => s.Value[1].Value, t => t.Value));

nullArrayObjectResult.Value.ShouldBeNull();
}
}

#if !NET35
// System.Linq.Expressions.Expression.MakeIndex() is missing in .NET 3.5, so not much danger of this configuration:
[Fact]
public void ShouldApplyAnInlineNullCheckedIntKeyedIndexDataSource()
{
using (var mapper = Mapper.CreateNew())
{
var source = new PublicProperty<PublicIndex<int, PublicField<Address>>>
{
Value = new PublicIndex<int, PublicField<Address>>
{
[0] = new PublicField<Address> { Value = new Address { Line1 = "1.1" } },
[1] = new PublicField<Address> { Value = new Address { Line1 = "1.2" } }
}
};

var sourceParameter = Parameter(source.GetType(), "s");
var sourceValueProperty = Property(sourceParameter, "Value");
var sourceValueIndexer = sourceValueProperty.Type.GetPublicInstanceProperty("Item");
var sourceValueIndex = MakeIndex(sourceValueProperty, sourceValueIndexer, new[] { Constant(1) });

var sourceLambda = Lambda<Func<PublicProperty<PublicIndex<int, PublicField<Address>>>, Address>>(
Field(sourceValueIndex, "Value"),
sourceParameter);

var result = mapper.Map(source).ToANew<PublicField<Address>>(cfg => cfg
.Map(sourceLambda, t => t.Value));

result.Value.ShouldNotBeNull();
result.Value.Line1.ShouldBe("1.2");

var nullIndexerSource = new PublicProperty<PublicIndex<int, PublicField<Address>>> { Value = null };

var nullIndexerResult = mapper.Map(nullIndexerSource).ToANew<PublicProperty<Address>>(cfg => cfg
.Map(sourceLambda, t => t.Value));

nullIndexerResult.Value.ShouldBeNull();

var noEntrySource = new PublicProperty<PublicIndex<int, PublicField<Address>>>
{
Value = new PublicIndex<int, PublicField<Address>>
{
[0] = new PublicField<Address> { Value = new Address { Line1 = "1.1" } }
}
};

var noEntryResult = mapper.Map(noEntrySource).ToANew<PublicProperty<Address>>(cfg => cfg
.Map(sourceLambda, t => t.Value));

noEntryResult.Value.ShouldBeNull();

var nullIndexedObjectSource = new PublicProperty<PublicIndex<int, PublicField<Address>>>
{
Value = new PublicIndex<int, PublicField<Address>>
{
[0] = new PublicField<Address> { Value = new Address { Line1 = "1.1" } },
[1] = new PublicField<Address> { Value = null }
}
};

var nullIndexedObjectResult = mapper.Map(nullIndexedObjectSource).ToANew<PublicProperty<Address>>(cfg => cfg
.Map(sourceLambda, t => t.Value));

nullIndexedObjectResult.Value.ShouldBeNull();
}
}

[Fact]
public void ShouldApplyAnInlineNullCheckedStringKeyedIndexDataSource()
{
using (var mapper = Mapper.CreateNew())
{
var source = new PublicProperty<PublicIndex<string, PublicField<Address>>>
{
Value = new PublicIndex<string, PublicField<Address>>
{
["A"] = new PublicField<Address> { Value = new Address { Line1 = "1.1" } },
["B"] = new PublicField<Address> { Value = new Address { Line1 = "1.2" } }
}
};

var sourceParameter = Parameter(source.GetType(), "s");
var sourceValueProperty = Property(sourceParameter, "Value");
var sourceValueIndexer = sourceValueProperty.Type.GetPublicInstanceProperty("Item");
var sourceValueIndex = MakeIndex(sourceValueProperty, sourceValueIndexer, new[] { Constant("B") });

var sourceLambda = Lambda<Func<PublicProperty<PublicIndex<string, PublicField<Address>>>, Address>>(
Field(sourceValueIndex, "Value"),
sourceParameter);

var result = mapper.Map(source).ToANew<PublicField<Address>>(cfg => cfg
.Map(sourceLambda, t => t.Value));

result.Value.ShouldNotBeNull();
result.Value.Line1.ShouldBe("1.2");

var nullIndexerSource = new PublicProperty<PublicIndex<string, PublicField<Address>>> { Value = null };

var nullIndexerResult = mapper.Map(nullIndexerSource).ToANew<PublicProperty<Address>>(cfg => cfg
.Map(sourceLambda, t => t.Value));

nullIndexerResult.Value.ShouldBeNull();

var noEntrySource = new PublicProperty<PublicIndex<string, PublicField<Address>>>
{
Value = new PublicIndex<string, PublicField<Address>>
{
["A"] = new PublicField<Address> { Value = new Address { Line1 = "1.1" } }
}
};

var noEntryResult = mapper.Map(noEntrySource).ToANew<PublicProperty<Address>>(cfg => cfg
.Map(sourceLambda, t => t.Value));

noEntryResult.Value.ShouldBeNull();

var nullIndexedObjectSource = new PublicProperty<PublicIndex<string, PublicField<Address>>>
{
Value = new PublicIndex<string, PublicField<Address>>
{
["A"] = new PublicField<Address> { Value = new Address { Line1 = "1.1" } },
["B"] = new PublicField<Address> { Value = null }
}
};

var nullIndexedObjectResult = mapper.Map(nullIndexedObjectSource).ToANew<PublicProperty<Address>>(cfg => cfg
.Map(sourceLambda, t => t.Value));

nullIndexedObjectResult.Value.ShouldBeNull();
}
}
#endif
[Fact]
public void ShouldHandleANullSourceMember()
{
Expand Down
Loading