From 7ec97810f7178b53f8011ca9686b29f72aacfe3a Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 01:11:34 +0300 Subject: [PATCH 01/23] interface type fixes & unit test improvements --- .../{OrderByDynamic.cs => LinqExtensions.cs} | 72 ++- Sieve/Services/SieveProcessor.cs | 4 +- .../Abstractions/Entity/IBaseEntity.cs | 3 +- SieveUnitTests/Abstractions/Entity/IPost.cs | 3 +- .../Entity/SieveConfigurationForIPost.cs | 23 +- .../Abstractions/Strategy/IAudit.cs | 12 + .../Strategy/ISupportSoftDelete.cs | 10 + SieveUnitTests/Entities/BaseEntity.cs | 3 + SieveUnitTests/Entities/Post.cs | 5 + .../Entities/SieveConfigurationForPost.cs | 21 +- SieveUnitTests/General.cs | 585 +++++++++-------- SieveUnitTests/GeneralWithInterfaces.cs | 588 +++++++++++------- .../Services/ApplicationSieveProcessor.cs | 66 +- .../Services/SieveCustomFilterMethods.cs | 14 +- SieveUnitTests/SieveUnitTests.csproj | 1 + SieveUnitTests/TestBase.cs | 48 ++ build/Configuration.cs | 4 +- 17 files changed, 880 insertions(+), 582 deletions(-) rename Sieve/Extensions/{OrderByDynamic.cs => LinqExtensions.cs} (52%) create mode 100644 SieveUnitTests/Abstractions/Strategy/IAudit.cs create mode 100644 SieveUnitTests/Abstractions/Strategy/ISupportSoftDelete.cs create mode 100644 SieveUnitTests/TestBase.cs diff --git a/Sieve/Extensions/OrderByDynamic.cs b/Sieve/Extensions/LinqExtensions.cs similarity index 52% rename from Sieve/Extensions/OrderByDynamic.cs rename to Sieve/Extensions/LinqExtensions.cs index aea83a8..7d3848a 100644 --- a/Sieve/Extensions/OrderByDynamic.cs +++ b/Sieve/Extensions/LinqExtensions.cs @@ -1,21 +1,76 @@ using System; using System.Linq; using System.Linq.Expressions; -using System.Reflection; +using Sieve.Exceptions; namespace Sieve.Extensions { public static partial class LinqExtensions { + internal static Expression GeneratePropertyAccess + ( + this Expression parameterExpression, + string propertyName + ) + { + var propertyAccessor = parameterExpression; + + try + { + propertyAccessor = Expression.PropertyOrField(propertyAccessor, propertyName); + } + catch (ArgumentException) + { + // propertyName is not a direct property of field of propertyAccessor expression's type. + // when propertyAccessor.Type is directly an interface, say typeof(ISomeEntity) and ISomeEntity is interfaced to IBaseEntity + // in which `propertyName` is defined in the first place. + // To solve this, search `propertyName` in all other implemented interfaces + + var possibleInterfaceType = propertyAccessor.Type; + + if (!possibleInterfaceType.IsInterface) + throw; + + // get all implemented interface types + var implementedInterfaces = possibleInterfaceType.GetInterfaces(); + + try + { + // search propertyName in all interfaces + var interfacedExpression = implementedInterfaces + .Where + ( + implementedInterface => implementedInterface + .GetProperties() + .Any(info => info.Name == propertyName) + ) + .Select(implementedInterface => Expression.TypeAs(propertyAccessor, implementedInterface)) + .SingleOrDefault(); + + if (interfacedExpression != null) + propertyAccessor = Expression.PropertyOrField(interfacedExpression, propertyName); + } + catch (InvalidOperationException ioe) + { + throw new SieveException + ( + $"{propertyName} is repeated in interface hierarchy. Try renaming.", + ioe + ); + } + } + + return propertyAccessor; + } + public static IQueryable OrderByDynamic( this IQueryable source, string fullPropertyName, - PropertyInfo propertyInfo, bool desc, bool useThenBy, bool disableNullableTypeExpression = false) { - var lambda = GenerateLambdaWithSafeMemberAccess(fullPropertyName, propertyInfo, disableNullableTypeExpression); + var lambda = GenerateLambdaWithSafeMemberAccess(fullPropertyName, disableNullableTypeExpression); var command = desc ? (useThenBy ? "ThenByDescending" : "OrderByDescending") @@ -34,7 +89,6 @@ public static IQueryable OrderByDynamic( private static Expression> GenerateLambdaWithSafeMemberAccess ( string fullPropertyName, - PropertyInfo propertyInfo, bool disableNullableTypeExpression ) { @@ -44,15 +98,7 @@ bool disableNullableTypeExpression foreach (var name in fullPropertyName.Split('.')) { - try - { - propertyValue = Expression.PropertyOrField(propertyValue, name); - } - catch (ArgumentException) - { - // name is not a direct property of field of propertyValue expression. construct a memberAccess then. - propertyValue = Expression.MakeMemberAccess(propertyValue, propertyInfo); - } + propertyValue = propertyValue.GeneratePropertyAccess(name); if (propertyValue.Type.IsNullable() && !disableNullableTypeExpression) { diff --git a/Sieve/Services/SieveProcessor.cs b/Sieve/Services/SieveProcessor.cs index 5b36ea1..2f72473 100644 --- a/Sieve/Services/SieveProcessor.cs +++ b/Sieve/Services/SieveProcessor.cs @@ -289,7 +289,7 @@ private static (Expression propertyValue, Expression nullCheck) GetPropertyValue var names = fullPropertyName.Split('.'); for (var i = 0; i < names.Length; i++) { - propertyValue = Expression.PropertyOrField(propertyValue, names[i]); + propertyValue = propertyValue.GeneratePropertyAccess(names[i]); if (i != names.Length - 1 && propertyValue.Type.IsNullable()) { @@ -368,7 +368,7 @@ protected virtual IQueryable ApplySorting(TSieveModel model, I if (property != null) { - result = result.OrderByDynamic(fullName, property, sortTerm.Descending, useThenBy, Options.Value.DisableNullableTypeExpressionForSorting); + result = result.OrderByDynamic(fullName, sortTerm.Descending, useThenBy, Options.Value.DisableNullableTypeExpressionForSorting); } else { diff --git a/SieveUnitTests/Abstractions/Entity/IBaseEntity.cs b/SieveUnitTests/Abstractions/Entity/IBaseEntity.cs index ce1edf9..6c1b16b 100644 --- a/SieveUnitTests/Abstractions/Entity/IBaseEntity.cs +++ b/SieveUnitTests/Abstractions/Entity/IBaseEntity.cs @@ -1,8 +1,9 @@ using System; +using SieveUnitTests.Abstractions.Strategy; namespace SieveUnitTests.Abstractions.Entity { - public interface IBaseEntity + public interface IBaseEntity: ISupportSoftDelete { int Id { get; set; } DateTimeOffset DateCreated { get; set; } diff --git a/SieveUnitTests/Abstractions/Entity/IPost.cs b/SieveUnitTests/Abstractions/Entity/IPost.cs index b05d365..5453c5e 100644 --- a/SieveUnitTests/Abstractions/Entity/IPost.cs +++ b/SieveUnitTests/Abstractions/Entity/IPost.cs @@ -1,9 +1,10 @@ using Sieve.Attributes; +using SieveUnitTests.Abstractions.Strategy; using SieveUnitTests.Entities; namespace SieveUnitTests.Abstractions.Entity { - public interface IPost: IBaseEntity + public interface IPost: IBaseEntity, IAudit { [Sieve(CanFilter = true, CanSort = true)] string Title { get; set; } diff --git a/SieveUnitTests/Abstractions/Entity/SieveConfigurationForIPost.cs b/SieveUnitTests/Abstractions/Entity/SieveConfigurationForIPost.cs index f6270ed..bfa2f45 100644 --- a/SieveUnitTests/Abstractions/Entity/SieveConfigurationForIPost.cs +++ b/SieveUnitTests/Abstractions/Entity/SieveConfigurationForIPost.cs @@ -4,13 +4,17 @@ namespace SieveUnitTests.Abstractions.Entity { public class SieveConfigurationForIPost : ISieveConfiguration { - public void Configure(SievePropertyMapper mapper) + public static void ConfigureStatic(SievePropertyMapper mapper) { + mapper + .Property(p => p.Id) + .CanSort(); + mapper.Property(p => p.ThisHasNoAttributeButIsAccessible) .CanSort() .CanFilter() .HasName("shortname"); - + mapper.Property(p => p.TopComment.Text) .CanFilter(); @@ -32,6 +36,21 @@ public void Configure(SievePropertyMapper mapper) .Property(p => p.DateCreated) .CanSort() .HasName("CreateDate"); + + mapper + .Property(post => post.DeletedBy) + .CanSort() + .HasName("DeletedBy"); + + mapper + .Property(post => post.UpdatedBy) + .CanFilter() + .HasName("UpdatedBy"); + } + + public void Configure(SievePropertyMapper mapper) + { + ConfigureStatic(mapper); } } } diff --git a/SieveUnitTests/Abstractions/Strategy/IAudit.cs b/SieveUnitTests/Abstractions/Strategy/IAudit.cs new file mode 100644 index 0000000..a67913f --- /dev/null +++ b/SieveUnitTests/Abstractions/Strategy/IAudit.cs @@ -0,0 +1,12 @@ +using System; + +namespace SieveUnitTests.Abstractions.Strategy +{ + public interface IAudit + { + string CreatedBy { get; } + DateTime? CreatedAt { get; } + string UpdatedBy { get; } + DateTime? UpdatedAt { get; } + } +} diff --git a/SieveUnitTests/Abstractions/Strategy/ISupportSoftDelete.cs b/SieveUnitTests/Abstractions/Strategy/ISupportSoftDelete.cs new file mode 100644 index 0000000..23759c4 --- /dev/null +++ b/SieveUnitTests/Abstractions/Strategy/ISupportSoftDelete.cs @@ -0,0 +1,10 @@ +using System; + +namespace SieveUnitTests.Abstractions.Strategy +{ + public interface ISupportSoftDelete + { + string DeletedBy { get; } + DateTime? DeletedAt { get; } + } +} diff --git a/SieveUnitTests/Entities/BaseEntity.cs b/SieveUnitTests/Entities/BaseEntity.cs index 6660033..c2a3d1c 100644 --- a/SieveUnitTests/Entities/BaseEntity.cs +++ b/SieveUnitTests/Entities/BaseEntity.cs @@ -10,5 +10,8 @@ public class BaseEntity : IBaseEntity [Sieve(CanFilter = true, CanSort = true)] public DateTimeOffset DateCreated { get; set; } = DateTimeOffset.UtcNow; + + public string DeletedBy { get; set; } + public DateTime? DeletedAt { get; set; } } } diff --git a/SieveUnitTests/Entities/Post.cs b/SieveUnitTests/Entities/Post.cs index aa931e9..d93867c 100644 --- a/SieveUnitTests/Entities/Post.cs +++ b/SieveUnitTests/Entities/Post.cs @@ -30,5 +30,10 @@ public class Post : BaseEntity, IPost public Comment TopComment { get; set; } public Comment FeaturedComment { get; set; } + + public string CreatedBy { get; set; } + public DateTime? CreatedAt { get; set; } + public string UpdatedBy { get; set; } + public DateTime? UpdatedAt { get; set; } } } diff --git a/SieveUnitTests/Entities/SieveConfigurationForPost.cs b/SieveUnitTests/Entities/SieveConfigurationForPost.cs index 8a02178..e3d7782 100644 --- a/SieveUnitTests/Entities/SieveConfigurationForPost.cs +++ b/SieveUnitTests/Entities/SieveConfigurationForPost.cs @@ -4,8 +4,12 @@ namespace SieveUnitTests.Entities { public class SieveConfigurationForPost : ISieveConfiguration { - public void Configure(SievePropertyMapper mapper) + public static void ConfigureStatic(SievePropertyMapper mapper) { + mapper + .Property(p => p.Id) + .CanSort(); + mapper.Property(p => p.ThisHasNoAttributeButIsAccessible) .CanSort() .CanFilter() @@ -32,6 +36,21 @@ public void Configure(SievePropertyMapper mapper) .Property(p => p.DateCreated) .CanSort() .HasName("CreateDate"); + + mapper + .Property(post => post.DeletedBy) + .CanSort() + .HasName("DeletedBy"); + + mapper + .Property(post => post.UpdatedBy) + .CanFilter() + .HasName("UpdatedBy"); + } + + public void Configure(SievePropertyMapper mapper) + { + ConfigureStatic(mapper); } } } diff --git a/SieveUnitTests/General.cs b/SieveUnitTests/General.cs index 886ce50..1dae88a 100644 --- a/SieveUnitTests/General.cs +++ b/SieveUnitTests/General.cs @@ -3,7 +3,6 @@ using System.Linq; using Sieve.Exceptions; using Sieve.Models; -using Sieve.Services; using SieveUnitTests.Entities; using SieveUnitTests.Services; using Xunit; @@ -11,28 +10,14 @@ namespace SieveUnitTests { - public class General + public class General: TestBase { - private readonly ITestOutputHelper _testOutputHelper; - private readonly SieveProcessor _processor; - private readonly SieveProcessor _nullableProcessor; private readonly IQueryable _posts; private readonly IQueryable _comments; public General(ITestOutputHelper testOutputHelper) + : base(testOutputHelper) { - var nullableAccessor = new SieveOptionsAccessor(); - nullableAccessor.Value.IgnoreNullsOnNotEqual = false; - - _testOutputHelper = testOutputHelper; - _processor = new ApplicationSieveProcessor(new SieveOptionsAccessor(), - new SieveCustomSortMethods(), - new SieveCustomFilterMethods()); - - _nullableProcessor = new ApplicationSieveProcessor(nullableAccessor, - new SieveCustomSortMethods(), - new SieveCustomFilterMethods()); - _posts = new List { new Post @@ -77,6 +62,16 @@ public General(ITestOutputHelper testOutputHelper) new Post { Id = 4, + Title = "E", + LikeCount = 5, + IsDraft = false, + CategoryId = null, + TopComment = new Comment { Id = 4, Text = "E1" }, + UpdatedBy = "You" + }, + new Post + { + Id = 5, Title = "Yen", LikeCount = 5, IsDraft = true, @@ -117,12 +112,15 @@ public void ContainsCanBeCaseInsensitive() Filters = "Title@=*a" }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.Equal(0, result.First().Id); - Assert.True(result.Count() == 1); + Assert.Equal(0, result.First().Id); + Assert.True(result.Count() == 1); + } } - + [Fact] public void NotEqualsCanBeCaseInsensitive() { @@ -131,10 +129,13 @@ public void NotEqualsCanBeCaseInsensitive() Filters = "Title!=*a" }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.Equal(1, result.First().Id); - Assert.True(result.Count() == 4); + Assert.Equal(1, result.First().Id); + Assert.True(result.Count() == _posts.Count(post => !post.Title.Contains("a", StringComparison.OrdinalIgnoreCase))); + } } [Fact] @@ -145,14 +146,17 @@ public void EndsWithWorks() Filters = "Title_-=n" }; - _testOutputHelper.WriteLine(model.GetFiltersParsed()[0].Values.ToString()); - _testOutputHelper.WriteLine(model.GetFiltersParsed()[0].Operator); - _testOutputHelper.WriteLine(model.GetFiltersParsed()[0].OperatorParsed.ToString()); + TestOutputHelper.WriteLine(model.GetFiltersParsed()[0].Values.ToString()); + TestOutputHelper.WriteLine(model.GetFiltersParsed()[0].Operator); + TestOutputHelper.WriteLine(model.GetFiltersParsed()[0].OperatorParsed.ToString()); - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.Equal(4, result.First().Id); - Assert.True(result.Count() == 1); + Assert.Equal(_posts.First(post => post.Title.EndsWith("n")).Id, result.First().Id); + Assert.True(result.Count() == 1); + } } [Fact] @@ -163,27 +167,30 @@ public void EndsWithCanBeCaseInsensitive() Filters = "Title_-=*N" }; - _testOutputHelper.WriteLine(model.GetFiltersParsed()[0].Values.ToString()); - _testOutputHelper.WriteLine(model.GetFiltersParsed()[0].Operator); - _testOutputHelper.WriteLine(model.GetFiltersParsed()[0].OperatorParsed.ToString()); + TestOutputHelper.WriteLine(model.GetFiltersParsed()[0].Values.ToString()); + TestOutputHelper.WriteLine(model.GetFiltersParsed()[0].Operator); + TestOutputHelper.WriteLine(model.GetFiltersParsed()[0].OperatorParsed.ToString()); - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.Equal(4, result.First().Id); - Assert.True(result.Count() == 1); + Assert.Equal(_posts.First(post => post.Title.EndsWith("N", StringComparison.OrdinalIgnoreCase)).Id, result.First().Id); + Assert.True(result.Count() == 1); + } } [Fact] public void ContainsIsCaseSensitive() { - var model = new SieveModel - { - Filters = "Title@=a", - }; + var model = new SieveModel { Filters = "Title@=a", }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.True(!result.Any()); + Assert.True(!result.Any()); + } } [Fact] @@ -194,65 +201,70 @@ public void NotContainsWorks() Filters = "Title!@=D", }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.True(result.Count() == 4); + Assert.True(result.Count() == _posts.Count(post => !post.Title.Contains("D"))); + } } [Fact] public void CanFilterBools() { - var model = new SieveModel - { - Filters = "IsDraft==false" - }; + var model = new SieveModel { Filters = "IsDraft==false" }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.True(result.Count() == 2); + Assert.True(result.Count() == _posts.Count(post => !post.IsDraft)); + } } [Fact] public void CanSortBools() { - var model = new SieveModel - { - Sorts = "-IsDraft" - }; + var model = new SieveModel { Sorts = "-IsDraft" }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.Equal(0, result.First().Id); + Assert.Equal(0, result.First().Id); + } } [Fact] public void CanFilterNullableInts() { - var model = new SieveModel - { - Filters = "CategoryId==1" - }; + var model = new SieveModel { Filters = "CategoryId==1" }; - var result = _processor.Apply(model, _posts); - var nullableResult = _nullableProcessor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.True(result.Count() == 2); - Assert.True(nullableResult.Count() == 2); + Assert.True(result.Count() == _posts.Count(post => post.CategoryId == 1)); + } } [Fact] public void CanFilterNullableIntsWithNotEqual() { - var model = new SieveModel() - { - Filters = "CategoryId!=1" - }; + var model = new SieveModel() { Filters = "CategoryId!=1" }; - var result = _processor.Apply(model, _posts); - var nullableResult = _nullableProcessor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.True(result.Count() == 2); - Assert.True(nullableResult.Count() == 3); + Assert.Equal + ( + (sieveProcessor as ApplicationSieveProcessor)?.ExposedOptions.IgnoreNullsOnNotEqual ?? true + ? _posts.Count(post => post.CategoryId != null && post.CategoryId != 1) + : _posts.Count(post => post.CategoryId != 1), + result.Count() + ); + } } [Theory] @@ -267,97 +279,100 @@ public void CanFilterWithEscapedComma(string filter) Filters = filter }; - var result = _processor.Apply(model, _comments); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _comments); - Assert.True(result.Count() == 1); + Assert.True(result.Count() == 1); + } } [Fact] public void EqualsDoesntFailWithNonStringTypes() { - var model = new SieveModel - { - Filters = "LikeCount==50", - }; + var model = new SieveModel { Filters = "LikeCount==50", }; - _testOutputHelper.WriteLine(model.GetFiltersParsed()[0].Values.ToString()); - _testOutputHelper.WriteLine(model.GetFiltersParsed()[0].Operator); - _testOutputHelper.WriteLine(model.GetFiltersParsed()[0].OperatorParsed.ToString()); + TestOutputHelper.WriteLine(model.GetFiltersParsed()[0].Values.ToString()); + TestOutputHelper.WriteLine(model.GetFiltersParsed()[0].Operator); + TestOutputHelper.WriteLine(model.GetFiltersParsed()[0].OperatorParsed.ToString()); - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.Equal(1, result.First().Id); - Assert.True(result.Count() == 1); + Assert.Equal(1, result.First().Id); + Assert.True(result.Count() == 1); + } } [Fact] public void CustomFiltersWork() { - var model = new SieveModel - { - Filters = "Isnew", - }; + var model = new SieveModel { Filters = "Isnew", }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.False(result.Any(p => p.Id == 0)); - Assert.True(result.Count() == 4); + Assert.False(result.Any(p => p.Id == 0)); + Assert.True(result.Count() == _posts.Count(SieveCustomFilterMethods.IsNewFilterForPost)); + } } [Fact] public void CustomGenericFiltersWork() { - var model = new SieveModel - { - Filters = "Latest", - }; + var model = new SieveModel { Filters = "Latest", }; - var result = _processor.Apply(model, _comments); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _comments); - Assert.False(result.Any(p => p.Id == 0)); - Assert.True(result.Count() == 2); + Assert.False(result.Any(p => p.Id == 0)); + Assert.True(result.Count() == 2); + } } [Fact] public void CustomFiltersWithOperatorsWork() { - var model = new SieveModel - { - Filters = "HasInTitle==A", - }; + var model = new SieveModel { Filters = "HasInTitle==A", }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.True(result.Any(p => p.Id == 0)); - Assert.True(result.Count() == 1); + Assert.True(result.Any(p => p.Id == 0)); + Assert.True(result.Count() == 1); + } } [Fact] public void CustomFiltersMixedWithUsualWork1() { - var model = new SieveModel - { - Filters = "Isnew,CategoryId==2", - }; + var model = new SieveModel { Filters = "Isnew,CategoryId==2", }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.True(result.Any(p => p.Id == 3)); - Assert.True(result.Count() == 1); + Assert.True(result.Any(p => p.Id == 3)); + Assert.True(result.Count() == 1); + } } [Fact] public void CustomFiltersMixedWithUsualWork2() { - var model = new SieveModel - { - Filters = "CategoryId==2,Isnew", - }; + var model = new SieveModel { Filters = "CategoryId==2,Isnew", }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.True(result.Any(p => p.Id == 3)); - Assert.True(result.Count() == 1); + Assert.True(result.Any(p => p.Id == 3)); + Assert.True(result.Count() == 1); + } } [Fact] @@ -368,85 +383,91 @@ public void CustomFiltersOnDifferentSourcesCanShareName() Filters = "CategoryId==2,Isnew", }; - var postResult = _processor.Apply(postModel, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var postResult = sieveProcessor.Apply(postModel, _posts); - Assert.True(postResult.Any(p => p.Id == 3)); - Assert.Equal(1, postResult.Count()); + Assert.True(postResult.Any(p => p.Id == 3)); + Assert.Equal(1, postResult.Count()); + } var commentModel = new SieveModel { Filters = "Isnew", }; - var commentResult = _processor.Apply(commentModel, _comments); + foreach (var sieveProcessor in GetProcessors()) + { + var commentResult = sieveProcessor.Apply(commentModel, _comments); - Assert.True(commentResult.Any(c => c.Id == 2)); - Assert.Equal(2, commentResult.Count()); + Assert.True(commentResult.Any(c => c.Id == 2)); + Assert.Equal(2, commentResult.Count()); + } } [Fact] public void CustomSortsWork() { - var model = new SieveModel - { - Sorts = "Popularity", - }; + var model = new SieveModel { Sorts = "Popularity", }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.False(result.First().Id == 0); + Assert.False(result.First().Id == 0); + } } [Fact] public void CustomGenericSortsWork() { - var model = new SieveModel - { - Sorts = "Oldest", - }; + var model = new SieveModel { Sorts = "Oldest", }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.True(result.Last().Id == 0); + Assert.True(result.Last().Id == 0); + } } [Fact] public void MethodNotFoundExceptionWork() { - var model = new SieveModel - { - Filters = "does not exist", - }; + var model = new SieveModel { Filters = "does not exist", }; - Assert.Throws(() => _processor.Apply(model, _posts)); + foreach (var sieveProcessor in GetProcessors()) + { + Assert.Throws(() => sieveProcessor.Apply(model, _posts)); + } } [Fact] public void IncompatibleMethodExceptionsWork() { - var model = new SieveModel - { - Filters = "TestComment", - }; + var model = new SieveModel { Filters = "TestComment", }; - Assert.Throws(() => _processor.Apply(model, _posts)); + foreach (var sieveProcessor in GetProcessors()) + { + Assert.Throws(() => sieveProcessor.Apply(model, _posts)); + } } [Fact] public void OrNameFilteringWorks() { - var model = new SieveModel - { - Filters = "(Title|LikeCount)==3", - }; + var model = new SieveModel { Filters = "(Title|LikeCount)==3", }; - var result = _processor.Apply(model, _posts); - var entry = result.FirstOrDefault(); - var resultCount = result.Count(); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + var entry = result.FirstOrDefault(); + var resultCount = result.Count(); - Assert.NotNull(entry); - Assert.Equal(1, resultCount); - Assert.Equal(3, entry.Id); + Assert.NotNull(entry); + Assert.Equal(1, resultCount); + Assert.Equal(3, entry.Id); + } } [Theory] @@ -454,96 +475,105 @@ public void OrNameFilteringWorks() [InlineData("(CategoryId|LikeCount)==50,CategoryId==1")] public void CombinedAndOrFilterIndependentOfOrder(string filter) { - var model = new SieveModel - { - Filters = filter, - }; + var model = new SieveModel { Filters = filter, }; - var result = _processor.Apply(model, _posts); - var entry = result.FirstOrDefault(); - var resultCount = result.Count(); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + var entry = result.FirstOrDefault(); + var resultCount = result.Count(); - Assert.NotNull(entry); - Assert.Equal(1, resultCount); + Assert.NotNull(entry); + Assert.Equal(1, resultCount); + } } [Fact] public void CombinedAndOrWithSpaceFilteringWorks() { - var model = new SieveModel - { - Filters = "Title==D, (Title|LikeCount)==3", - }; + var model = new SieveModel { Filters = "Title==D, (Title|LikeCount)==3", }; - var result = _processor.Apply(model, _posts); - var entry = result.FirstOrDefault(); - var resultCount = result.Count(); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + var entry = result.FirstOrDefault(); + var resultCount = result.Count(); - Assert.NotNull(entry); - Assert.Equal(1, resultCount); - Assert.Equal(3, entry.Id); + Assert.NotNull(entry); + Assert.Equal(1, resultCount); + Assert.Equal(3, entry.Id); + } } [Fact] public void OrValueFilteringWorks() { - var model = new SieveModel - { - Filters = "Title==C|D", - }; + var model = new SieveModel { Filters = "Title==C|D", }; - var result = _processor.Apply(model, _posts); - Assert.Equal(2, result.Count()); - Assert.True(result.Any(p => p.Id == 2)); - Assert.True(result.Any(p => p.Id == 3)); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + Assert.Equal(2, result.Count()); + Assert.True(result.Any(p => p.Id == 2)); + Assert.True(result.Any(p => p.Id == 3)); + } } [Fact] public void OrValueFilteringWorks2() { - var model = new SieveModel - { - Filters = "Text@=(|)", - }; + var model = new SieveModel { Filters = "Text@=(|)", }; - var result = _processor.Apply(model, _comments); - Assert.Equal(1, result.Count()); - Assert.Equal(2, result.FirstOrDefault()?.Id); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _comments); + Assert.Equal(1, result.Count()); + Assert.Equal(2, result.FirstOrDefault()?.Id); + } } [Fact] public void NestedFilteringWorks() { - var model = new SieveModel - { - Filters = "TopComment.Text!@=A", - }; + var model = new SieveModel { Filters = "TopComment.Text!@=A", }; - var result = _processor.Apply(model, _posts); - Assert.Equal(4, result.Count()); - var posts = result.ToList(); - Assert.Contains("B", posts[0].TopComment.Text); - Assert.Contains("C", posts[1].TopComment.Text); - Assert.Contains("D", posts[2].TopComment.Text); - Assert.Contains("Yen", posts[3].TopComment.Text); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + Assert.Equal(_posts.Count(post => !post.TopComment.Text.Contains("A")), result.Count()); + var posts = result.ToList(); + Assert.Contains("B", posts[0].TopComment.Text); + Assert.Contains("C", posts[1].TopComment.Text); + Assert.Contains("D", posts[2].TopComment.Text); + Assert.Contains("E1", posts[3].TopComment.Text); + Assert.Contains("Yen", posts[4].TopComment.Text); + } } [Fact] public void NestedSortingWorks() { - var model = new SieveModel + var model = new SieveModel { Sorts = "TopComment.Id", }; + + foreach (var sieveProcessor in GetProcessors()) { - Sorts = "TopComment.Id", - }; + var result = sieveProcessor.Apply(model, _posts); + Assert.Equal(_posts.Count(), result.Count()); + var posts = result + .Select(post => post.Id) + .ToList(); - var result = _processor.Apply(model, _posts); - Assert.Equal(5, result.Count()); - var posts = result.ToList(); - Assert.Equal(0, posts[0].Id); - Assert.Equal(3, posts[1].Id); - Assert.Equal(2, posts[2].Id); - Assert.Equal(1, posts[3].Id); - Assert.Equal(4, posts[4].Id); + Assert.True + ( + posts.SequenceEqual + ( + _posts + .AsEnumerable() + .OrderBy(post => post.TopComment.Id) + .Select(post => post.Id) + ) + ); + } } [Fact] @@ -554,16 +584,22 @@ public void NestedFilteringWithIdenticTypesWorks() Filters = "(topc|featc)@=*2", }; - var result = _processor.Apply(model, _posts); - Assert.Equal(4, result.Count()); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + Assert.Equal(4, result.Count()); + } model = new SieveModel { Filters = "(topc|featc)@=*B", }; - result = _processor.Apply(model, _posts); - Assert.Equal(1, result.Count()); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + Assert.Equal(1, result.Count()); + } } [Fact] @@ -583,13 +619,13 @@ public void FilteringNullsWorks() }, }.AsQueryable(); - var model = new SieveModel - { - Filters = "FeaturedComment.Text!@=Some value", - }; + var model = new SieveModel { Filters = "FeaturedComment.Text!@=Some value", }; - var result = _processor.Apply(model, posts); - Assert.Equal(0, result.Count()); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, posts); + Assert.Equal(0, result.Count()); + } } [Fact] @@ -624,11 +660,14 @@ public void SortingNullsWorks() Sorts = "TopComment.Id", }; - var result = _processor.Apply(model, posts); - Assert.Equal(2, result.Count()); - var sortedPosts = result.ToList(); - Assert.Equal(2, sortedPosts[0].Id); - Assert.Equal(1, sortedPosts[1].Id); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, posts); + Assert.Equal(2, result.Count()); + var sortedPosts = result.ToList(); + Assert.Equal(2, sortedPosts[0].Id); + Assert.Equal(1, sortedPosts[1].Id); + } } [Fact] @@ -663,10 +702,13 @@ public void FilteringOnNullWorks() Filters = "FeaturedComment.Text==null", }; - var result = _processor.Apply(model, posts); - Assert.Equal(1, result.Count()); - var filteredPosts = result.ToList(); - Assert.Equal(2, filteredPosts[0].Id); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, posts); + Assert.Equal(1, result.Count()); + var filteredPosts = result.ToList(); + Assert.Equal(2, filteredPosts[0].Id); + } } [Fact] @@ -677,16 +719,25 @@ public void BaseDefinedPropertyMappingSortingWorks_WithCustomName() Sorts = "-CreateDate" }; - var result = _processor.Apply(model, _posts); - Assert.Equal(5, result.Count()); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + Assert.Equal(_posts.Count(), result.Count()); - var posts = result.ToList(); - Assert.Equal(4, posts[0].Id); - Assert.Equal(3,posts[1].Id); - Assert.Equal(2,posts[2].Id); - Assert.Equal(1,posts[3].Id); - Assert.Equal(0,posts[4].Id); + var posts = result + .Select(post => post.Id) + .ToList(); + Assert.True + ( + posts.SequenceEqual + ( + _posts + .OrderByDescending(post => post.DateCreated) + .Select(post => post.Id) + ) + ); + } } [Fact] @@ -713,8 +764,11 @@ public void CanFilter_WithEscapeCharacter() Filters = "Text==Here is\\, another comment" }; - var result = _processor.Apply(model, comments); - Assert.Equal(1, result.Count()); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, comments); + Assert.Equal(1, result.Count()); + } } [Fact] @@ -747,8 +801,11 @@ public void OrEscapedPipeValueFilteringWorks() Filters = @"Text==Here is \| a comment|Here is \| another comment|Here is \\\| another comment(1)", }; - var result = _processor.Apply(model, comments); - Assert.Equal(3, result.Count()); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, comments); + Assert.Equal(3, result.Count()); + } } [Theory] @@ -761,12 +818,15 @@ public void CanFilterWithEscape(string filter) Filters = filter }; - var result = _processor.Apply(model, _posts); - var entry = result.FirstOrDefault(); - var resultCount = result.Count(); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + var entry = result.FirstOrDefault(); + var resultCount = result.Count(); - Assert.NotNull(entry); - Assert.Equal(1, resultCount); + Assert.NotNull(entry); + Assert.Equal(1, resultCount); + } } [Theory] @@ -792,12 +852,15 @@ public void CanFilterWithEscapedBackSlash(string filter) Filters = filter }; - var result = _processor.Apply(model, posts); - var entry = result.FirstOrDefault(); - var resultCount = result.Count(); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, posts); + var entry = result.FirstOrDefault(); + var resultCount = result.Count(); - Assert.NotNull(entry); - Assert.Equal(1, resultCount); + Assert.NotNull(entry); + Assert.Equal(1, resultCount); + } } [Theory] @@ -840,13 +903,15 @@ public void CanFilterWithEscapedOperators(string filter) Filters = filter, }; - var result = _processor.Apply(model, posts); - var entry = result.FirstOrDefault(); - var resultCount = result.Count(); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, posts); + var entry = result.FirstOrDefault(); + var resultCount = result.Count(); - Assert.NotNull(entry); - Assert.Equal(1, resultCount); + Assert.NotNull(entry); + Assert.Equal(1, resultCount); + } } - } } diff --git a/SieveUnitTests/GeneralWithInterfaces.cs b/SieveUnitTests/GeneralWithInterfaces.cs index f23db16..4adedcd 100644 --- a/SieveUnitTests/GeneralWithInterfaces.cs +++ b/SieveUnitTests/GeneralWithInterfaces.cs @@ -3,7 +3,6 @@ using System.Linq; using Sieve.Exceptions; using Sieve.Models; -using Sieve.Services; using SieveUnitTests.Abstractions.Entity; using SieveUnitTests.Entities; using SieveUnitTests.Services; @@ -12,28 +11,14 @@ namespace SieveUnitTests { - public class GeneralWithInterfaces + public class GeneralWithInterfaces: TestBase { - private readonly ITestOutputHelper _testOutputHelper; - private readonly SieveProcessor _processor; - private readonly SieveProcessor _nullableProcessor; private readonly IQueryable _posts; private readonly IQueryable _comments; public GeneralWithInterfaces(ITestOutputHelper testOutputHelper) + : base(testOutputHelper) { - var nullableAccessor = new SieveOptionsAccessor(); - nullableAccessor.Value.IgnoreNullsOnNotEqual = false; - - _testOutputHelper = testOutputHelper; - _processor = new ApplicationSieveProcessor(new SieveOptionsAccessor(), - new SieveCustomSortMethods(), - new SieveCustomFilterMethods()); - - _nullableProcessor = new ApplicationSieveProcessor(nullableAccessor, - new SieveCustomSortMethods(), - new SieveCustomFilterMethods()); - _posts = new List { new Post @@ -44,7 +29,8 @@ public GeneralWithInterfaces(ITestOutputHelper testOutputHelper) IsDraft = true, CategoryId = null, TopComment = new Comment { Id = 0, Text = "A1" }, - FeaturedComment = new Comment { Id = 4, Text = "A2" } + FeaturedComment = new Comment { Id = 4, Text = "A2" }, + DeletedBy = "Me" }, new Post { @@ -54,7 +40,9 @@ public GeneralWithInterfaces(ITestOutputHelper testOutputHelper) IsDraft = false, CategoryId = 1, TopComment = new Comment { Id = 3, Text = "B1" }, - FeaturedComment = new Comment { Id = 5, Text = "B2" } + FeaturedComment = new Comment { Id = 5, Text = "B2" }, + DeletedBy = "You", + UpdatedBy = "Me" }, new Post { @@ -63,7 +51,9 @@ public GeneralWithInterfaces(ITestOutputHelper testOutputHelper) LikeCount = 0, CategoryId = 1, TopComment = new Comment { Id = 2, Text = "C1" }, - FeaturedComment = new Comment { Id = 6, Text = "C2" } + FeaturedComment = new Comment { Id = 6, Text = "C2" }, + DeletedBy = "Not Me", + UpdatedBy = "Your highness" }, new Post { @@ -73,8 +63,29 @@ public GeneralWithInterfaces(ITestOutputHelper testOutputHelper) IsDraft = true, CategoryId = 2, TopComment = new Comment { Id = 1, Text = "D1" }, - FeaturedComment = new Comment { Id = 7, Text = "D2" } + FeaturedComment = new Comment { Id = 7, Text = "D2" }, + UpdatedBy = "Him" }, + new Post + { + Id = 4, + Title = "E", + LikeCount = 5, + IsDraft = false, + CategoryId = null, + TopComment = new Comment { Id = 4, Text = "E1" }, + UpdatedBy = "You" + }, + new Post + { + Id = 5, + Title = "Yen", + LikeCount = 5, + IsDraft = true, + CategoryId = 5, + TopComment = new Comment { Id = 4, Text = "Yen3" }, + FeaturedComment = new Comment { Id = 8, Text = "Yen4" } + } }.AsQueryable(); _comments = new List @@ -108,10 +119,13 @@ public void ContainsCanBeCaseInsensitive() Filters = "Title@=*a" }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.Equal(0, result.First().Id); - Assert.True(result.Count() == 1); + Assert.Equal(0, result.First().Id); + Assert.True(result.Count() == 1); + } } [Fact] @@ -122,23 +136,26 @@ public void NotEqualsCanBeCaseInsensitive() Filters = "Title!=*a" }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.Equal(1, result.First().Id); - Assert.True(result.Count() == 3); + Assert.Equal(1, result.First().Id); + Assert.True(result.Count() == _posts.Count(post => !post.Title.Contains("a", StringComparison.OrdinalIgnoreCase))); + } } [Fact] public void ContainsIsCaseSensitive() { - var model = new SieveModel - { - Filters = "Title@=a", - }; + var model = new SieveModel { Filters = "Title@=a", }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.True(!result.Any()); + Assert.True(!result.Any()); + } } [Fact] @@ -149,153 +166,158 @@ public void NotContainsWorks() Filters = "Title!@=D", }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.True(result.Count() == 3); + Assert.True(result.Count() == _posts.Count(post => !post.Title.Contains("D"))); + } } [Fact] public void CanFilterBools() { - var model = new SieveModel - { - Filters = "IsDraft==false" - }; + var model = new SieveModel { Filters = "IsDraft==false" }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.True(result.Count() == 2); + Assert.True(result.Count() == _posts.Count(post => !post.IsDraft)); + } } [Fact] public void CanSortBools() { - var model = new SieveModel - { - Sorts = "-IsDraft" - }; + var model = new SieveModel { Sorts = "-IsDraft" }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.Equal(0, result.First().Id); + Assert.Equal(0, result.First().Id); + } } [Fact] public void CanFilterNullableInts() { - var model = new SieveModel - { - Filters = "CategoryId==1" - }; - - var result = _processor.Apply(model, _posts); - var nullableResult = _nullableProcessor.Apply(model, _posts); + var model = new SieveModel { Filters = "CategoryId==1" }; - Assert.True(result.Count() == 2); - Assert.True(nullableResult.Count() == 2); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + + Assert.True(result.Count() == _posts.Count(post => post.CategoryId == 1)); + } } [Fact] public void CanFilterNullableIntsWithNotEqual() { - var model = new SieveModel() - { - Filters = "CategoryId!=1" - }; + var model = new SieveModel() { Filters = "CategoryId!=1" }; - var result = _processor.Apply(model, _posts); - var nullableResult = _nullableProcessor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.True(result.Count() == 1); - Assert.True(nullableResult.Count() == 2); + Assert.Equal + ( + (sieveProcessor as ApplicationSieveProcessor)?.ExposedOptions.IgnoreNullsOnNotEqual ?? true + ? _posts.Count(post => post.CategoryId != null && post.CategoryId != 1) + : _posts.Count(post => post.CategoryId != 1), + result.Count() + ); + } } [Fact] public void EqualsDoesntFailWithNonStringTypes() { - var model = new SieveModel - { - Filters = "LikeCount==50", - }; + var model = new SieveModel { Filters = "LikeCount==50", }; - _testOutputHelper.WriteLine(model.GetFiltersParsed()[0].Values.ToString()); - _testOutputHelper.WriteLine(model.GetFiltersParsed()[0].Operator); - _testOutputHelper.WriteLine(model.GetFiltersParsed()[0].OperatorParsed.ToString()); + TestOutputHelper.WriteLine(model.GetFiltersParsed()[0].Values.ToString()); + TestOutputHelper.WriteLine(model.GetFiltersParsed()[0].Operator); + TestOutputHelper.WriteLine(model.GetFiltersParsed()[0].OperatorParsed.ToString()); - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.Equal(1, result.First().Id); - Assert.True(result.Count() == 1); + Assert.Equal(1, result.First().Id); + Assert.True(result.Count() == 1); + } } [Fact] public void CustomFiltersWork() { - var model = new SieveModel - { - Filters = "Isnew", - }; + var model = new SieveModel { Filters = "Isnew", }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.False(result.Any(p => p.Id == 0)); - Assert.True(result.Count() == 3); + Assert.False(result.Any(p => p.Id == 0)); + Assert.True(result.Count() == _posts.Count(SieveCustomFilterMethods.IsNewFilterForIPost)); + } } [Fact] public void CustomGenericFiltersWork() { - var model = new SieveModel - { - Filters = "Latest", - }; + var model = new SieveModel { Filters = "Latest", }; - var result = _processor.Apply(model, _comments); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _comments); - Assert.False(result.Any(p => p.Id == 0)); - Assert.True(result.Count() == 2); + Assert.False(result.Any(p => p.Id == 0)); + Assert.True(result.Count() == 2); + } } [Fact] public void CustomFiltersWithOperatorsWork() { - var model = new SieveModel - { - Filters = "HasInTitle==A", - }; + var model = new SieveModel { Filters = "HasInTitle==A", }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.True(result.Any(p => p.Id == 0)); - Assert.True(result.Count() == 1); + Assert.True(result.Any(p => p.Id == 0)); + Assert.True(result.Count() == 1); + } } [Fact] public void CustomFiltersMixedWithUsualWork1() { - var model = new SieveModel - { - Filters = "Isnew,CategoryId==2", - }; + var model = new SieveModel { Filters = "Isnew,CategoryId==2", }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.True(result.Any(p => p.Id == 3)); - Assert.True(result.Count() == 1); + Assert.True(result.Any(p => p.Id == 3)); + Assert.True(result.Count() == 1); + } } [Fact] public void CustomFiltersMixedWithUsualWork2() { - var model = new SieveModel - { - Filters = "CategoryId==2,Isnew", - }; + var model = new SieveModel { Filters = "CategoryId==2,Isnew", }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.True(result.Any(p => p.Id == 3)); - Assert.True(result.Count() == 1); + Assert.True(result.Any(p => p.Id == 3)); + Assert.True(result.Count() == 1); + } } [Fact] @@ -306,85 +328,91 @@ public void CustomFiltersOnDifferentSourcesCanShareName() Filters = "CategoryId==2,Isnew", }; - var postResult = _processor.Apply(postModel, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var postResult = sieveProcessor.Apply(postModel, _posts); - Assert.True(postResult.Any(p => p.Id == 3)); - Assert.Equal(1, postResult.Count()); + Assert.True(postResult.Any(p => p.Id == 3)); + Assert.Equal(1, postResult.Count()); + } var commentModel = new SieveModel { Filters = "Isnew", }; - var commentResult = _processor.Apply(commentModel, _comments); + foreach (var sieveProcessor in GetProcessors()) + { + var commentResult = sieveProcessor.Apply(commentModel, _comments); - Assert.True(commentResult.Any(c => c.Id == 2)); - Assert.Equal(2, commentResult.Count()); + Assert.True(commentResult.Any(c => c.Id == 2)); + Assert.Equal(2, commentResult.Count()); + } } [Fact] public void CustomSortsWork() { - var model = new SieveModel - { - Sorts = "Popularity", - }; + var model = new SieveModel { Sorts = "Popularity", }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.False(result.First().Id == 0); + Assert.False(result.First().Id == 0); + } } [Fact] public void CustomGenericSortsWork() { - var model = new SieveModel - { - Sorts = "Oldest", - }; + var model = new SieveModel { Sorts = "Oldest", }; - var result = _processor.Apply(model, _posts); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); - Assert.True(result.Last().Id == 0); + Assert.True(result.Last().Id == 0); + } } [Fact] public void MethodNotFoundExceptionWork() { - var model = new SieveModel - { - Filters = "does not exist", - }; + var model = new SieveModel { Filters = "does not exist", }; - Assert.Throws(() => _processor.Apply(model, _posts)); + foreach (var sieveProcessor in GetProcessors()) + { + Assert.Throws(() => sieveProcessor.Apply(model, _posts)); + } } [Fact] public void IncompatibleMethodExceptionsWork() { - var model = new SieveModel - { - Filters = "TestComment", - }; + var model = new SieveModel { Filters = "TestComment", }; - Assert.Throws(() => _processor.Apply(model, _posts)); + foreach (var sieveProcessor in GetProcessors()) + { + Assert.Throws(() => sieveProcessor.Apply(model, _posts)); + } } [Fact] public void OrNameFilteringWorks() { - var model = new SieveModel - { - Filters = "(Title|LikeCount)==3", - }; + var model = new SieveModel { Filters = "(Title|LikeCount)==3", }; - var result = _processor.Apply(model, _posts); - var entry = result.FirstOrDefault(); - var resultCount = result.Count(); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + var entry = result.FirstOrDefault(); + var resultCount = result.Count(); - Assert.NotNull(entry); - Assert.Equal(1, resultCount); - Assert.Equal(3, entry.Id); + Assert.NotNull(entry); + Assert.Equal(1, resultCount); + Assert.Equal(3, entry.Id); + } } [Theory] @@ -392,94 +420,105 @@ public void OrNameFilteringWorks() [InlineData("(CategoryId|LikeCount)==50,CategoryId==1")] public void CombinedAndOrFilterIndependentOfOrder(string filter) { - var model = new SieveModel - { - Filters = filter, - }; + var model = new SieveModel { Filters = filter, }; - var result = _processor.Apply(model, _posts); - var entry = result.FirstOrDefault(); - var resultCount = result.Count(); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + var entry = result.FirstOrDefault(); + var resultCount = result.Count(); - Assert.NotNull(entry); - Assert.Equal(1, resultCount); + Assert.NotNull(entry); + Assert.Equal(1, resultCount); + } } [Fact] public void CombinedAndOrWithSpaceFilteringWorks() { - var model = new SieveModel - { - Filters = "Title==D, (Title|LikeCount)==3", - }; + var model = new SieveModel { Filters = "Title==D, (Title|LikeCount)==3", }; - var result = _processor.Apply(model, _posts); - var entry = result.FirstOrDefault(); - var resultCount = result.Count(); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + var entry = result.FirstOrDefault(); + var resultCount = result.Count(); - Assert.NotNull(entry); - Assert.Equal(1, resultCount); - Assert.Equal(3, entry.Id); + Assert.NotNull(entry); + Assert.Equal(1, resultCount); + Assert.Equal(3, entry.Id); + } } [Fact] public void OrValueFilteringWorks() { - var model = new SieveModel - { - Filters = "Title==C|D", - }; + var model = new SieveModel { Filters = "Title==C|D", }; - var result = _processor.Apply(model, _posts); - Assert.Equal(2, result.Count()); - Assert.True(result.Any(p => p.Id == 2)); - Assert.True(result.Any(p => p.Id == 3)); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + Assert.Equal(2, result.Count()); + Assert.True(result.Any(p => p.Id == 2)); + Assert.True(result.Any(p => p.Id == 3)); + } } [Fact] public void OrValueFilteringWorks2() { - var model = new SieveModel - { - Filters = "Text@=(|)", - }; + var model = new SieveModel { Filters = "Text@=(|)", }; - var result = _processor.Apply(model, _comments); - Assert.Equal(1, result.Count()); - Assert.Equal(2, result.FirstOrDefault()?.Id); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _comments); + Assert.Equal(1, result.Count()); + Assert.Equal(2, result.FirstOrDefault()?.Id); + } } [Fact] public void NestedFilteringWorks() { - var model = new SieveModel - { - Filters = "TopComment.Text!@=A", - }; + var model = new SieveModel { Filters = "TopComment.Text!@=A", }; - var result = _processor.Apply(model, _posts); - Assert.Equal(3, result.Count()); - var posts = result.ToList(); - Assert.Contains("B", posts[0].TopComment.Text); - Assert.Contains("C", posts[1].TopComment.Text); - Assert.Contains("D", posts[2].TopComment.Text); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + Assert.Equal(_posts.Count(post => !post.TopComment.Text.Contains("A")), result.Count()); + var posts = result.ToList(); + Assert.Contains("B", posts[0].TopComment.Text); + Assert.Contains("C", posts[1].TopComment.Text); + Assert.Contains("D", posts[2].TopComment.Text); + Assert.Contains("E1", posts[3].TopComment.Text); + Assert.Contains("Yen", posts[4].TopComment.Text); + } } [Fact] public void NestedSortingWorks() { - var model = new SieveModel + var model = new SieveModel { Sorts = "TopComment.Id", }; + + foreach (var sieveProcessor in GetProcessors()) { - Sorts = "TopComment.Id", - }; + var result = sieveProcessor.Apply(model, _posts); + Assert.Equal(_posts.Count(), result.Count()); + var posts = result + .Select(post => post.Id) + .ToList(); - var result = _processor.Apply(model, _posts); - Assert.Equal(4, result.Count()); - var posts = result.ToList(); - Assert.Equal(0, posts[0].Id); - Assert.Equal(3, posts[1].Id); - Assert.Equal(2, posts[2].Id); - Assert.Equal(1, posts[3].Id); + Assert.True + ( + posts.SequenceEqual + ( + _posts + .AsEnumerable() + .OrderBy(post => post.TopComment.Id) + .Select(post => post.Id) + ) + ); + } } [Fact] @@ -490,16 +529,22 @@ public void NestedFilteringWithIdenticTypesWorks() Filters = "(topc|featc)@=*2", }; - var result = _processor.Apply(model, _posts); - Assert.Equal(4, result.Count()); - + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + Assert.Equal(4, result.Count()); + } + model = new SieveModel { Filters = "(topc|featc)@=*B", }; - result = _processor.Apply(model, _posts); - Assert.Equal(1, result.Count()); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + Assert.Equal(1, result.Count()); + } } [Fact] @@ -519,13 +564,13 @@ public void FilteringNullsWorks() }, }.AsQueryable(); - var model = new SieveModel - { - Filters = "FeaturedComment.Text!@=Some value", - }; + var model = new SieveModel { Filters = "FeaturedComment.Text!@=Some value", }; - var result = _processor.Apply(model, posts); - Assert.Equal(0, result.Count()); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, posts); + Assert.Equal(0, result.Count()); + } } [Fact] @@ -540,7 +585,7 @@ public void SortingNullsWorks() LikeCount = 0, IsDraft = false, CategoryId = null, - TopComment = new Comment { Id = 1 }, + TopComment = new Comment { Id = 1 }, FeaturedComment = null }, new Post @@ -555,16 +600,16 @@ public void SortingNullsWorks() }, }.AsQueryable(); - var model = new SieveModel - { - Sorts = "TopComment.Id", - }; + var model = new SieveModel { Sorts = "TopComment.Id", }; - var result = _processor.Apply(model, posts); - Assert.Equal(2, result.Count()); - var sortedPosts = result.ToList(); - Assert.Equal(2, sortedPosts[0].Id); - Assert.Equal(1, sortedPosts[1].Id); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, posts); + Assert.Equal(2, result.Count()); + var sortedPosts = result.ToList(); + Assert.Equal(2, sortedPosts[0].Id); + Assert.Equal(1, sortedPosts[1].Id); + } } [Fact] @@ -590,37 +635,98 @@ public void FilteringOnNullWorks() IsDraft = false, CategoryId = null, TopComment = null, - FeaturedComment = new Comment { Id = 1, Text = null } + FeaturedComment = new Comment { Id = 1, Text = null } }, }.AsQueryable(); - var model = new SieveModel - { - Filters = "FeaturedComment.Text==null", - }; + var model = new SieveModel { Filters = "FeaturedComment.Text==null", }; - var result = _processor.Apply(model, posts); - Assert.Equal(1, result.Count()); - var filteredPosts = result.ToList(); - Assert.Equal(2, filteredPosts[0].Id); + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, posts); + Assert.Equal(1, result.Count()); + var filteredPosts = result.ToList(); + Assert.Equal(2, filteredPosts[0].Id); + } } [Fact] public void BaseDefinedPropertyMappingSortingWorks_WithCustomName() { - var model = new SieveModel + var model = new SieveModel { Sorts = "-CreateDate" }; + + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + Assert.Equal(_posts.Count(), result.Count()); + + var posts = result + .Select(post => post.Id) + .ToList(); + + Assert.True + ( + posts.SequenceEqual + ( + _posts + .OrderByDescending(post => post.DateCreated) + .Select(post => post.Id) + ) + ); + } + } + + [Theory] + [InlineData("DeletedBy")] + [InlineData("-DeletedBy")] + public void CanSortWithInterfaceProperties(string sort) + { + var model = new SieveModel { Sorts = sort }; + + foreach (var sieveProcessor in GetProcessors()) { - Sorts = "-CreateDate" - }; - var result = _processor.Apply(model, _posts); - Assert.Equal(4, result.Count()); + var result = sieveProcessor.Apply(model, _posts); + var entry = result.FirstOrDefault(); + var resultCount = result.Count(); - var posts = result.ToList(); - Assert.Equal(3,posts[0].Id); - Assert.Equal(2,posts[1].Id); - Assert.Equal(1,posts[2].Id); - Assert.Equal(0,posts[3].Id); + Assert.NotNull(entry); + Assert.Equal(_posts.Count(), resultCount); + } + } + + [Theory] + [InlineData("UpdatedBy==Me", 1, 1, new [] {1})] + [InlineData("UpdatedBy==Me|You", 2, 2, null)] + [InlineData("UpdatedBy==You|Me", 2, 2, null)] + [InlineData("UpdatedBy!=Him", 5, 3, null)] + [InlineData("UpdatedBy_=*You", 2, 2, null)] + public void CanFilterWithInterfaceProperties(string filters, int recordCount, int nullIgnoredRecordCount, int[] filteredIds) + { + var model = new SieveModel { Filters = filters, Sorts = "Id" }; + + foreach (var sieveProcessor in GetProcessors()) + { + var result = sieveProcessor.Apply(model, _posts); + var resultCount = result.Count(); + Assert.Equal + ( + (sieveProcessor as ApplicationSieveProcessor)?.ExposedOptions.IgnoreNullsOnNotEqual ?? true + ? nullIgnoredRecordCount + : recordCount, + resultCount + ); + + if (filteredIds != null) + { + Assert.True + ( + result + .Select(post => post.Id) + .SequenceEqual(filteredIds) + ); + } + } } } } diff --git a/SieveUnitTests/Services/ApplicationSieveProcessor.cs b/SieveUnitTests/Services/ApplicationSieveProcessor.cs index f0a8815..1cf96c6 100644 --- a/SieveUnitTests/Services/ApplicationSieveProcessor.cs +++ b/SieveUnitTests/Services/ApplicationSieveProcessor.cs @@ -16,62 +16,20 @@ public ApplicationSieveProcessor( { } - protected override SievePropertyMapper MapProperties(SievePropertyMapper mapper) + public SieveOptions ExposedOptions => new SieveOptions() { - mapper.Property(p => p.ThisHasNoAttributeButIsAccessible) - .CanSort() - .CanFilter() - .HasName("shortname"); - - mapper.Property(p => p.TopComment.Text) - .CanFilter(); - - mapper.Property(p => p.TopComment.Id) - .CanSort(); - - mapper.Property(p => p.OnlySortableViaFluentApi) - .CanSort(); - - mapper.Property(p => p.TopComment.Text) - .CanFilter() - .HasName("topc"); - - mapper.Property(p => p.FeaturedComment.Text) - .CanFilter() - .HasName("featc"); - - mapper - .Property(p => p.DateCreated) - .CanSort() - .HasName("CreateDate"); - - // interfaces - mapper.Property(p => p.ThisHasNoAttributeButIsAccessible) - .CanSort() - .CanFilter() - .HasName("shortname"); + IgnoreNullsOnNotEqual = Options.Value.IgnoreNullsOnNotEqual, + CaseSensitive = Options.Value.CaseSensitive, + DefaultPageSize = Options.Value.DefaultPageSize, + DisableNullableTypeExpressionForSorting = Options.Value.DisableNullableTypeExpressionForSorting, + MaxPageSize = Options.Value.MaxPageSize, + ThrowExceptions = Options.Value.ThrowExceptions, + }; - mapper.Property(p => p.TopComment.Text) - .CanFilter(); - - mapper.Property(p => p.TopComment.Id) - .CanSort(); - - mapper.Property(p => p.OnlySortableViaFluentApi) - .CanSort(); - - mapper.Property(p => p.TopComment.Text) - .CanFilter() - .HasName("topc"); - - mapper.Property(p => p.FeaturedComment.Text) - .CanFilter() - .HasName("featc"); - - mapper - .Property(p => p.DateCreated) - .CanSort() - .HasName("CreateDate"); + protected override SievePropertyMapper MapProperties(SievePropertyMapper mapper) + { + SieveConfigurationForPost.ConfigureStatic(mapper); + SieveConfigurationForIPost.ConfigureStatic(mapper); return mapper; } diff --git a/SieveUnitTests/Services/SieveCustomFilterMethods.cs b/SieveUnitTests/Services/SieveCustomFilterMethods.cs index 0f534e3..d156a26 100644 --- a/SieveUnitTests/Services/SieveCustomFilterMethods.cs +++ b/SieveUnitTests/Services/SieveCustomFilterMethods.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Linq.Expressions; using Sieve.Services; using SieveUnitTests.Abstractions.Entity; using SieveUnitTests.Entities; @@ -8,9 +9,14 @@ namespace SieveUnitTests.Services { public class SieveCustomFilterMethods : ISieveCustomFilterMethods { + internal static readonly Expression> IsNewFilterForPost = post => post.LikeCount < 100; + internal static readonly Expression> IsNewFilterForIPost = post => post.LikeCount < 100; + internal static readonly Expression> IsNewFilterForComment = comment => comment.DateCreated > DateTimeOffset.UtcNow.AddDays(-2); + internal static readonly Expression> IsNewFilterForIComment = comment => comment.DateCreated > DateTimeOffset.UtcNow.AddDays(-2); + public IQueryable IsNew(IQueryable source, string op, string[] values) { - var result = source.Where(p => p.LikeCount < 100); + var result = source.Where(IsNewFilterForPost); return result; } @@ -24,7 +30,7 @@ public IQueryable HasInTitle(IQueryable source, string op, string[] public IQueryable IsNew(IQueryable source, string op, string[] values) { - var result = source.Where(c => c.DateCreated > DateTimeOffset.UtcNow.AddDays(-2)); + var result = source.Where(IsNewFilterForComment); return result; } @@ -42,7 +48,7 @@ public IQueryable Latest(IQueryable source, string op, string[] values) public IQueryable IsNew(IQueryable source, string op, string[] values) { - var result = source.Where(p => p.LikeCount < 100); + var result = source.Where(IsNewFilterForIPost); return result; } @@ -56,7 +62,7 @@ public IQueryable HasInTitle(IQueryable source, string op, string[ public IQueryable IsNew(IQueryable source, string op, string[] values) { - var result = source.Where(c => c.DateCreated > DateTimeOffset.UtcNow.AddDays(-2)); + var result = source.Where(IsNewFilterForIComment); return result; } diff --git a/SieveUnitTests/SieveUnitTests.csproj b/SieveUnitTests/SieveUnitTests.csproj index 1c26e54..a8abb1c 100644 --- a/SieveUnitTests/SieveUnitTests.csproj +++ b/SieveUnitTests/SieveUnitTests.csproj @@ -9,6 +9,7 @@ + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/SieveUnitTests/TestBase.cs b/SieveUnitTests/TestBase.cs new file mode 100644 index 0000000..24f319c --- /dev/null +++ b/SieveUnitTests/TestBase.cs @@ -0,0 +1,48 @@ +using System.Collections.Generic; +using Sieve.Services; +using SieveUnitTests.Services; +using Xunit.Abstractions; + +namespace SieveUnitTests +{ + public abstract class TestBase + { + protected TestBase(ITestOutputHelper testOutputHelper) + { + TestOutputHelper = testOutputHelper; + } + + protected ITestOutputHelper TestOutputHelper { get; } + + /// + /// Processors with the same mappings but configured via a different method. + /// + /// + public static IEnumerable GetProcessors() + { + // normal processor + yield return new ApplicationSieveProcessor( + new SieveOptionsAccessor(), + new SieveCustomSortMethods(), + new SieveCustomFilterMethods()); + + // nullable processor + yield return new ApplicationSieveProcessor( + new SieveOptionsAccessor() { Value = { IgnoreNullsOnNotEqual = false } }, + new SieveCustomSortMethods(), + new SieveCustomFilterMethods()); + + // modular processor + yield return new ModularConfigurationSieveProcessor( + new SieveOptionsAccessor(), + new SieveCustomSortMethods(), + new SieveCustomFilterMethods()); + + // modular processor with scan + yield return new ModularConfigurationWithScanSieveProcessor( + new SieveOptionsAccessor(), + new SieveCustomSortMethods(), + new SieveCustomFilterMethods()); + } + } +} diff --git a/build/Configuration.cs b/build/Configuration.cs index 9c08b1a..f66c1ad 100644 --- a/build/Configuration.cs +++ b/build/Configuration.cs @@ -1,6 +1,4 @@ -using System; -using System.ComponentModel; -using System.Linq; +using System.ComponentModel; using Nuke.Common.Tooling; [TypeConverter(typeof(TypeConverter))] From 73ce4e97cfdc9401c64b19709181301200b174df Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 01:29:45 +0300 Subject: [PATCH 02/23] target change --- build/_build.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/_build.csproj b/build/_build.csproj index c432dd2..b2612d1 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -2,7 +2,7 @@ Exe - net5.0 + net6.0 CS0649;CS0169 .. From 278cb7457adbdd83083f4136a4bda95e1f641479 Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 01:58:56 +0300 Subject: [PATCH 03/23] package updates --- Sieve.Sample/Sieve.Sample.csproj | 8 ++++---- Sieve/Sieve.csproj | 6 +++--- SieveUnitTests/SieveUnitTests.csproj | 12 ++++++------ build/Build.cs | 2 +- build/_build.csproj | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Sieve.Sample/Sieve.Sample.csproj b/Sieve.Sample/Sieve.Sample.csproj index 8aca6b9..a8c1f83 100644 --- a/Sieve.Sample/Sieve.Sample.csproj +++ b/Sieve.Sample/Sieve.Sample.csproj @@ -1,16 +1,16 @@  - netcoreapp3.1 + net6.0 - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/Sieve/Sieve.csproj b/Sieve/Sieve.csproj index 78b51b0..b7d73a5 100644 --- a/Sieve/Sieve.csproj +++ b/Sieve/Sieve.csproj @@ -22,9 +22,9 @@ - - - + + + diff --git a/SieveUnitTests/SieveUnitTests.csproj b/SieveUnitTests/SieveUnitTests.csproj index a8abb1c..017a5a2 100644 --- a/SieveUnitTests/SieveUnitTests.csproj +++ b/SieveUnitTests/SieveUnitTests.csproj @@ -1,20 +1,20 @@ - netcoreapp3.1 + net6.0 false - - - + + + - + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/build/Build.cs b/build/Build.cs index 3146ffc..ecb53af 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using GlobExpressions; using Nuke.Common; using Nuke.Common.CI; diff --git a/build/_build.csproj b/build/_build.csproj index b2612d1..e941599 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -10,7 +10,7 @@ - + From 515297502c661bb67b929ccafd18ce697d5f4092 Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 02:06:26 +0300 Subject: [PATCH 04/23] cleanups --- build/Build.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/build/Build.cs b/build/Build.cs index ecb53af..4fbd27e 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -13,7 +13,6 @@ using static Nuke.Common.IO.FileSystemTasks; using static Nuke.Common.Tools.DotNet.DotNetTasks; -[CheckBuildProjectConfigurations] [ShutdownDotNetAfterServerBuild] [GitHubActions("ci", GitHubActionsImage.UbuntuLatest, OnPullRequestBranches = new[] {"master", "releases/*"}, @@ -34,7 +33,7 @@ class Build : NukeBuild [GitRepository] readonly GitRepository GitRepository; - [GitVersion(Framework = "netcoreapp3.1")] readonly GitVersion GitVersion; + [GitVersion] readonly GitVersion GitVersion; [Solution] readonly Solution Solution; @@ -102,8 +101,14 @@ class Build : NukeBuild .Requires(() => Configuration.Equals(Configuration.Release)) .Executes(() => { - Glob.Files(OutputDirectory, "*.nupkg") - .NotEmpty() + var files = Glob + .Files(OutputDirectory, "*.nupkg") + .NotNull() + .ToList(); + + Assert.NotEmpty(files); + + files .ForEach(x => { DotNetNuGetPush(s => s From 9aff96cc8765deca1f824b2c13474aa37b98d510 Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 02:35:18 +0300 Subject: [PATCH 05/23] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7511e1d..adbf54d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +test + # Sieve ⚗️ Sieve is a simple, clean, and extensible framework for .NET Core that **adds sorting, filtering, and pagination functionality out of the box**. Most common use case would be for serving ASP.NET Core GET queries. From 9ecb9538e33a99daa7b82303ecb65c2ee6503dd6 Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 02:38:51 +0300 Subject: [PATCH 06/23] nuke test --- .github/workflows/ci.yml | 2 +- .github/workflows/ci_publish.yml | 2 +- .nuke/build.schema.json | 10 +++++++++- build/_build.csproj | 5 ++--- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c7c592..4729864 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,6 +27,6 @@ jobs: name: ubuntu-latest runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: Run './build.cmd Ci' run: ./build.cmd Ci diff --git a/.github/workflows/ci_publish.yml b/.github/workflows/ci_publish.yml index 1ff5730..b2fa7a1 100644 --- a/.github/workflows/ci_publish.yml +++ b/.github/workflows/ci_publish.yml @@ -28,7 +28,7 @@ jobs: name: ubuntu-latest runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: Run './build.cmd CiPublish' run: ./build.cmd CiPublish env: diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json index 6c8135f..8e950d4 100644 --- a/.nuke/build.schema.json +++ b/.nuke/build.schema.json @@ -29,14 +29,18 @@ "AppVeyor", "AzurePipelines", "Bamboo", + "Bitbucket", "Bitrise", "GitHubActions", "GitLab", "Jenkins", + "Rider", "SpaceAutomation", "TeamCity", "Terminal", - "TravisCI" + "TravisCI", + "VisualStudio", + "VSCode" ] }, "NoLogo": { @@ -46,6 +50,10 @@ "NUGET_API_KEY": { "type": "string" }, + "Partition": { + "type": "string", + "description": "Partition to use on CI" + }, "Plan": { "type": "boolean", "description": "Shows the execution plan (HTML)" diff --git a/build/_build.csproj b/build/_build.csproj index c432dd2..eaabf3a 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -2,7 +2,7 @@ Exe - net5.0 + net6.0 CS0649;CS0169 .. @@ -10,8 +10,7 @@ - - + From b94c98662e8c053e1f40c4c39be136bc94676e72 Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 02:46:36 +0300 Subject: [PATCH 07/23] gitversion.commandline added --- build/_build.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/_build.csproj b/build/_build.csproj index eaabf3a..fcd60f5 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -10,6 +10,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + From f20abb97f2b724b9d92aef1a7c5056da2cf2156c Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 02:49:04 +0300 Subject: [PATCH 08/23] target framework change --- build/_build.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/_build.csproj b/build/_build.csproj index fcd60f5..5255a3c 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net5.0 CS0649;CS0169 .. From 491ffe02878c0730c2205c346e65ca236fda8533 Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 03:04:00 +0300 Subject: [PATCH 09/23] spec change --- build/Build.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build/Build.cs b/build/Build.cs index 4fbd27e..9dc10a9 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -14,11 +14,13 @@ using static Nuke.Common.Tools.DotNet.DotNetTasks; [ShutdownDotNetAfterServerBuild] -[GitHubActions("ci", GitHubActionsImage.UbuntuLatest, +[GitHubActions("ci", GitHubActionsImage.Ubuntu2004, OnPullRequestBranches = new[] {"master", "releases/*"}, AutoGenerate = true, InvokedTargets = new[] {nameof(Ci)}, - CacheKeyFiles = new string[0])] + CacheKeyFiles = new string[0], + ) +] [GitHubActions("ci_publish", GitHubActionsImage.UbuntuLatest, OnPushBranches = new[] { "releases/*" }, OnPushTags = new[] { "v*" }, From 61b58e5210a7fe9a25ef0dd249f25da39fa2aa0a Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 03:05:40 +0300 Subject: [PATCH 10/23] fix --- build/Build.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Build.cs b/build/Build.cs index 9dc10a9..beee3fd 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -18,7 +18,7 @@ OnPullRequestBranches = new[] {"master", "releases/*"}, AutoGenerate = true, InvokedTargets = new[] {nameof(Ci)}, - CacheKeyFiles = new string[0], + CacheKeyFiles = new string[0] ) ] [GitHubActions("ci_publish", GitHubActionsImage.UbuntuLatest, From 61287bb58b218ccc097145fc9b52ff5aa4ee025b Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 03:07:57 +0300 Subject: [PATCH 11/23] yoruldum --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4729864..f70d4ab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,8 +24,8 @@ on: jobs: ubuntu-latest: - name: ubuntu-latest - runs-on: ubuntu-latest + name: ubuntu-20.04 + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 - name: Run './build.cmd Ci' From f615980408084de7c45e59cad05e75be1326c140 Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 03:15:46 +0300 Subject: [PATCH 12/23] pof --- build/_build.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/_build.csproj b/build/_build.csproj index 5255a3c..fcd60f5 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -2,7 +2,7 @@ Exe - net5.0 + net6.0 CS0649;CS0169 .. From f4a0432977c10227a923f1c60bf98f65e565a1ce Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 03:17:45 +0300 Subject: [PATCH 13/23] asdlkhasdlkjh --- build/Build.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Build.cs b/build/Build.cs index beee3fd..dc80ed3 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -35,7 +35,7 @@ class Build : NukeBuild [GitRepository] readonly GitRepository GitRepository; - [GitVersion] readonly GitVersion GitVersion; + [GitVersion(Framework = "netcoreapp3.1")] readonly GitVersion GitVersion; [Solution] readonly Solution Solution; From 01ba3914ae1da404b6072b83f93b1c68a1eb8ddc Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 03:19:31 +0300 Subject: [PATCH 14/23] asdasklhlskdjhg --- build/_build.csproj | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/build/_build.csproj b/build/_build.csproj index fcd60f5..e941599 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -10,11 +10,8 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + From a6dbcedf94627e0187859e25abdeccb393506c61 Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 03:57:01 +0300 Subject: [PATCH 15/23] acaba? --- .github/workflows/ci.yml | 6 ++++-- build/Build.cs | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f70d4ab..503b225 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,10 +23,12 @@ on: - 'releases/*' jobs: - ubuntu-latest: - name: ubuntu-20.04 + ubuntu-20_04: + name: ubuntu-20_04 runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Run './build.cmd Ci' run: ./build.cmd Ci diff --git a/build/Build.cs b/build/Build.cs index dc80ed3..6310937 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -18,7 +18,8 @@ OnPullRequestBranches = new[] {"master", "releases/*"}, AutoGenerate = true, InvokedTargets = new[] {nameof(Ci)}, - CacheKeyFiles = new string[0] + CacheKeyFiles = new string[0], + FetchDepth = 0 ) ] [GitHubActions("ci_publish", GitHubActionsImage.UbuntuLatest, From c5a977e5c9ab788ce027a9114da4753982f93265 Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 04:00:22 +0300 Subject: [PATCH 16/23] last test --- .github/workflows/ci.yml | 6 +++--- build/Build.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 503b225..8a5a4b5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,9 +23,9 @@ on: - 'releases/*' jobs: - ubuntu-20_04: - name: ubuntu-20_04 - runs-on: ubuntu-20.04 + ubuntu-latest: + name: ubuntu-latest + runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: diff --git a/build/Build.cs b/build/Build.cs index 6310937..7f4c5fd 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -14,7 +14,7 @@ using static Nuke.Common.Tools.DotNet.DotNetTasks; [ShutdownDotNetAfterServerBuild] -[GitHubActions("ci", GitHubActionsImage.Ubuntu2004, +[GitHubActions("ci", GitHubActionsImage.UbuntuLatest, OnPullRequestBranches = new[] {"master", "releases/*"}, AutoGenerate = true, InvokedTargets = new[] {nameof(Ci)}, From ad7178ef96f3ac49903d6b395b0b1fdd4a4207eb Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 04:16:20 +0300 Subject: [PATCH 17/23] =?UTF-8?q?asdlkal=C5=9Fdja?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/Build.cs | 10 +++++----- build/_build.csproj | 7 +++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/build/Build.cs b/build/Build.cs index 7f4c5fd..ca3f8a6 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -15,14 +15,14 @@ [ShutdownDotNetAfterServerBuild] [GitHubActions("ci", GitHubActionsImage.UbuntuLatest, + FetchDepth = 0, OnPullRequestBranches = new[] {"master", "releases/*"}, AutoGenerate = true, InvokedTargets = new[] {nameof(Ci)}, - CacheKeyFiles = new string[0], - FetchDepth = 0 - ) -] + CacheKeyFiles = new string[0] + )] [GitHubActions("ci_publish", GitHubActionsImage.UbuntuLatest, + FetchDepth = 0, OnPushBranches = new[] { "releases/*" }, OnPushTags = new[] { "v*" }, AutoGenerate = true, @@ -36,7 +36,7 @@ class Build : NukeBuild [GitRepository] readonly GitRepository GitRepository; - [GitVersion(Framework = "netcoreapp3.1")] readonly GitVersion GitVersion; + [GitVersion] readonly GitVersion GitVersion; [Solution] readonly Solution Solution; diff --git a/build/_build.csproj b/build/_build.csproj index e941599..5255a3c 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net5.0 CS0649;CS0169 .. @@ -10,8 +10,11 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + - From 1d64e4caf9a6217bfcf96a797d629cca43cdc38f Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 04:17:47 +0300 Subject: [PATCH 18/23] asdads --- build/_build.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/_build.csproj b/build/_build.csproj index 5255a3c..fcd60f5 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -2,7 +2,7 @@ Exe - net5.0 + net6.0 CS0649;CS0169 .. From 721beb7fe1b422fe8470f44b200dbc05d2cac950 Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 04:30:13 +0300 Subject: [PATCH 19/23] final? --- build/Build.cs | 6 +++--- build/_build.csproj | 5 +---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/build/Build.cs b/build/Build.cs index ca3f8a6..2277cc6 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -14,14 +14,14 @@ using static Nuke.Common.Tools.DotNet.DotNetTasks; [ShutdownDotNetAfterServerBuild] -[GitHubActions("ci", GitHubActionsImage.UbuntuLatest, +[GitHubActions("ci", GitHubActionsImage.Ubuntu2004, FetchDepth = 0, OnPullRequestBranches = new[] {"master", "releases/*"}, AutoGenerate = true, InvokedTargets = new[] {nameof(Ci)}, CacheKeyFiles = new string[0] )] -[GitHubActions("ci_publish", GitHubActionsImage.UbuntuLatest, +[GitHubActions("ci_publish", GitHubActionsImage.Ubuntu2004, FetchDepth = 0, OnPushBranches = new[] { "releases/*" }, OnPushTags = new[] { "v*" }, @@ -36,7 +36,7 @@ class Build : NukeBuild [GitRepository] readonly GitRepository GitRepository; - [GitVersion] readonly GitVersion GitVersion; + [GitVersion(Framework = "netcoreapp3.1")] readonly GitVersion GitVersion; [Solution] readonly Solution Solution; diff --git a/build/_build.csproj b/build/_build.csproj index fcd60f5..e941599 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -10,11 +10,8 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + From affa6c80c2630929b8a33336dcbe7f85fe90772c Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 04:31:31 +0300 Subject: [PATCH 20/23] final!!! --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8a5a4b5..503b225 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,9 +23,9 @@ on: - 'releases/*' jobs: - ubuntu-latest: - name: ubuntu-latest - runs-on: ubuntu-latest + ubuntu-20_04: + name: ubuntu-20_04 + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 with: From 5a2ae9f5d9b98c8e81fc01bd931cf62d85a7a84d Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 04:35:57 +0300 Subject: [PATCH 21/23] hede --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index adbf54d..7511e1d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -test - # Sieve ⚗️ Sieve is a simple, clean, and extensible framework for .NET Core that **adds sorting, filtering, and pagination functionality out of the box**. Most common use case would be for serving ASP.NET Core GET queries. From 333cba43c6b98db9154c0486c8878ecd6c2016cc Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Thu, 23 Feb 2023 04:38:03 +0300 Subject: [PATCH 22/23] Update README.md (#1) nuke fix --- .github/workflows/ci.yml | 10 ++++++---- .github/workflows/ci_publish.yml | 2 +- .nuke/build.schema.json | 10 +++++++++- build/Build.cs | 11 +++++++---- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c7c592..503b225 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,10 +23,12 @@ on: - 'releases/*' jobs: - ubuntu-latest: - name: ubuntu-latest - runs-on: ubuntu-latest + ubuntu-20_04: + name: ubuntu-20_04 + runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Run './build.cmd Ci' run: ./build.cmd Ci diff --git a/.github/workflows/ci_publish.yml b/.github/workflows/ci_publish.yml index 1ff5730..b2fa7a1 100644 --- a/.github/workflows/ci_publish.yml +++ b/.github/workflows/ci_publish.yml @@ -28,7 +28,7 @@ jobs: name: ubuntu-latest runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: Run './build.cmd CiPublish' run: ./build.cmd CiPublish env: diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json index 6c8135f..8e950d4 100644 --- a/.nuke/build.schema.json +++ b/.nuke/build.schema.json @@ -29,14 +29,18 @@ "AppVeyor", "AzurePipelines", "Bamboo", + "Bitbucket", "Bitrise", "GitHubActions", "GitLab", "Jenkins", + "Rider", "SpaceAutomation", "TeamCity", "Terminal", - "TravisCI" + "TravisCI", + "VisualStudio", + "VSCode" ] }, "NoLogo": { @@ -46,6 +50,10 @@ "NUGET_API_KEY": { "type": "string" }, + "Partition": { + "type": "string", + "description": "Partition to use on CI" + }, "Plan": { "type": "boolean", "description": "Shows the execution plan (HTML)" diff --git a/build/Build.cs b/build/Build.cs index 4fbd27e..2277cc6 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -14,12 +14,15 @@ using static Nuke.Common.Tools.DotNet.DotNetTasks; [ShutdownDotNetAfterServerBuild] -[GitHubActions("ci", GitHubActionsImage.UbuntuLatest, +[GitHubActions("ci", GitHubActionsImage.Ubuntu2004, + FetchDepth = 0, OnPullRequestBranches = new[] {"master", "releases/*"}, AutoGenerate = true, InvokedTargets = new[] {nameof(Ci)}, - CacheKeyFiles = new string[0])] -[GitHubActions("ci_publish", GitHubActionsImage.UbuntuLatest, + CacheKeyFiles = new string[0] + )] +[GitHubActions("ci_publish", GitHubActionsImage.Ubuntu2004, + FetchDepth = 0, OnPushBranches = new[] { "releases/*" }, OnPushTags = new[] { "v*" }, AutoGenerate = true, @@ -33,7 +36,7 @@ class Build : NukeBuild [GitRepository] readonly GitRepository GitRepository; - [GitVersion] readonly GitVersion GitVersion; + [GitVersion(Framework = "netcoreapp3.1")] readonly GitVersion GitVersion; [Solution] readonly Solution Solution; From 5627a3a5ed0797886ad4dcab3ceb8cab5e53c93b Mon Sep 17 00:00:00 2001 From: Hasan Manzak Date: Mon, 27 Feb 2023 17:15:31 +0300 Subject: [PATCH 23/23] publish config change --- .github/workflows/ci_publish.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci_publish.yml b/.github/workflows/ci_publish.yml index b2fa7a1..191711a 100644 --- a/.github/workflows/ci_publish.yml +++ b/.github/workflows/ci_publish.yml @@ -24,11 +24,13 @@ on: - 'v*' jobs: - ubuntu-latest: - name: ubuntu-latest - runs-on: ubuntu-latest + ubuntu-20_04: + name: ubuntu-20_04 + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Run './build.cmd CiPublish' run: ./build.cmd CiPublish env: