Exemplo n.º 1
0
        public void CombinationFilterNode_Equality_IsNotAffectedByGenericType()
        {
            IFilterNode <CharFilter> combination1 = new CombinationFilterNode <CharFilter>(new[] { new CharFilterSubClass('A'), new CharFilterSubClass('B') });

            // Note combination2 is constructed using a more specific generic type than combination1.
            IFilterNode <CharFilter> combination2 = new CombinationFilterNode <CharFilterSubClass>(new[] { new CharFilterSubClass('A'), new CharFilterSubClass('B') });

            Assert.Equal(combination1, combination2);
            Assert.Equal(combination2, combination1);
        }
        public void CombinationFilter_OrOperator_GetPredicate_FiltersToExpectedResults()
        {
            var filter1 = new NumericRangeFilter(5, 10);
            var filter2 = new NumericRangeFilter(8, 15);
            var filter  = new CombinationFilterNode <NumericRangeFilter>(new[] { filter1, filter2 }, CombinationOperator.Any);
            var values  = new[] { 1, 3, 5, 9, 11 };
            var expectedFilteredValues = new[] { 5, 9, 11 };

            var filterPredicate = filter.GetPredicate <NumericRangeFilter, int>();
            var filteredValues  = values.Where(filterPredicate);

            Assert.Equal(expectedFilteredValues, filteredValues);
        }
        public void Collapse_ShouldRemoveDuplicates()
        {
            var filter                = new CharFilter('A');
            var leafFilterNode        = filter.ToLeafFilterNode();
            var combinationFilterNode = new CombinationFilterNode <CharFilter>(new[] { leafFilterNode, leafFilterNode });
            var collapsedFilterNode   = combinationFilterNode.Collapse();
            var expectedFilterNode    = filter.ToLeafFilterNode();

            Assert.Equal(expectedFilterNode, collapsedFilterNode);

            // Also check IsEquivalentTo works, which internally uses Collapse.
            Assert.True(leafFilterNode.IsEquivalentTo(combinationFilterNode));
            Assert.True(combinationFilterNode.IsEquivalentTo(leafFilterNode));
        }
        public void CombinationFilterNodeWithOperatorAll_ShouldPrecedeCombinationFilterNodeWithOperatorAny()
        {
            var allCombination = new CombinationFilterNode <CharFilter>(new[] { new CharFilter('B'), new CharFilter('C') }, CombinationOperator.All);
            var anyCombination = new CombinationFilterNode <CharFilter>(new[] { new CharFilter('B'), new CharFilter('C') }, CombinationOperator.Any);

            var sut    = FilterNodeComparer <CharFilter> .Default;
            var result = sut.Compare(allCombination, anyCombination);

            Assert.Equal(-1, result);

            var oppositeResult = sut.Compare(anyCombination, allCombination);

            Assert.Equal(1, oppositeResult);
        }
        public void InvertedFilterNode_ShouldPrecedeCombinationFilterNode()
        {
            var invertedFilterNode    = new InvertedFilterNode <CharFilter>(new CharFilter('A'));
            var combinationFilterNode = new CombinationFilterNode <CharFilter>(new[] { new CharFilter('B'), new CharFilter('C') });

            var sut    = FilterNodeComparer <CharFilter> .Default;
            var result = sut.Compare(invertedFilterNode, combinationFilterNode);

            Assert.Equal(-1, result);

            var oppositeResult = sut.Compare(combinationFilterNode, invertedFilterNode);

            Assert.Equal(1, oppositeResult);
        }
        public void CombinationFilterNodeComparison_ShouldUseLexicographicalListComparison()
        {
            var combination1 = new CombinationFilterNode <CharFilter>(new[] { new CharFilter('A'), new CharFilter('C') });
            var combination2 = new CombinationFilterNode <CharFilter>(new[] { new CharFilter('A'), new CharFilter('B') });

            var sut    = FilterNodeComparer <CharFilter> .Default;
            var result = sut.Compare(combination1, combination2);

            Assert.Equal(1, result);

            var oppositeResult = sut.Compare(combination2, combination1);

            Assert.Equal(-1, oppositeResult);
        }
Exemplo n.º 7
0
        public void ComplexFilter_IsMatch_FiltersToExpectedResults()
        {
            var filter5To10        = new NumericRangeFilter(5, 10);
            var filter8To15        = new NumericRangeFilter(8, 15);
            var filter5To10Or8To15 = new CombinationFilterNode <NumericRangeFilter>(new[] { filter5To10, filter8To15 }, CombinationOperator.Any);
            var filter9To12        = new NumericRangeFilter(9, 12);
            var filter             = new CombinationFilterNode <NumericRangeFilter>(new IFilterNode <NumericRangeFilter>[] { filter5To10Or8To15, filter9To12.ToLeafFilterNode() }, CombinationOperator.All);

            var values = new[] { 1, 3, 5, 9, 11 };
            var expectedFilteredValues = new[] { 9, 11 };

            var filteredValues = values.Where(filter.IsMatch);

            Assert.Equal(expectedFilteredValues, filteredValues);
        }
        public void Collapse_ShouldFlattenNestedCombinations_WhenInnerOperatorMatchesOuter(CombinationOperator outerCombinationOperator, CombinationOperator alternateInnerCombinationOperator)
        {
            var filterA = new CharFilter('A');
            var filterB = new CharFilter('B');
            var filterC = new CharFilter('C');
            var filterD = new CharFilter('D');
            var filterE = new CharFilter('E');
            var filterF = new CharFilter('F');
            var filterG = new CharFilter('G');
            var filterH = new CharFilter('H');

            var innerCombinationFilterToFlatten = new CombinationFilterNode <CharFilter>(new [] { filterA, filterB }, outerCombinationOperator);
            var innerCombinationFilterToRetain1 = new CombinationFilterNode <CharFilter>(new [] { filterC, filterD }, alternateInnerCombinationOperator);
            var innerCombinationFilterToRetain2 = new CombinationFilterNode <CharFilter>(new[] { filterE, filterF }, alternateInnerCombinationOperator);

            // When outer operator == All and other == Any, this is equivalent to
            // (A AND B) AND (C OR D) AND (E OR F) AND G AND H
            // Which can be collapsed to: A AND B AND G AND H AND (C OR D) AND (E OR F)
            // When outer operator == Any and other == All, this is equivalent to
            // (A OR B) OR (C AND D) OR (E AND F) OR G OR H
            // Which can be collapsed to: A OR B OR G OR H OR (C AND D) OR (E AND F)
            var outerCombinationFilter = new CombinationFilterNode <CharFilter>(new IFilterNode <CharFilter>[]
            {
                innerCombinationFilterToFlatten,
                innerCombinationFilterToRetain1,
                innerCombinationFilterToRetain2,
                filterG.ToLeafFilterNode(),
                filterH.ToLeafFilterNode()
            }, outerCombinationOperator);

            var collapsedFilter = outerCombinationFilter.Collapse();

            var expectedCollapsedFilter = new CombinationFilterNode <CharFilter>(new IFilterNode <CharFilter>[]
            {
                filterA.ToLeafFilterNode(),
                filterB.ToLeafFilterNode(),
                innerCombinationFilterToRetain1,
                innerCombinationFilterToRetain2,
                filterG.ToLeafFilterNode(),
                filterH.ToLeafFilterNode(),
            }, outerCombinationOperator);

            Assert.Equal(expectedCollapsedFilter, collapsedFilter);

            // Also check IsEquivalentTo works, which internally uses Collapse.
            Assert.True(collapsedFilter.IsEquivalentTo(outerCombinationFilter));
            Assert.True(outerCombinationFilter.IsEquivalentTo(collapsedFilter));
        }
        public void Aggregate_ReturnsExpectedResult_WhenComputingLengthOfLongestInterval()
        {
            var filter5To10        = new NumericRangeFilter(5, 10);
            var filter8To15        = new NumericRangeFilter(8, 15);
            var filter5To10Or8To15 = new CombinationFilterNode <NumericRangeFilter>(new[] { filter5To10, filter8To15 }, CombinationOperator.Any);
            var filter9To12        = new NumericRangeFilter(9, 12);
            var filter             = new CombinationFilterNode <NumericRangeFilter>(new IFilterNode <NumericRangeFilter>[] { filter5To10Or8To15, filter9To12.ToLeafFilterNode() }, CombinationOperator.All);

            // Reduce the filter to get the length of the longest interval
            var result = filter.Aggregate <double>(
                (lengths, _) => lengths.Max(),
                length => double.PositiveInfinity,
                leafFilterNode => leafFilterNode.Filter.UpperBound - leafFilterNode.Filter.LowerBound);

            // Max is 15 - 8
            Assert.Equal(7, result);
        }
