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 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 LeafFilterNodeComparison_ShouldUseFilterComparer() { var filterA = new CharFilter('A'); var filterALeafNode = filterA.ToLeafFilterNode(); var filterB = new CharFilter('B'); var filterBLeafNode = filterB.ToLeafFilterNode(); const int expectedResultFilterAVsFilterB = 1337; const int expectedResultFilterBVsFilterA = 1338; var filterComparer = Substitute.For <IComparer <CharFilter> >(); filterComparer.Compare(filterA, filterB) .Returns(expectedResultFilterAVsFilterB); filterComparer.Compare(filterB, filterA) .Returns(expectedResultFilterBVsFilterA); var sut = new FilterNodeComparer <CharFilter>(filterComparer); var result = sut.Compare(filterALeafNode, filterBLeafNode); Assert.Equal(expectedResultFilterAVsFilterB, result); var oppositeResult = sut.Compare(filterBLeafNode, filterALeafNode); Assert.Equal(expectedResultFilterBVsFilterA, oppositeResult); }
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)); }
public void InvertedFilterNodeComparison_ShouldCompareNodeToInvert() { var filterA = new CharFilter('A'); var filterALeafNode = filterA.ToLeafFilterNode(); var invertedFilterA = filterALeafNode.Invert(); var filterB = new CharFilter('B'); var filterBLeafNode = filterB.ToLeafFilterNode(); var invertedFilterB = filterBLeafNode.Invert(); var sut = FilterNodeComparer <CharFilter> .Default; var result = sut.Compare(invertedFilterA, invertedFilterB); Assert.Equal(-1, result); var oppositeResult = sut.Compare(invertedFilterB, invertedFilterA); Assert.Equal(1, oppositeResult); }