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; namespace DD.Persistence.Test; public class FilterBuilderShould { private readonly SpecificationEvaluator SpecificationEvaluator; public FilterBuilderShould() { this.SpecificationEvaluator = new SpecificationEvaluator(); } [Fact] public void TestFilterBuilding() { //arrange var discriminatorId = Guid.NewGuid(); var dataScheme = new DataScheme() { DiscriminatorId = discriminatorId, PropNames = ["A", "B", "C"], PropTypes = [PropTypeEnum.DateTime, PropTypeEnum.Double, PropTypeEnum.String] }; 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 DataScheme = dataScheme }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-2), Values = new object[] { filterDate.AddMinutes(1), 2.21, "IsNotEqualText" }, // true DataScheme = dataScheme }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-3), Values = new object[] { filterDate.AddMinutes(-1), 2.22, "IsNotEqualText" }, // false DataScheme = dataScheme }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-4), Values = new object[] { filterDate.AddMinutes(-1), 2.21, "IsNotEqualText" }, // false DataScheme = dataScheme } } .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 dataScheme = new DataScheme() { DiscriminatorId = discriminatorId, PropNames = ["A"], PropTypes = [PropTypeEnum.Double] }; 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 DataScheme = dataScheme }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-2), Values = new object[] { 1.96 }, // false DataScheme = dataScheme }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-3), Values = new object[] { 1.97 }, // true DataScheme = dataScheme }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-4), Values = new object[] { 1.98 }, // false DataScheme = dataScheme }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-5), Values = new object[] { 1.99 }, // true DataScheme = dataScheme }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-6), Values = new object[] { 2 }, // false DataScheme = dataScheme } } .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 dataScheme = new DataScheme() { DiscriminatorId = discriminatorId, PropNames = ["A", "B", "C", "D"], PropTypes = [PropTypeEnum.Double, PropTypeEnum.Double, PropTypeEnum.String, PropTypeEnum.DateTime] }; 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 DataScheme = dataScheme }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-2), Values = new object[] { 2, 1.11, "IsNotEqualText", DateTimeOffset.Now.AddMinutes(-1) }, // true DataScheme = dataScheme }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-3), Values = new object[] { 2, 2.22, "IsEqualText", DateTimeOffset.Now.AddMinutes(-1) }, // true DataScheme = dataScheme }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-4), Values = new object[] { 2, 2.22, "IsNotEqualText", filterDate }, // true DataScheme = dataScheme }, new TimestampedValues { DiscriminatorId = discriminatorId, Timestamp = DateTimeOffset.Now.AddMinutes(-1), Values = new object[] { 2, 2.22, "IsNotEqualText", DateTimeOffset.Now.AddMinutes(-1) }, // false DataScheme = dataScheme } } .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); } }