< Summary - Code Coverage

Information
Class: Plainquire.Filter.ValueFilterExpressions.DateTimeFilterExpression
Assembly: Plainquire.Filter
File(s): /home/runner/work/plainquire/plainquire/Plainquire.Filter/Plainquire.Filter/ValueFilterExpressions/DateTimeFilterExpression.cs
Tag: 64_13932151703
Line coverage
97%
Covered lines: 42
Uncovered lines: 1
Coverable lines: 43
Total lines: 118
Line coverage: 97.6%
Branch coverage
86%
Covered branches: 19
Total branches: 22
Branch coverage: 86.3%
Method coverage
100%
Covered methods: 5
Total methods: 5
Method coverage: 100%

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
CanCreateExpressionFor(...)100%11100%
CreateExpressionForValue(...)100%66100%
CreateDateTimeExpressionByFilterOperator(...)81.25%161694.11%
CreateDateTimeSpanContainsExpression(...)100%11100%

File(s)

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

#LineLine coverage
 1using Plainquire.Filter.Abstractions;
 2using System;
 3using System.Collections.Generic;
 4using System.Diagnostics.CodeAnalysis;
 5using System.Globalization;
 6using System.Linq;
 7using System.Linq.Expressions;
 8
 9namespace Plainquire.Filter.ValueFilterExpressions;
 10
 11/// <inheritdoc cref="IDateTimeFilterExpression"/>
 12[SuppressMessage("ReSharper", "MemberCanBePrivate.Global", Justification = "Provided as library, can be used from outsid
 13public class DateTimeFilterExpression : DefaultFilterExpression, IDateTimeFilterExpression
 14{
 15    /// <inheritdoc />
 16    public override ICollection<FilterOperator> SupportedFilterOperators
 17        =>
 826018        [
 826019            FilterOperator.Default,
 826020            FilterOperator.Contains,
 826021            FilterOperator.EqualCaseInsensitive,
 826022            FilterOperator.EqualCaseSensitive,
 826023            FilterOperator.NotEqual,
 826024            FilterOperator.LessThan,
 826025            FilterOperator.LessThanOrEqual,
 826026            FilterOperator.GreaterThan,
 826027            FilterOperator.GreaterThanOrEqual,
 826028            FilterOperator.IsNull,
 826029            FilterOperator.NotNull
 826030        ];
 31
 32    /// <inheritdoc />
 33    public override bool CanCreateExpressionFor(Type type)
 34#if NET6_0_OR_GREATER
 1930235        => new[] { typeof(Range<DateTimeOffset>), typeof(DateTime), typeof(DateOnly), typeof(DateTimeOffset) }.Contains(
 36#else
 37        => new[] { typeof(Range<DateTimeOffset>), typeof(DateTime), typeof(DateTimeOffset) }.Contains(type.GetUnderlying
 38#endif
 39
 40    /// <inheritdoc />
 41    protected internal override Expression? CreateExpressionForValue<TEntity, TProperty>(Expression<Func<TEntity, TPrope
 42    {
 717943        var now = interceptor?.Now() ?? DateTimeOffset.Now;
 717944        if (value.TryConvertStringToDateTimeRange(now, out var dateTimeSpan, new CultureInfo(configuration.CultureName))
 623945            return CreateDateTimeExpressionByFilterOperator(propertySelector, filterOperator, dateTimeSpan);
 46
 94047        if (configuration.IgnoreParseExceptions)
 14748            return null;
 49
 79350        throw CreateFilterExpressionCreationException("Unable to parse given filter value", propertySelector, filterOper
 51    }
 52
 53    private Expression CreateDateTimeExpressionByFilterOperator<TEntity, TProperty>(Expression<Func<TEntity, TProperty>>
 54    {
 55        TProperty valueStart;
 56        TProperty valueEnd;
 57
 623958        var underlyingFilterPropertyType = typeof(TProperty).GetUnderlyingType();
 623959        if (underlyingFilterPropertyType == typeof(DateTime))
 60        {
 178761            valueStart = (TProperty)(object)value.Start.DateTime;
 178762            valueEnd = (TProperty)(object)value.End.DateTime;
 63        }
 64#if NET6_0_OR_GREATER
 445265        else if (underlyingFilterPropertyType == typeof(DateOnly))
 66        {
 175267            valueStart = (TProperty)(object)DateOnly.FromDateTime(value.Start.Date);
 175268            valueEnd = (TProperty)(object)DateOnly.FromDateTime(value.End.Date);
 69        }
 70#endif
 71        else
 72        {
 270073            valueStart = (TProperty)(object)value.Start;
 270074            valueEnd = (TProperty)(object)value.End;
 75        }
 76
 77        switch (filterOperator)
 78        {
 79            case FilterOperator.Default:
 80            case FilterOperator.Contains:
 310781                return CreateDateTimeSpanContainsExpression(propertySelector, valueStart, valueEnd);
 82            case FilterOperator.EqualCaseInsensitive:
 83            case FilterOperator.EqualCaseSensitive:
 105684                return CreateEqualExpression(propertySelector, valueStart);
 85            case FilterOperator.NotEqual:
 52886                return CreateNotEqualExpression(propertySelector, valueStart);
 87            case FilterOperator.LessThan:
 39088                return CreateLessThanExpression(propertySelector, valueStart);
 89            case FilterOperator.LessThanOrEqual:
 38490                return CreateLessThanOrEqualExpression(propertySelector, valueStart);
 91            case FilterOperator.GreaterThan:
 38492                return CreateGreaterThanExpression(propertySelector, valueStart);
 93            case FilterOperator.GreaterThanOrEqual:
 39094                return CreateGreaterThanOrEqualExpression(propertySelector, valueStart);
 95            default:
 096                throw CreateFilterExpressionCreationException($"Filter operator '{filterOperator}' not allowed for prope
 97        }
 98    }
 99
 100    /// <summary>
 101    /// Creates a date time span contains expression.
 102    /// </summary>
 103    /// <typeparam name="TEntity">The type of the entity.</typeparam>
 104    /// <typeparam name="TProperty">The type of the property.</typeparam>
 105    /// <typeparam name="TValue">The type of the value.</typeparam>
 106    /// <param name="propertySelector">The property selector.</param>
 107    /// <param name="start">The start <see cref="DateTime"/> or <see cref="DateTimeOffset"/>.</param>
 108    /// <param name="end">The end <see cref="DateTime"/> or <see cref="DateTimeOffset"/>.</param>
 109    public static Expression CreateDateTimeSpanContainsExpression<TEntity, TProperty, TValue>(Expression<Func<TEntity, T
 110    {
 3107111        var startExpression = Expression.Constant(start, typeof(TProperty));
 3107112        var endExpression = Expression.Constant(end, typeof(TProperty));
 3107113        var startGreaterThanOrEqualExpression = Expression.GreaterThanOrEqual(propertySelector.Body, startExpression);
 3107114        var endLessThanExpression = Expression.LessThan(propertySelector.Body, endExpression);
 3107115        var result = Expression.AndAlso(startGreaterThanOrEqualExpression, endLessThanExpression);
 3107116        return result;
 117    }
 118}