using Ardalis.Specification.EntityFrameworkCore; using DD.Persistence.Database.Entity; using DD.Persistence.Filter.Models; using DD.Persistence.Filter.Models.Enumerations; using DD.Persistence.Models; using DD.Persistence.Database.Postgres.Helpers; using System.Text.Json; namespace DD.Persistence.Test; /// ToDo: переписать под Theory public class FilterBuilderShould { private readonly SpecificationEvaluator SpecificationEvaluator; public FilterBuilderShould() { this.SpecificationEvaluator = new SpecificationEvaluator(); } [Fact] public void TestFilterBuilding() { //arrange var discriminatorId = Guid.NewGuid(); var dataSchemeProperties = new SchemePropertyDto[] { new SchemePropertyDto() { Index = 0, PropertyName = "A", PropertyKind = JsonValueKind.String }, new SchemePropertyDto() { Index = 1, PropertyName = "B", PropertyKind = JsonValueKind.Number }, new SchemePropertyDto() { Index = 2, PropertyName = "C", PropertyKind = JsonValueKind.String } }; var dataScheme = new DataSchemeDto(discriminatorId, dataSchemeProperties); var filterDate = DateTime.Now.AddMinutes(-1); var root = new TVertex( OperationEnum.Or, new TVertex( OperationEnum.And, new TLeaf(OperationEnum.Greate, "A", filterDate), new TLeaf(OperationEnum.Less, "B", 2.22) ), new TLeaf(OperationEnum.Equal, "C", "IsEqualText") ); var queryableData = new[] { new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-1), Values = new object[] { filterDate.AddMinutes(-1), 200, "IsEqualText" } // true }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-2), Values = new object[] { filterDate.AddMinutes(1), 2.21, "IsNotEqualText" } // true }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-3), Values = new object[] { filterDate.AddMinutes(-1), 2.22, "IsNotEqualText" } // false }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-4), Values = new object[] { filterDate.AddMinutes(-1), 2.21, "IsNotEqualText" } // false } } .AsQueryable(); //act var specification = dataScheme.BuildFilter(root); //assert Assert.NotNull(specification); var query = SpecificationEvaluator.GetQuery(queryableData, specification); var result = query.ToList(); Assert.NotNull(result); Assert.NotEmpty(result); var expectedCount = 2; var actualCount = result.Count(); Assert.Equal(expectedCount, actualCount); } [Fact] public void TestFilterOperations() { //arrange var discriminatorId = Guid.NewGuid(); var dataSchemeProperties = new SchemePropertyDto[] { new SchemePropertyDto() { Index = 0, PropertyName = "A", PropertyKind = JsonValueKind.Number } }; var dataScheme = new DataSchemeDto(discriminatorId, dataSchemeProperties); var root = new TVertex( OperationEnum.Or, new TVertex( OperationEnum.And, new TVertex( OperationEnum.And, new TVertex( OperationEnum.And, new TVertex( OperationEnum.And, new TLeaf(OperationEnum.Less, "A", 2), new TLeaf(OperationEnum.LessOrEqual, "A", 1.99) ), new TLeaf(OperationEnum.GreateOrEqual, "A", 1.97) ), new TLeaf(OperationEnum.Greate, "A", 1.96) ), new TLeaf(OperationEnum.NotEqual, "A", 1.98) ), new TLeaf(OperationEnum.Equal, "A", 1) ); var queryableData = new[] { new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-1), Values = new object[] { 1 } // true }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-2), Values = new object[] { 1.96 } // false }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-3), Values = new object[] { 1.97 } // true }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-4), Values = new object[] { 1.98 } // false }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-5), Values = new object[] { 1.99 } // true }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-6), Values = new object[] { 2 } // false } } .AsQueryable(); //act var specification = dataScheme.BuildFilter(root); //assert Assert.NotNull(specification); var query = SpecificationEvaluator.GetQuery(queryableData, specification); var result = query.ToList(); Assert.NotNull(result); Assert.NotEmpty(result); var expectedCount = 3; var actualCount = result.Count(); Assert.Equal(expectedCount, actualCount); } [Fact] public void TestFilterValues() { //arrange var discriminatorId = Guid.NewGuid(); var filterDate = DateTimeOffset.Now; var dataSchemeProperties = new SchemePropertyDto[] { new SchemePropertyDto() { Index = 0, PropertyName = "A", PropertyKind = JsonValueKind.Number }, new SchemePropertyDto() { Index = 1, PropertyName = "B", PropertyKind = JsonValueKind.Number }, new SchemePropertyDto() { Index = 2, PropertyName = "C", PropertyKind = JsonValueKind.String }, new SchemePropertyDto() { Index = 3, PropertyName = "D", PropertyKind = JsonValueKind.String } }; var dataScheme = new DataSchemeDto(discriminatorId, dataSchemeProperties); var root = new TVertex( OperationEnum.Or, new TVertex( OperationEnum.Or, new TVertex( OperationEnum.Or, new TLeaf(OperationEnum.Equal, "A", 1), new TLeaf(OperationEnum.Equal, "B", 1.11) ), new TLeaf(OperationEnum.Equal, "C", "IsEqualText") ), new TLeaf(OperationEnum.Equal, "D", filterDate) ); var queryableData = new[] { new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-1), Values = new object[] { 1, 2.22, "IsNotEqualText", DateTimeOffset.Now.AddMinutes(-1) } // true }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-2), Values = new object[] { 2, 1.11, "IsNotEqualText", DateTimeOffset.Now.AddMinutes(-1) } // true }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-3), Values = new object[] { 2, 2.22, "IsEqualText", DateTimeOffset.Now.AddMinutes(-1) } // true }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-4), Values = new object[] { 2, 2.22, "IsNotEqualText", filterDate } // true }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-1), Values = new object[] { 2, 2.22, "IsNotEqualText", DateTimeOffset.Now.AddMinutes(-1) } // false } } .AsQueryable(); //act var specification = dataScheme.BuildFilter(root); //assert Assert.NotNull(specification); var query = SpecificationEvaluator.GetQuery(queryableData, specification); var result = query.ToList(); Assert.NotNull(result); Assert.NotEmpty(result); var expectedCount = 4; var actualCount = result.Count(); Assert.Equal(expectedCount, actualCount); } }