Modular mapping configuration (#162)

* Modular configuration for property mappings

* Update Readme, unit tests and sample

Co-authored-by: Steven Decoodt <steven.decoodt@vinci-energies.net>
This commit is contained in:
Steven Decoodt
2022-01-12 20:22:24 +01:00
committed by GitHub
parent 820358e8ff
commit 863d75bdc1
9 changed files with 312 additions and 13 deletions

View File

@@ -0,0 +1,37 @@
using Sieve.Services;
namespace SieveUnitTests.Abstractions.Entity
{
public class SieveConfigurationForIPost : ISieveConfiguration
{
public void Configure(SievePropertyMapper mapper)
{
mapper.Property<IPost>(p => p.ThisHasNoAttributeButIsAccessible)
.CanSort()
.CanFilter()
.HasName("shortname");
mapper.Property<IPost>(p => p.TopComment.Text)
.CanFilter();
mapper.Property<IPost>(p => p.TopComment.Id)
.CanSort();
mapper.Property<IPost>(p => p.OnlySortableViaFluentApi)
.CanSort();
mapper.Property<IPost>(p => p.TopComment.Text)
.CanFilter()
.HasName("topc");
mapper.Property<IPost>(p => p.FeaturedComment.Text)
.CanFilter()
.HasName("featc");
mapper
.Property<IPost>(p => p.DateCreated)
.CanSort()
.HasName("CreateDate");
}
}
}

View File

@@ -0,0 +1,37 @@
using Sieve.Services;
namespace SieveUnitTests.Entities
{
public class SieveConfigurationForPost : ISieveConfiguration
{
public void Configure(SievePropertyMapper mapper)
{
mapper.Property<Post>(p => p.ThisHasNoAttributeButIsAccessible)
.CanSort()
.CanFilter()
.HasName("shortname");
mapper.Property<Post>(p => p.TopComment.Text)
.CanFilter();
mapper.Property<Post>(p => p.TopComment.Id)
.CanSort();
mapper.Property<Post>(p => p.OnlySortableViaFluentApi)
.CanSort();
mapper.Property<Post>(p => p.TopComment.Text)
.CanFilter()
.HasName("topc");
mapper.Property<Post>(p => p.FeaturedComment.Text)
.CanFilter()
.HasName("featc");
mapper
.Property<Post>(p => p.DateCreated)
.CanSort()
.HasName("CreateDate");
}
}
}

View File

@@ -2,6 +2,7 @@ using System.Collections.Generic;
using System.Linq;
using Sieve.Exceptions;
using Sieve.Models;
using Sieve.Services;
using SieveUnitTests.Entities;
using SieveUnitTests.Services;
using Xunit;
@@ -10,15 +11,10 @@ namespace SieveUnitTests
{
public class Mapper
{
private readonly ApplicationSieveProcessor _processor;
private readonly IQueryable<Post> _posts;
public Mapper()
{
_processor = new ApplicationSieveProcessor(new SieveOptionsAccessor(),
new SieveCustomSortMethods(),
new SieveCustomFilterMethods());
_posts = new List<Post>
{
new Post
@@ -45,23 +41,49 @@ namespace SieveUnitTests
}.AsQueryable();
}
[Fact]
public void MapperWorks()
/// <summary>
/// Processors with the same mappings but configured via a different method.
/// </summary>
/// <returns></returns>
public static IEnumerable<object[]> GetProcessors()
{
yield return new object[] {
new ApplicationSieveProcessor(
new SieveOptionsAccessor(),
new SieveCustomSortMethods(),
new SieveCustomFilterMethods())};
yield return new object[] {
new ModularConfigurationSieveProcessor(
new SieveOptionsAccessor(),
new SieveCustomSortMethods(),
new SieveCustomFilterMethods())};
yield return new object[] {
new ModularConfigurationWithScanSieveProcessor(
new SieveOptionsAccessor(),
new SieveCustomSortMethods(),
new SieveCustomFilterMethods())};
}
[Theory]
[MemberData(nameof(GetProcessors))]
public void MapperWorks(ISieveProcessor processor)
{
var model = new SieveModel
{
Filters = "shortname@=A",
};
var result = _processor.Apply(model, _posts);
var result = processor.Apply(model, _posts);
Assert.Equal("A", result.First().ThisHasNoAttributeButIsAccessible);
Assert.True(result.Count() == 1);
}
[Fact]
public void MapperSortOnlyWorks()
[Theory]
[MemberData(nameof(GetProcessors))]
public void MapperSortOnlyWorks(ISieveProcessor processor)
{
var model = new SieveModel
{
@@ -69,9 +91,9 @@ namespace SieveUnitTests
Sorts = "OnlySortableViaFluentApi"
};
var result = _processor.Apply(model, _posts, applyFiltering: false, applyPagination: false);
var result = processor.Apply(model, _posts, applyFiltering: false, applyPagination: false);
Assert.Throws<SieveMethodNotFoundException>(() => _processor.Apply(model, _posts));
Assert.Throws<SieveMethodNotFoundException>(() => processor.Apply(model, _posts));
Assert.Equal(3, result.First().Id);

View File

@@ -0,0 +1,26 @@
using Microsoft.Extensions.Options;
using Sieve.Models;
using Sieve.Services;
using SieveUnitTests.Abstractions.Entity;
using SieveUnitTests.Entities;
namespace SieveUnitTests.Services
{
public class ModularConfigurationSieveProcessor : SieveProcessor
{
public ModularConfigurationSieveProcessor(
IOptions<SieveOptions> options,
ISieveCustomSortMethods customSortMethods,
ISieveCustomFilterMethods customFilterMethods)
: base(options, customSortMethods, customFilterMethods)
{
}
protected override SievePropertyMapper MapProperties(SievePropertyMapper mapper)
{
return mapper
.ApplyConfiguration<SieveConfigurationForPost>()
.ApplyConfiguration<SieveConfigurationForIPost>();
}
}
}

View File

@@ -0,0 +1,20 @@
using Microsoft.Extensions.Options;
using Sieve.Models;
using Sieve.Services;
namespace SieveUnitTests.Services
{
public class ModularConfigurationWithScanSieveProcessor : SieveProcessor
{
public ModularConfigurationWithScanSieveProcessor(
IOptions<SieveOptions> options,
ISieveCustomSortMethods customSortMethods,
ISieveCustomFilterMethods customFilterMethods)
: base(options, customSortMethods, customFilterMethods)
{
}
protected override SievePropertyMapper MapProperties(SievePropertyMapper mapper) =>
mapper.ApplyConfigurationsFromAssembly(typeof(ModularConfigurationWithScanSieveProcessor).Assembly);
}
}