< Summary

Information
Class: Fluorite.Strainer.Services.Pipelines.FilterPipelineOperation
Assembly: Fluorite.Strainer
File(s): /builds/fluorite/strainer/src/Strainer/Services/Pipelines/FilterPipelineOperation.cs
Line coverage
100%
Covered lines: 49
Uncovered lines: 0
Coverable lines: 49
Total lines: 108
Line coverage: 100%
Branch coverage
100%
Covered branches: 16
Total branches: 16
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
Execute(...)100%1616100%

File(s)

/builds/fluorite/strainer/src/Strainer/Services/Pipelines/FilterPipelineOperation.cs

#LineLine coverage
 1using Fluorite.Strainer.Exceptions;
 2using Fluorite.Strainer.Models;
 3using Fluorite.Strainer.Services.Filtering;
 4using Fluorite.Strainer.Services.Linq;
 5using Fluorite.Strainer.Services.Metadata;
 6using System.Linq.Expressions;
 7
 8namespace Fluorite.Strainer.Services.Pipelines;
 9
 10public class FilterPipelineOperation : IFilterPipelineOperation, IStrainerPipelineOperation
 11{
 12    private readonly ICustomFilteringExpressionProvider _customFilteringExpressionProvider;
 13    private readonly IFilterExpressionProvider _filterExpressionProvider;
 14    private readonly IQueryableEvaluator _queryableEvaluator;
 15    private readonly IFilterTermParser _filterTermParser;
 16    private readonly IMetadataFacade _metadataFacade;
 17    private readonly IStrainerOptionsProvider _strainerOptionsProvider;
 18
 919    public FilterPipelineOperation(
 920        ICustomFilteringExpressionProvider customFilteringExpressionProvider,
 921        IFilterExpressionProvider filterExpressionProvider,
 922        IQueryableEvaluator queryableEvaluator,
 923        IFilterTermParser filterTermParser,
 924        IMetadataFacade metadataFacade,
 925        IStrainerOptionsProvider strainerOptionsProvider)
 26    {
 927        _customFilteringExpressionProvider = Guard.Against.Null(customFilteringExpressionProvider);
 928        _filterExpressionProvider = Guard.Against.Null(filterExpressionProvider);
 929        _queryableEvaluator = Guard.Against.Null(queryableEvaluator);
 930        _filterTermParser = Guard.Against.Null(filterTermParser);
 931        _metadataFacade = Guard.Against.Null(metadataFacade);
 932        _strainerOptionsProvider = Guard.Against.Null(strainerOptionsProvider);
 933    }
 34
 35    public IQueryable<T> Execute<T>(IStrainerModel model, IQueryable<T> source)
 36    {
 837        Guard.Against.Null(model);
 838        Guard.Against.Null(source);
 39
 840        var options = _strainerOptionsProvider.GetStrainerOptions();
 841        var parsedTerms = _filterTermParser.GetParsedTerms(model.Filters);
 842        if (parsedTerms.Count == 0)
 43        {
 144            return source;
 45        }
 46
 747        var isMaterializedQueryable = _queryableEvaluator.IsMaterialized(source);
 748        Expression? outerExpression = null;
 749        var parameterExpression = Expression.Parameter(typeof(T), "e");
 2850        foreach (var filterTerm in parsedTerms)
 51        {
 852            Expression? termExpression = null;
 3253            foreach (var filterTermName in filterTerm.Names)
 54            {
 955                var metadata = _metadataFacade.GetMetadata<T>(
 956                    isSortableRequired: false,
 957                    isFilterableRequired: true,
 958                    name: filterTermName);
 59
 60                try
 61                {
 962                    if (metadata is not null)
 63                    {
 664                        termExpression = _filterExpressionProvider.GetExpression(metadata, filterTerm, parameterExpressi
 65                    }
 66                    else
 67                    {
 368                        if (_customFilteringExpressionProvider.TryGetCustomExpression<T>(filterTerm, filterTermName, out
 69                        {
 170                            source = source.Where(customExpression);
 71                        }
 72                        else
 73                        {
 274                            throw new StrainerFilterNotFoundException(
 275                                filterTermName,
 276                                $"Property or custom filter method '{filterTermName}' was not found.");
 77                        }
 78                    }
 779                }
 280                catch (StrainerException) when (!options.ThrowExceptions)
 81                {
 182                    return source;
 83                }
 84            }
 85
 686            if (termExpression is not null)
 87            {
 488                if (outerExpression is null)
 89                {
 390                    outerExpression = termExpression;
 91                }
 92                else
 93                {
 194                    outerExpression = Expression.And(outerExpression, termExpression);
 95                }
 96            }
 97        }
 98
 599        if (outerExpression is null)
 100        {
 2101            return source;
 102        }
 103
 3104        var lambdaExpression = Expression.Lambda<Func<T, bool>>(outerExpression, parameterExpression);
 105
 3106        return source.Where(lambdaExpression);
 1107    }
 108}