From 75da85d22ed6206ae86821071758cf9c8ac92dc2 Mon Sep 17 00:00:00 2001 From: mehmetuken Date: Fri, 28 Jan 2022 09:08:04 +0300 Subject: [PATCH] Adding StringFilter NotContains, NotStartsWith and NotEndsWith options. --- src/AutoFilterer/Types/StringFilter.cs | 26 +++++++++- .../Types/StringFilterTests.cs | 49 +++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/AutoFilterer/Types/StringFilter.cs b/src/AutoFilterer/Types/StringFilter.cs index c0dfd66..bf580bd 100644 --- a/src/AutoFilterer/Types/StringFilter.cs +++ b/src/AutoFilterer/Types/StringFilter.cs @@ -28,19 +28,34 @@ public class StringFilter : IFilterableType public virtual new string Equals { get; set; } /// - /// Provides parameter to String.Conains method query. + /// Provides parameter to String.Contains method query. /// public virtual string Contains { get; set; } + + /// + /// Provides parameter to !String.Contains method query. + /// + public virtual string NotContains { get; set; } /// /// Provides parameter to String.StartsWith method query. /// public virtual string StartsWith { get; set; } + + /// + /// Provides parameter to !String.StartsWith method query. + /// + public virtual string NotStartsWith { get; set; } /// /// Provides parameter to String.EndsWith method query. /// public virtual string EndsWith { get; set; } + + /// + /// Provides parameter to !String.EndsWith method query. + /// + public virtual string NotEndsWith { get; set; } /// /// @@ -68,11 +83,20 @@ public virtual Expression BuildExpression(Expression expressionBody, PropertyInf if (Contains != null) expression = expression.Combine(new StringFilterOptionsAttribute(StringFilterOption.Contains) { Comparison = Compare }.BuildExpression(expressionBody, targetProperty, filterProperty, Contains), CombineWith); + if (NotContains != null) + expression = expression.Combine(Expression.Not(new StringFilterOptionsAttribute(StringFilterOption.Contains) { Comparison = Compare }.BuildExpression(expressionBody, targetProperty, filterProperty, NotContains)), CombineWith); + if (StartsWith != null) expression = expression.Combine(new StringFilterOptionsAttribute(StringFilterOption.StartsWith) { Comparison = Compare }.BuildExpression(expressionBody, targetProperty, filterProperty, StartsWith), CombineWith); + if (NotStartsWith != null) + expression = expression.Combine(Expression.Not(new StringFilterOptionsAttribute(StringFilterOption.StartsWith) { Comparison = Compare }.BuildExpression(expressionBody, targetProperty, filterProperty, NotStartsWith)), CombineWith); + if (EndsWith != null) expression = expression.Combine(new StringFilterOptionsAttribute(StringFilterOption.EndsWith) { Comparison = Compare }.BuildExpression(expressionBody, targetProperty, filterProperty, EndsWith), CombineWith); + + if (NotEndsWith != null) + expression = expression.Combine(Expression.Not(new StringFilterOptionsAttribute(StringFilterOption.EndsWith) { Comparison = Compare }.BuildExpression(expressionBody, targetProperty, filterProperty, NotEndsWith)), CombineWith); return expression; } diff --git a/tests/AutoFilterer.Tests/Types/StringFilterTests.cs b/tests/AutoFilterer.Tests/Types/StringFilterTests.cs index 82c6bb9..4344f22 100644 --- a/tests/AutoFilterer.Tests/Types/StringFilterTests.cs +++ b/tests/AutoFilterer.Tests/Types/StringFilterTests.cs @@ -60,4 +60,53 @@ public void BuildExpression_TitleWithContainsCaseInsensitive_ShouldMatchCount(Li foreach (var item in actualResult) Assert.Contains(item, result); } + + [Theory, AutoMoqData(count: 64)] + public void BuildExpression_TitleWithNotContains_ShouldMatchCount(List data) + { + // Arrange + var filter = new BookFilter_StringFilter_Title + { + Title = new StringFilter + { + NotContains = "ab" + } + }; + + // Act + var query = data.AsQueryable().ApplyFilter(filter); + var result = query.ToList(); + + // Assert + var actualResult = data.AsQueryable().Where(x => !x.Title.Contains(filter.Title.NotContains)).ToList(); + + Assert.Equal(actualResult.Count, result.Count); + foreach (var item in actualResult) + Assert.Contains(item, result); + } + + [Theory, AutoMoqData(count: 64)] + public void BuildExpression_TitleWithNotContainsCaseInsensitive_ShouldMatchCount(List data) + { + // Arrange + var filter = new BookFilter_StringFilter_Title + { + Title = new StringFilter + { + NotContains = "Ab", + Compare = StringComparison.InvariantCultureIgnoreCase + } + }; + + // Act + var query = data.AsQueryable().ApplyFilter(filter); + var result = query.ToList(); + + // Assert + var actualResult = data.AsQueryable().Where(x => !x.Title.Contains(filter.Title.NotContains, StringComparison.InvariantCultureIgnoreCase)).ToList(); + + Assert.Equal(actualResult.Count, result.Count); + foreach (var item in actualResult) + Assert.Contains(item, result); + } }