< Summary

Information
Class: Pozitron.QuerySpecification.Specification<T>
Assembly: Pozitron.QuerySpecification
File(s): /home/runner/work/QuerySpecification/QuerySpecification/src/QuerySpecification/Specification.cs
Tag: 44_11195777782
Line coverage
100%
Covered lines: 25
Uncovered lines: 0
Coverable lines: 25
Total lines: 78
Line coverage: 100%
Branch coverage
100%
Covered branches: 22
Total branches: 22
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%
get_Query()100%11100%
get_Take()100%11100%
get_Skip()100%11100%
get_IgnoreQueryFilters()100%11100%
get_AsSplitQuery()100%11100%
get_AsNoTracking()100%11100%
get_AsNoTrackingWithIdentityResolution()100%11100%
Add(...)100%22100%
Add(...)100%22100%
Add(...)100%22100%
Add(...)100%22100%
Add(...)100%22100%
get_Items()100%22100%
get_WhereExpressions()100%22100%
get_LikeExpressions()100%22100%
get_OrderExpressions()100%22100%
get_IncludeExpressions()100%22100%
get_IncludeStrings()100%22100%
Evaluate(...)100%11100%
IsSatisfiedBy(...)100%11100%

File(s)

/home/runner/work/QuerySpecification/QuerySpecification/src/QuerySpecification/Specification.cs

#LineLine coverage
 1namespace Pozitron.QuerySpecification;
 2
 3public class Specification<T, TResult> : Specification<T>
 4{
 5    public Specification()
 6    {
 7        Query = new SpecificationBuilder<T, TResult>(this);
 8    }
 9
 10    public new ISpecificationBuilder<T, TResult> Query { get; }
 11
 12    public Expression<Func<T, TResult>>? Selector { get; internal set; }
 13    public Expression<Func<T, IEnumerable<TResult>>>? SelectorMany { get; internal set; }
 14
 15    public new virtual IEnumerable<TResult> Evaluate(IEnumerable<T> entities, bool ignorePaging = false)
 16    {
 17        var evaluator = SpecificationInMemoryEvaluator.Default;
 18        return evaluator.Evaluate(entities, this, ignorePaging);
 19    }
 20}
 21
 22public class Specification<T>
 23{
 24    // The state is null initially, but we're spending 8 bytes per reference on x64.
 25    // I considered keeping the whole state as a Dictionary<int, object>, and that reduces the footprint for empty specs
 26    // But, specs are never empty, and the overhead of the dictionary compensates the saved space. Also casting back and
 27    // Refer to SpecificationSizeTests for more details.
 28    private List<WhereExpression<T>>? _whereExpressions;
 29    private List<LikeExpression<T>>? _likeExpressions;
 30    private List<OrderExpression<T>>? _orderExpressions;
 31    private List<IncludeExpression>? _includeExpressions;
 32    private List<string>? _includeStrings;
 33    private Dictionary<string, object>? _items;
 34
 24235    public Specification()
 36    {
 24237        Query = new SpecificationBuilder<T>(this);
 24238    }
 39
 12440    public ISpecificationBuilder<T> Query { get; }
 41
 33842    public int Take { get; internal set; } = -1;
 33943    public int Skip { get; internal set; } = -1;
 44
 45    // Based on the alignment of 8 bytes (on x64) we can store 8 flags here
 46    // So, we have space for 4 more flags for free.
 6947    public bool IgnoreQueryFilters { get; internal set; } = false;
 6148    public bool AsSplitQuery { get; internal set; } = false;
 7449    public bool AsNoTracking { get; internal set; } = false;
 7450    public bool AsNoTrackingWithIdentityResolution { get; internal set; } = false;
 51
 7752    internal void Add(WhereExpression<T> whereExpression) => (_whereExpressions ??= new(2)).Add(whereExpression);
 6753    internal void Add(LikeExpression<T> likeExpression) => (_likeExpressions ??= new(2)).Add(likeExpression);
 9254    internal void Add(OrderExpression<T> orderExpression) => (_orderExpressions ??= new(2)).Add(orderExpression);
 10955    internal void Add(IncludeExpression includeExpression) => (_includeExpressions ??= new(2)).Add(includeExpression);
 1556    internal void Add(string includeString) => (_includeStrings ??= new(1)).Add(includeString);
 57
 58
 59    // Specs are not intended to be thread-safe, so we don't need to worry about thread-safety here.
 160    public Dictionary<string, object> Items => _items ??= [];
 8661    public IEnumerable<WhereExpression<T>> WhereExpressions => _whereExpressions ?? Enumerable.Empty<WhereExpression<T>>
 11762    public IEnumerable<LikeExpression<T>> LikeExpressions => _likeExpressions ?? Enumerable.Empty<LikeExpression<T>>();
 16863    public IEnumerable<OrderExpression<T>> OrderExpressions => _orderExpressions ?? Enumerable.Empty<OrderExpression<T>>
 9064    public IEnumerable<IncludeExpression> IncludeExpressions => _includeExpressions ?? Enumerable.Empty<IncludeExpressio
 6265    public IEnumerable<string> IncludeStrings => _includeStrings ?? Enumerable.Empty<string>();
 66
 67    public virtual IEnumerable<T> Evaluate(IEnumerable<T> entities, bool ignorePaging = false)
 68    {
 269        var evaluator = SpecificationInMemoryEvaluator.Default;
 270        return evaluator.Evaluate(entities, this, ignorePaging);
 71    }
 72
 73    public virtual bool IsSatisfiedBy(T entity)
 74    {
 375        var validator = SpecificationValidator.Default;
 376        return validator.IsValid(entity, this);
 77    }
 78}