public void Collapse_FilterIsEquivalent()
        {
            var interestingCount = 0;

            while (interestingCount < 10)
            {
                var numSets = _random.Next(1000);

                var strings = Enumerable.Range(1, numSets).Select(_ => _generator.GetRandomString(_random.Next(RandomCharFilterGenerator.Chars.Length)))
                              .ToHashSet();

                const int nodeCount = 10;

                var filter          = _generator.GetRandomFilter(nodeCount);
                var collapsedFilter = filter.Collapse();

                if (filter.Equals(collapsedFilter))
                {
                    // Trivial, ignore.
                    continue;
                }

                var expectedResult = strings.Where(filter.GetPredicate <CharFilter, string>());
                var actualResult   = strings.Where(collapsedFilter.GetPredicate <CharFilter, string>());

                Assert.Equal(expectedResult, actualResult);

                // Also check IsEquivalentTo works, which internally uses Collapse.
                Assert.True(filter.IsEquivalentTo(collapsedFilter));
                Assert.True(collapsedFilter.IsEquivalentTo(filter));

                interestingCount++;
            }
        }
Example #2
0
        public void GetPartial_FiltersSubset()
        {
            bool IsComplex(IFilterNode <CharFilter> filter)
            {
                bool IsComplexInner(IFilterNode <CharFilter> inner, int invertedCount)
                {
                    if (invertedCount > 1)
                    {
                        return(true);
                    }

                    return(inner.Match(
                               combine => combine.Nodes.Any(f => IsComplexInner(f, invertedCount)),
                               invert => IsComplexInner(invert.NodeToInvert, invertedCount + 1),
                               leaf => false));
                }

                return(IsComplexInner(filter, 0));
            }

            var scenarioToCount = new Dictionary <Func <IFilterNode <CharFilter>, bool>, int>
            {
                { f => true, 100 }, // Any scenario
                { IsComplex, 10 },
            };

            while (scenarioToCount.Any(kvp => kvp.Value > 0))
            {
                var numSets = _random.Next(1000);

                var strings = Enumerable.Range(1, numSets)
                              .Select(_ => _generator.GetRandomString(_random.Next(RandomCharFilterGenerator.Chars.Length)))
                              .ToHashSet();

                const int nodeCount = 10;

                var filter = _generator.GetRandomFilter(nodeCount);

                var charsToExclude = Enumerable.Range(0, _random.Next(nodeCount))
                                     .Select(_ => _generator.GetRandomChar())
                                     .ToHashSet();
                var partial = filter.GetPartial(f => !charsToExclude.Contains(f.Character));

                var partialResult = strings.Where(partial.GetPredicate <CharFilter, string>())
                                    .ToHashSet();
                var finalResult = partialResult.Where(filter.GetPredicate <CharFilter, string>())
                                  .ToHashSet();

                if (partialResult.Count == strings.Count || finalResult.Count == partialResult.Count)
                {
                    // Trivial, ignore.
                    continue;
                }

                var originalResult = strings.Where(filter.GetPredicate <CharFilter, string>())
                                     .ToHashSet();

                Assert.Equal(originalResult, finalResult);

                foreach (var kvp in scenarioToCount.ToList())
                {
                    if (kvp.Key(filter))
                    {
                        scenarioToCount[kvp.Key]--;
                    }
                }
            }
        }