Exemplo n.º 10
0
        public void Bind_ReturnsCorrectStructureAndValues()
        {
            var filter5To10 = new NumericRangeFilter(5, 10);
            var filter8To15 = new NumericRangeFilter(8, 15);
            var filter5To10Or8To15 = new[] { filter5To10, filter8To15 }.Combine(CombinationOperator.Any);
            var filter9To12 = new NumericRangeFilter(9, 12);
            var filter = new[] { filter5To10Or8To15, filter9To12.ToLeafFilterNode() }.Combine(CombinationOperator.All);

            var result = filter.Bind <NumericRangeFilter>(
                f =>
            {
                if (ReferenceEquals(f, filter5To10))
                {
                    return(new CombinationFilterNode <NumericRangeFilter>(new [] { filter5To10, filter8To15 }, CombinationOperator.Any));
                }

                if (ReferenceEquals(f, filter8To15))
                {
                    return(FilterNode <NumericRangeFilter> .False);
                }

                if (ReferenceEquals(f, filter9To12))
                {
                    return(new InvertedFilterNode <NumericRangeFilter>(f));
                }

                return(f.ToLeafFilterNode());
            });

            var expectedFilter = new CombinationFilterNode <NumericRangeFilter>(
                new IFilterNode <NumericRangeFilter>[]
            {
                new CombinationFilterNode <NumericRangeFilter>(
                    new IFilterNode <NumericRangeFilter>[]
                {
                    filter5To10Or8To15,
                    FilterNode <NumericRangeFilter> .False
                }, CombinationOperator.Any),
                new InvertedFilterNode <NumericRangeFilter>(filter9To12),
            }, CombinationOperator.All);

            Assert.Equal(expectedFilter, result);
        }
Exemplo n.º 11
0
        public void Collapse_ShouldAbsorbRedundantNestedCombinations(CombinationOperator outerCombinationOperator, CombinationOperator alternateInnerCombinationOperator)
        {
            var filterA = new CharFilter('A');
            var filterB = new CharFilter('B');
            var filterC = new CharFilter('C');
            var filterD = new CharFilter('D');
            var filterE = new CharFilter('E');
            var filterF = new CharFilter('F');
            var filterG = new CharFilter('G');
            var filterH = new CharFilter('H');

            var innerCombinationFilterToFlatten = new CombinationFilterNode <CharFilter>(new[] { filterA, filterB }, outerCombinationOperator);
            var innerCombinationFilterToRetain  = new CombinationFilterNode <CharFilter>(new[] { filterC, filterD }, alternateInnerCombinationOperator);
            var innerCombinationFilterToAbsorb  = new CombinationFilterNode <CharFilter>(new[] { filterA, filterE }, alternateInnerCombinationOperator);

            var outerCombinationFilter = new CombinationFilterNode <CharFilter>(new IFilterNode <CharFilter>[]
            {
                innerCombinationFilterToFlatten,
                innerCombinationFilterToRetain,
                innerCombinationFilterToAbsorb,
                filterG.ToLeafFilterNode(),
                filterH.ToLeafFilterNode()
            }, outerCombinationOperator);

            var collapsedFilter = outerCombinationFilter.Collapse();

            var expectedCollapsedFilter = new CombinationFilterNode <CharFilter>(new IFilterNode <CharFilter>[]
            {
                filterA.ToLeafFilterNode(),
                filterB.ToLeafFilterNode(),
                innerCombinationFilterToRetain,
                filterG.ToLeafFilterNode(),
                filterH.ToLeafFilterNode(),
            }, outerCombinationOperator);

            Assert.Equal(expectedCollapsedFilter, collapsedFilter);

            // Also check IsEquivalentTo works, which internally uses Collapse.
            Assert.True(collapsedFilter.IsEquivalentTo(outerCombinationFilter));
            Assert.True(outerCombinationFilter.IsEquivalentTo(collapsedFilter));
        }
