< Summary - Code Coverage

Information
Class: Plainquire.Filter.ValueFilterExpressions.DefaultFilterExpression
Assembly: Plainquire.Filter
File(s): /home/runner/work/plainquire/plainquire/Plainquire.Filter/Plainquire.Filter/ValueFilterExpressions/DefaultFilterExpression.cs
Tag: 64_13932151703
Line coverage
79%
Covered lines: 76
Uncovered lines: 20
Coverable lines: 96
Total lines: 312
Line coverage: 79.1%
Branch coverage
56%
Covered branches: 17
Total branches: 30
Branch coverage: 56.6%
Method coverage
84%
Covered methods: 16
Total methods: 19
Method coverage: 84.2%

Metrics

File(s)

/home/runner/work/plainquire/plainquire/Plainquire.Filter/Plainquire.Filter/ValueFilterExpressions/DefaultFilterExpression.cs

#LineLine coverage
 1using Plainquire.Filter.Abstractions;
 2using System;
 3using System.Collections.Generic;
 4using System.Diagnostics.CodeAnalysis;
 5using System.Linq;
 6using System.Linq.Expressions;
 7
 8namespace Plainquire.Filter.ValueFilterExpressions;
 9
 10/// <inheritdoc />
 11[SuppressMessage("ReSharper", "MemberCanBePrivate.Global", Justification = "Provided as library, can be used from outsid
 12[SuppressMessage("ReSharper", "MemberCanBeProtected.Global", Justification = "Provided as library, can be used from outs
 13public class DefaultFilterExpression : IValueFilterExpression
 14{
 15    /// <summary>
 16    /// Gets the supported filter operators.
 17    /// </summary>
 18    public virtual ICollection<FilterOperator> SupportedFilterOperators
 19        =>
 020        [
 021            FilterOperator.Default,
 022            FilterOperator.EqualCaseSensitive,
 023            FilterOperator.EqualCaseInsensitive,
 024            FilterOperator.NotEqual,
 025            FilterOperator.LessThanOrEqual,
 026            FilterOperator.LessThan,
 027            FilterOperator.GreaterThanOrEqual,
 028            FilterOperator.GreaterThan,
 029            FilterOperator.IsNull,
 030            FilterOperator.NotNull
 031        ];
 32
 33    /// <inheritdoc />
 34    public bool CanCreateExpressionFor<TType>()
 7249235        => CanCreateExpressionFor(typeof(TType));
 36
 37    /// <inheritdoc />
 38    public virtual bool CanCreateExpressionFor(Type type)
 039        => true;
 40
 41    /// <inheritdoc />
 42    public Expression? CreateExpression<TEntity, TProperty>(Expression<Func<TEntity, TProperty>> propertySelector, IEnum
 43    {
 1819444        var filterCollection = filters?.ToList();
 1819445        if (filterCollection == null || filterCollection.Count == 0)
 1046            return null;
 47
 1818448        var propertyType = typeof(TProperty);
 1818449        var propertyCanBeNull = !propertyType.IsValueType || Nullable.GetUnderlyingType(propertyType) != null;
 50
 1818451        var filterExpressions = filterCollection
 1818452            .Select(filter =>
 1818453            {
 1818454                if (!SupportedFilterOperators.Contains(filter.Operator))
 1818455                    throw CreateFilterExpressionCreationException($"Filter operator '{filter.Operator}' not allowed for 
 1818456
 1818457                if (filter.IsEmpty)
 1818458                    return null;
 1818459
 1818460                switch (filter.Operator)
 1818461                {
 1818462                    case FilterOperator.IsNull:
 1818463                        if (!propertyCanBeNull)
 1818464                            throw CreateFilterExpressionCreationException($"Filter operator '{filter.Operator}' not allo
 1818465                        return Expression.Equal(propertySelector.Body, Expression.Constant(null));
 1818466                    case FilterOperator.NotNull:
 1818467                        if (!propertyCanBeNull)
 1818468                            throw CreateFilterExpressionCreationException($"Filter operator '{filter.Operator}' not allo
 1818469                        return Expression.NotEqual(propertySelector.Body, Expression.Constant(null));
 1818470                    default:
 1818471                        return CreateExpressionForValue(propertySelector, filter.Operator, filter.Value, configuration, 
 1818472                }
 1818473            })
 1818474            .WhereNotNull()
 1818475            .ToList();
 76
 1630477        if (filterExpressions.Count == 0)
 19578            return null;
 79
 1610980        var filterExpression = filterExpressions.Aggregate(Expression.OrElse);
 81
 1610982        return filterExpression;
 83    }
 84
 85    /// <summary>
 86    /// Creates the body of a filter expression.
 87    /// </summary>
 88    /// <typeparam name="TEntity">The type of the class that declares <typeparamref name="TProperty"/>.</typeparam>
 89    /// <typeparam name="TProperty">The type of the property.</typeparam>
 90    /// <param name="propertySelector">The property to create the expression for.</param>
 91    /// <param name="filterOperator">The filter operator to use.</param>
 92    /// <param name="value">The value to create the expression for.</param>
 93    /// <param name="configuration">The filter configuration to use.</param>
 94    /// <param name="interceptor">An interceptor to manipulate the generated filters.</param>
 95    protected internal virtual Expression? CreateExpressionForValue<TEntity, TProperty>(Expression<Func<TEntity, TProper
 96    {
 97        switch (filterOperator)
 98        {
 99            case FilterOperator.NotEqual:
 0100                return CreateNotEqualExpression(propertySelector, value);
 101            case FilterOperator.GreaterThan:
 0102                return CreateGreaterThanExpression(propertySelector, value);
 103            case FilterOperator.GreaterThanOrEqual:
 0104                return CreateGreaterThanOrEqualExpression(propertySelector, value);
 105            case FilterOperator.LessThan:
 0106                return CreateLessThanExpression(propertySelector, value);
 107            case FilterOperator.LessThanOrEqual:
 0108                return CreateLessThanOrEqualExpression(propertySelector, value);
 109            case FilterOperator.Default:
 110            case FilterOperator.EqualCaseInsensitive:
 111            case FilterOperator.EqualCaseSensitive:
 0112                return CreateEqualExpression(propertySelector, value);
 113            default:
 0114                throw CreateFilterExpressionCreationException($"Filter operator '{filterOperator}' not allowed for prope
 115        }
 116    }
 117
 118    /// <summary>
 119    /// Creates a binary 'equals' ('==') expression for the given property/value pair.
 120    /// </summary>
 121    /// <typeparam name="TEntity">The type of the class that declares <typeparamref name="TProperty"/>.</typeparam>
 122    /// <typeparam name="TProperty">The type of the property.</typeparam>
 123    /// <typeparam name="TValue">The type of the value.</typeparam>
 124    /// <param name="propertySelector">The property to use.</param>
 125    /// <param name="value">The value to use.</param>
 126    public static Expression CreateEqualExpression<TEntity, TProperty, TValue>(Expression<Func<TEntity, TProperty>> prop
 5276127        => CreateEqualExpression(propertySelector, typeof(TValue), value);
 128
 129    /// <summary>
 130    /// Creates a binary 'equals' ('==') expression for the given property/value pair.
 131    /// </summary>
 132    /// <typeparam name="TEntity">The type of the class that declares <typeparamref name="TProperty"/>.</typeparam>
 133    /// <typeparam name="TProperty">The type of the property.</typeparam>
 134    /// <param name="propertySelector">The property to use.</param>
 135    /// <param name="valueType">The type of the value.</param>
 136    /// <param name="value">The value to use.</param>
 137    protected static Expression CreateEqualExpression<TEntity, TProperty>(Expression<Func<TEntity, TProperty>> propertyS
 138    {
 5276139        var (propertyExpression, valueExpression) = CreateAndCastExpressionParts(propertySelector, valueType, value);
 5276140        return Expression.Equal(propertyExpression, valueExpression);
 141    }
 142
 143    /// <summary>
 144    /// Creates a binary 'not equals' ('!=') expression for the given property/value pair.
 145    /// </summary>
 146    /// <typeparam name="TEntity">The type of the class that declares <typeparamref name="TProperty"/>.</typeparam>
 147    /// <typeparam name="TProperty">The type of the property.</typeparam>
 148    /// <typeparam name="TValue">The type of the value.</typeparam>
 149    /// <param name="propertySelector">The property to use.</param>
 150    /// <param name="value">The value to use.</param>
 151    public static Expression CreateNotEqualExpression<TEntity, TProperty, TValue>(Expression<Func<TEntity, TProperty>> p
 1344152        => CreateNotEqualExpression(propertySelector, typeof(TValue), value);
 153
 154    /// <summary>
 155    /// Creates a binary 'not equals' ('!=') expression for the given property/value pair.
 156    /// </summary>
 157    /// <typeparam name="TEntity">The type of the class that declares <typeparamref name="TProperty"/>.</typeparam>
 158    /// <typeparam name="TProperty">The type of the property.</typeparam>
 159    /// <param name="propertySelector">The property to use.</param>
 160    /// <param name="valueType">The type of the value.</param>
 161    /// <param name="value">The value to use.</param>
 162    protected static Expression CreateNotEqualExpression<TEntity, TProperty>(Expression<Func<TEntity, TProperty>> proper
 163    {
 1344164        var (propertyExpression, valueExpression) = CreateAndCastExpressionParts(propertySelector, valueType, value);
 1344165        return Expression.NotEqual(propertyExpression, valueExpression);
 166    }
 167
 168    /// <summary>
 169    /// Creates a binary 'less than' ('&lt;') expression for the given property/value pair.
 170    /// </summary>
 171    /// <typeparam name="TEntity">The type of the class that declares <typeparamref name="TProperty"/>.</typeparam>
 172    /// <typeparam name="TProperty">The type of the property.</typeparam>
 173    /// <typeparam name="TValue">The type of the value.</typeparam>
 174    /// <param name="propertySelector">The property to use.</param>
 175    /// <param name="value">The value to use.</param>
 176    public static Expression CreateLessThanExpression<TEntity, TProperty, TValue>(Expression<Func<TEntity, TProperty>> p
 678177        => CreateLessThanExpression(propertySelector, typeof(TValue), value);
 178
 179    /// <summary>
 180    /// Creates a binary 'less than' ('&lt;') expression for the given property/value pair.
 181    /// </summary>
 182    /// <typeparam name="TEntity">The type of the class that declares <typeparamref name="TProperty"/>.</typeparam>
 183    /// <typeparam name="TProperty">The type of the property.</typeparam>
 184    /// <param name="propertySelector">The property to use.</param>
 185    /// <param name="valueType">The type of the value.</param>
 186    /// <param name="value">The value to use.</param>
 187    protected static Expression CreateLessThanExpression<TEntity, TProperty>(Expression<Func<TEntity, TProperty>> proper
 188    {
 942189        var (propertyExpression, valueExpression) = CreateAndCastExpressionParts(propertySelector, valueType, value);
 942190        return Expression.LessThan(propertyExpression, valueExpression);
 191    }
 192
 193    /// <summary>
 194    /// Creates a binary 'less than or equal' ('&lt;=') expression for the given property/value pair.
 195    /// </summary>
 196    /// <typeparam name="TEntity">The type of the class that declares <typeparamref name="TProperty"/>.</typeparam>
 197    /// <typeparam name="TProperty">The type of the property.</typeparam>
 198    /// <typeparam name="TValue">The type of the value.</typeparam>
 199    /// <param name="propertySelector">The property to use.</param>
 200    /// <param name="value">The value to use.</param>
 201    public static Expression CreateLessThanOrEqualExpression<TEntity, TProperty, TValue>(Expression<Func<TEntity, TPrope
 672202        => CreateLessThanOrEqualExpression(propertySelector, typeof(TValue), value);
 203
 204    /// <summary>
 205    /// Creates a binary 'less than or equal' ('&lt;=') expression for the given property/value pair.
 206    /// </summary>
 207    /// <typeparam name="TEntity">The type of the class that declares <typeparamref name="TProperty"/>.</typeparam>
 208    /// <typeparam name="TProperty">The type of the property.</typeparam>
 209    /// <param name="propertySelector">The property to use.</param>
 210    /// <param name="valueType">The type of the value.</param>
 211    /// <param name="value">The value to use.</param>
 212    protected static Expression CreateLessThanOrEqualExpression<TEntity, TProperty>(Expression<Func<TEntity, TProperty>>
 213    {
 936214        var (propertyExpression, valueExpression) = CreateAndCastExpressionParts(propertySelector, valueType, value);
 936215        return Expression.LessThanOrEqual(propertyExpression, valueExpression);
 216    }
 217
 218    /// <summary>
 219    /// Creates a binary 'greater than' ('&gt;') expression for the given property/value pair.
 220    /// </summary>
 221    /// <typeparam name="TEntity">The type of the class that declares <typeparamref name="TProperty"/>.</typeparam>
 222    /// <typeparam name="TProperty">The type of the property.</typeparam>
 223    /// <typeparam name="TValue">The type of the value.</typeparam>
 224    /// <param name="propertySelector">The property to use.</param>
 225    /// <param name="value">The value to use.</param>
 226    public static Expression CreateGreaterThanExpression<TEntity, TProperty, TValue>(Expression<Func<TEntity, TProperty>
 672227        => CreateGreaterThanExpression(propertySelector, typeof(TValue), value);
 228
 229    /// <summary>
 230    /// Creates a binary 'greater than' ('&gt;') expression for the given property/value pair.
 231    /// </summary>
 232    /// <typeparam name="TEntity">The type of the class that declares <typeparamref name="TProperty"/>.</typeparam>
 233    /// <typeparam name="TProperty">The type of the property.</typeparam>
 234    /// <param name="propertySelector">The property to use.</param>
 235    /// <param name="valueType">The type of the value.</param>
 236    /// <param name="value">The value to use.</param>
 237    protected static Expression CreateGreaterThanExpression<TEntity, TProperty>(Expression<Func<TEntity, TProperty>> pro
 238    {
 936239        var (propertyExpression, valueExpression) = CreateAndCastExpressionParts(propertySelector, valueType, value);
 936240        return Expression.GreaterThan(propertyExpression, valueExpression);
 241    }
 242
 243    /// <summary>
 244    /// Creates a binary 'greater than or equal' ('&gt;=') expression for the given property/value pair.
 245    /// </summary>
 246    /// <typeparam name="TEntity">The type of the class that declares <typeparamref name="TProperty"/>.</typeparam>
 247    /// <typeparam name="TProperty">The type of the property.</typeparam>
 248    /// <typeparam name="TValue">The type of the value.</typeparam>
 249    /// <param name="propertySelector">The property to use.</param>
 250    /// <param name="value">The value to use.</param>
 251    public static Expression CreateGreaterThanOrEqualExpression<TEntity, TProperty, TValue>(Expression<Func<TEntity, TPr
 678252        => CreateGreaterThanOrEqualExpression(propertySelector, typeof(TValue), value);
 253
 254    /// <summary>
 255    /// Creates a binary 'greater than or equal' ('&gt;=') expression for the given property/value pair.
 256    /// </summary>
 257    /// <typeparam name="TEntity">The type of the class that declares <typeparamref name="TProperty"/>.</typeparam>
 258    /// <typeparam name="TProperty">The type of the property.</typeparam>
 259    /// <param name="propertySelector">The property to use.</param>
 260    /// <param name="valueType">The type of the value.</param>
 261    /// <param name="value">The value to use.</param>
 262    protected static Expression CreateGreaterThanOrEqualExpression<TEntity, TProperty>(Expression<Func<TEntity, TPropert
 263    {
 942264        var (propertyExpression, valueExpression) = CreateAndCastExpressionParts(propertySelector, valueType, value);
 942265        return Expression.GreaterThanOrEqual(propertyExpression, valueExpression);
 266    }
 267
 268    private static (Expression propertyExpression, Expression valueExpression) CreateAndCastExpressionParts<TEntity, TPr
 269    {
 10376270        var underlingValueType = valueType.GetUnderlyingType();
 10376271        var partsHaveSameUnderlyingTypes = typeof(TProperty).GetUnderlyingType() == underlingValueType;
 10376272        var propertyIsNullable = Nullable.GetUnderlyingType(typeof(TProperty)) != null;
 273
 10376274        var destinationType = propertyIsNullable && underlingValueType.IsValueType
 10376275            ? typeof(Nullable<>).MakeGenericType(underlingValueType)
 10376276            : valueType;
 277
 10376278        var valueExpression = partsHaveSameUnderlyingTypes
 10376279            ? Expression.Constant(value, typeof(TProperty))
 10376280            : Expression.Constant(value, destinationType);
 281
 10376282        var propertyExpression = partsHaveSameUnderlyingTypes
 10376283            ? propertySelector.Body
 10376284            : propertySelector.Body.Cast(typeof(TProperty), destinationType);
 285
 10376286        return (propertyExpression, valueExpression);
 287    }
 288
 289    /// <summary>
 290    /// Creates a filter expression creation exception.
 291    /// </summary>
 292    /// <typeparam name="TEntity">The type of the class that declares <typeparamref name="TProperty"/>.</typeparam>
 293    /// <typeparam name="TProperty">The type of the property.</typeparam>
 294    /// <typeparam name="TValue">The type of the value.</typeparam>
 295    /// <param name="message">The exception message.</param>
 296    /// <param name="property">The property the filter is created for.</param>
 297    /// <param name="filterOperator">The filter operator.</param>
 298    /// <param name="value">The value to filter.</param>
 299    protected FilterExpressionException CreateFilterExpressionCreationException<TEntity, TProperty, TValue>(string messa
 300    {
 1880301        return new FilterExpressionException(message)
 1880302        {
 1880303            FilteredEntity = typeof(TEntity),
 1880304            FilteredProperty = ((MemberExpression)property.Body).Member.Name,
 1880305            FilteredPropertyType = typeof(TProperty),
 1880306            FilterOperator = filterOperator,
 1880307            Value = value,
 1880308            ValueType = typeof(TValue),
 1880309            SupportedFilterOperators = SupportedFilterOperators
 1880310        };
 311    }
 312}

Methods/Properties

SupportedFilterOperators()
CanCreateExpressionFor()
CanCreateExpressionFor(System.Type)
CreateExpression(System.Linq.Expressions.Expression`1<System.Func`2<TEntity,TProperty>>,System.Collections.Generic.IEnumerable`1<Plainquire.Filter.ValueFilter>,Plainquire.Filter.Abstractions.FilterConfiguration,Plainquire.Filter.IFilterInterceptor)
CreateExpressionForValue(System.Linq.Expressions.Expression`1<System.Func`2<TEntity,TProperty>>,Plainquire.Filter.Abstractions.FilterOperator,System.String,Plainquire.Filter.Abstractions.FilterConfiguration,Plainquire.Filter.IFilterInterceptor)
CreateEqualExpression(System.Linq.Expressions.Expression`1<System.Func`2<TEntity,TProperty>>,TValue)
CreateEqualExpression(System.Linq.Expressions.Expression`1<System.Func`2<TEntity,TProperty>>,System.Type,System.Object)
CreateNotEqualExpression(System.Linq.Expressions.Expression`1<System.Func`2<TEntity,TProperty>>,TValue)
CreateNotEqualExpression(System.Linq.Expressions.Expression`1<System.Func`2<TEntity,TProperty>>,System.Type,System.Object)
CreateLessThanExpression(System.Linq.Expressions.Expression`1<System.Func`2<TEntity,TProperty>>,TValue)
CreateLessThanExpression(System.Linq.Expressions.Expression`1<System.Func`2<TEntity,TProperty>>,System.Type,System.Object)
CreateLessThanOrEqualExpression(System.Linq.Expressions.Expression`1<System.Func`2<TEntity,TProperty>>,TValue)
CreateLessThanOrEqualExpression(System.Linq.Expressions.Expression`1<System.Func`2<TEntity,TProperty>>,System.Type,System.Object)
CreateGreaterThanExpression(System.Linq.Expressions.Expression`1<System.Func`2<TEntity,TProperty>>,TValue)
CreateGreaterThanExpression(System.Linq.Expressions.Expression`1<System.Func`2<TEntity,TProperty>>,System.Type,System.Object)
CreateGreaterThanOrEqualExpression(System.Linq.Expressions.Expression`1<System.Func`2<TEntity,TProperty>>,TValue)
CreateGreaterThanOrEqualExpression(System.Linq.Expressions.Expression`1<System.Func`2<TEntity,TProperty>>,System.Type,System.Object)
CreateAndCastExpressionParts(System.Linq.Expressions.Expression`1<System.Func`2<TEntity,TProperty>>,System.Type,System.Object)
CreateFilterExpressionCreationException(System.String,System.Linq.Expressions.Expression`1<System.Func`2<TEntity,TProperty>>,Plainquire.Filter.Abstractions.FilterOperator,TValue)