Exemplo n.º 12
0
        public void GetPartial_Example()
        {
            // All the numbers from -5 to 10, EXCEPT numbers from 2 to 6
            var filter = new CombinationFilterNode <NumericRangeFilter>(new IFilterNode <NumericRangeFilter>[]
            {
                new LeafFilterNode <NumericRangeFilter>(new NumericRangeFilter(-5, 10)),
                new InvertedFilterNode <NumericRangeFilter>(new NumericRangeFilter(2, 6)),
            }, CombinationOperator.All);

            // Exclude filters with negative values
            var partialFilter = filter.GetPartial(f => f.LowerBound >= 0);

            var positiveValues    = new[] { 1, 3, 5, 7, 12 };
            var prefilteredValues = positiveValues.Where(partialFilter.GetPredicate <NumericRangeFilter, int>()).ToList();

            Assert.Equal(new[] { 1, 7, 12 }, prefilteredValues);

            var additionalValues = new[] { -7, -4, 11 };
            var combinedValues   = prefilteredValues.Concat(additionalValues);

            var finalValues = combinedValues.Where(filter.GetPredicate <NumericRangeFilter, int>());

            Assert.Equal(new[] { 1, 7, -4 }, finalValues);
        }
Exemplo n.º 13
0
        public void Map_ReturnsCorrectStructureAndValues()
        {
            var filter5To10        = new NumericRangeFilter(5, 10);
            var filter8To15        = new NumericRangeFilter(8, 15);
            var filter5To10Or8To15 = new CombinationFilterNode <NumericRangeFilter>(new[] { filter5To10, filter8To15 }, CombinationOperator.Any);
            var filter9To12        = new NumericRangeFilter(9, 12);
            var filter             = new CombinationFilterNode <NumericRangeFilter>(new IFilterNode <NumericRangeFilter>[] { filter5To10Or8To15, filter9To12.ToLeafFilterNode() }, CombinationOperator.All);

            var result = filter.Map(
                f =>
            {
                var newLowerBound = f.LowerBound + 1;
                var newUpperBound = f.UpperBound - 1;
                return(new NumericRangeFilter(newLowerBound, newUpperBound));
            });

            var filter6To9        = new NumericRangeFilter(6, 9);
            var filter9To14       = new NumericRangeFilter(9, 14);
            var filter6To9Or9To14 = new CombinationFilterNode <NumericRangeFilter>(new[] { filter6To9, filter9To14 }, CombinationOperator.Any);
            var filter10To11      = new NumericRangeFilter(10, 11);
            var expectedFilter    = new CombinationFilterNode <NumericRangeFilter>(new IFilterNode <NumericRangeFilter>[] { filter6To9Or9To14, filter10To11.ToLeafFilterNode() }, CombinationOperator.All);

            Assert.Equal(expectedFilter, result);
        }