public static IExampleSpace <TResult> MergeInternal <T, TResult>(
                List <IExampleSpace <T> > exampleSpaces,
                Func <List <T>, TResult> mergeValues,
                ShrinkFunc <List <IExampleSpace <T> > > shrinkExampleSpaces,
                MeasureFunc <List <IExampleSpace <T> > > measureMerge,
                ImmutableHashSet <ExampleId> encounteredIds,
                bool enableSmallestExampleSpacesOptimization,
                bool isRoot)
            {
                IExampleSpace <TResult> GenerateNextExampleSpace(IEnumerable <IExampleSpace <T> > exampleSpaces, ImmutableHashSet <ExampleId> encounteredIds)
                {
                    return(MergeInternal(
                               exampleSpaces.ToList(),
                               mergeValues,
                               shrinkExampleSpaces,
                               measureMerge,
                               encounteredIds,
                               enableSmallestExampleSpacesOptimization,
                               false));
                }

                var mergedId = exampleSpaces.Aggregate(
                    ExampleId.Primitive(exampleSpaces.Count()),
                    (acc, curr) => ExampleId.Combine(acc, curr.Current.Id));

                var mergedValue = mergeValues(exampleSpaces.Select(es => es.Current.Value).ToList());

                var mergedDistance = measureMerge(exampleSpaces);

                var current = new Example <TResult>(
                    mergedId,
                    mergedValue,
                    mergedDistance);

                var smallestExampleSpacesShrink = enableSmallestExampleSpacesOptimization && isRoot && exampleSpaces.Any(exampleSpace => exampleSpace.Subspace.Any())
                    ? exampleSpaces
                                                  .Select(exampleSpace =>
                {
                    var smallestExampleSpace = exampleSpace.Subspace.FirstOrDefault() ?? exampleSpace;
                    return(smallestExampleSpace);
                })
                                                  .ToList()
                    : null;

                var exampleSpaceCullingShrinks = shrinkExampleSpaces(exampleSpaces);

                var subspaceMergingShrinks = exampleSpaces
                                             .Select((exampleSpace, index) => LiftAndInsertSubspace(exampleSpaces, exampleSpace.Subspace, index))
                                             .SelectMany(exampleSpaces => exampleSpaces);

                var shrinks = TraverseUnencountered(
                    Enumerable.Concat(
                        smallestExampleSpacesShrink == null ? Enumerable.Empty <List <IExampleSpace <T> > >() : new[] { smallestExampleSpacesShrink }.AsEnumerable(),
                        Enumerable.Concat(exampleSpaceCullingShrinks, subspaceMergingShrinks)),
                    encounteredIds,
                    GenerateNextExampleSpace);

                return(new ExampleSpace <TResult>(current, shrinks));
            }
Beispiel #2
0
        public void Examples(long value, long target, long[] expectedShrinks)
        {
            var func = ShrinkFunc.Towards(target);

            var shrinks = func(value);

            shrinks.Should().BeEquivalentTo(expectedShrinks);
        }
        public void Examples(string value, int k, string expectedShrinksDelimited)
        {
            var func = ShrinkFunc.OtherCombinations <char>(k);

            var shrinks = func(value.ToList()).Select(chars => new string(chars.ToArray()));

            shrinks.Should().BeEquivalentTo(expectedShrinksDelimited.Split(","));
        }
Beispiel #4
0
        public IGen <Test> IfValueEqualsTarget_ItWillNotShrink() =>
        from value in Gen.Int32().Select(x => (long)x)
        select Property.ForThese(() =>
        {
            var func = ShrinkFunc.Towards(value);

            var shrinks = func(value);

            shrinks.Should().BeEmpty();
        });
Beispiel #5
0
        public IGen <Test> IfListLengthIsLessThanDoubleMinLength_ItWillNotShrink() =>
        from minLength in TestGen.MinLength(minMinLength: 1)
        from list in DomainGen.AnyList().WithCountLessThan(minLength * 2)
        select Property.ForThese(() =>
        {
            var func = ShrinkFunc.Bisect <object>(minLength);

            var shrinks = func(list.ToList());

            shrinks.Should().BeEmpty();
        });
Beispiel #6
0
        public IGen <Test> IfListHasOneElement_ItWillNotShrink() =>
        from minLength in TestGen.MinLength()
        from list in DomainGen.AnyList().WithCount(1)
        select Property.ForThese(() =>
        {
            var func = ShrinkFunc.Bisect <object>(minLength);

            var shrinks = func(list.ToList());

            shrinks.Should().BeEmpty();
        });
Beispiel #7
0
        public IGen <Test> ItWillProduceDistinctShrinks() =>
        from minLength in TestGen.MinLength()
        from list in DomainGen.AnyList().WithCountGreaterThan(minLength)
        select Property.ForThese(() =>
        {
            var func = ShrinkFunc.DropOne <object>(minLength);

            var shrinks = func(list.ToList());

            shrinks.Should().OnlyHaveUniqueItems();
        });
Beispiel #8
0
        public IGen <Test> IfListIsOrdered_ItWillNotShrink() =>
        from keySelector in Gen.Function <int, int>(Gen.Int32()).NoShrink()
        from list in Gen.Int32().ListOf().Select(l => l.OrderBy(keySelector))
        select Property.ForThese(() =>
        {
            var func = ShrinkFunc.Order(keySelector);

            var shrinks = func(list.ToList());

            shrinks.Should().BeEmpty();
        });
Beispiel #9
0
        public IGen <Test> ItWillProduceDistinctShrinks() =>
        from value in Gen.Int32().Select(x => (long)x)
        from target in Gen.Int32().Select(x => (long)x)
        select Property.ForThese(() =>
        {
            var func = ShrinkFunc.Towards(target);

            var shrinks = func(value);

            shrinks.Should().OnlyHaveUniqueItems();
        });
Beispiel #10
0
        public IGen <Test> ItWillProducesShrinksThatCanRecreateTheOriginalList() =>
        from minLength in TestGen.MinLength()
        from list in DomainGen.AnyList().WithCountGreaterThanEqual((minLength + 1) * 2)
        select Property.ForThese(() =>
        {
            var func = ShrinkFunc.Bisect <object>(minLength);

            var shrinks = func(list.ToList());

            shrinks.SelectMany(x => x).Should().BeEquivalentTo(list.ToList());
        });
        public IGen <Test> IfKIsOne_ItProducesAListOfEachSingleElement() =>
        from list in DomainGen.AnyList().WithCountGreaterThanEqual(2)
        select Property.ForThese(() =>
        {
            var func = ShrinkFunc.OtherCombinations <object>(1);

            var shrinks = func(list.ToList());

            shrinks.Should().HaveCount(list.Count);
            shrinks.SelectMany(x => x).Should().BeEquivalentTo(list);
        });
Beispiel #12
0
        public IGen <Test> ItReflectsAroundZero() =>
        from value in Gen.Int32().GreaterThanEqual(0).Select(x => (long)x)
        select Property.ForThese(() =>
        {
            var func = ShrinkFunc.Towards(0L);

            var shrinks          = func(value);
            var shrinksReflected = func(-value).Select(shrink => - shrink);

            shrinks.Should().BeEquivalentTo(shrinksReflected);
        });
        public IGen <Test> IfListCountIsGreaterThanK_ItWillShrink() =>
        from k in Gen.Int32().Between(1, 20)
        from list in DomainGen.AnyList().WithCountGreaterThan(k)
        select Property.ForThese(() =>
        {
            var func = ShrinkFunc.OtherCombinations <object>(k);

            var shrinks = func(list.ToList());

            shrinks.Should().NotBeEmpty();
        });
Beispiel #14
0
        public IGen <Test> ItWillNotProduceAShrinkEquallingTheValue() =>
        from value in Gen.Int32().Select(x => (long)x)
        from target in Gen.Int32().Select(x => (long)x)
        select Property.ForThese(() =>
        {
            var func = ShrinkFunc.Towards(target);

            var shrinks = func(value);

            shrinks.Should().NotContain(value);
        });
Beispiel #15
0
        private static ShrinkFunc <List <IExampleSpace <T> > > ShrinkTowardsLength(int length)
        {
            // If the value type is a collection, that is, this generator is building a "collection of collections",
            // it is "less complex" to order the inner collections by descending length. It also lets us find the
            // minimal shrink a lot more efficiently in some examples,
            // e.g. https://github.com/jlink/shrinking-challenge/blob/main/challenges/large_union_list.md

            return(ShrinkFunc.TowardsCountOptimized <IExampleSpace <T>, decimal>(length, exampleSpace =>
            {
                return -exampleSpace.Current.Distance;
            }));
        }
Beispiel #16
0
 /// <summary>
 /// Creates an example space by recursively applying a shrinking function to the root value.
 /// </summary>
 /// <typeparam name="T">The type of the example's value.</typeparam>
 /// <param name="rootValue"></param>
 /// <param name="shrink"></param>
 /// <param name="measure"></param>
 /// <param name="identify"></param>
 /// <returns></returns>
 public static IExampleSpace <T> Unfold <T>(
     T rootValue,
     ShrinkFunc <T> shrink,
     MeasureFunc <T> measure,
     IdentifyFunc <T> identify)
 {
     return(Unfold(
                rootValue,
                ShrinkFunc.WithoutContext(shrink),
                measure,
                identify));
 }
Beispiel #17
0
        public IGen <Test> ItWillProduceTwoShrinksOfSimilarLengths() =>
        from minLength in TestGen.MinLength()
        from list in DomainGen.AnyList().WithCountGreaterThanEqual((minLength + 1) * 2)
        select Property.ForThese(() =>
        {
            var func = ShrinkFunc.Bisect <object>(minLength);

            var shrinks = func(list.ToList());

            shrinks.Should().HaveCount(2);
            shrinks.First().Count.Should().BeCloseTo(shrinks.Skip(1).Single().Count, 1);
        });
Beispiel #18
0
        public IGen <Test> ItWillProduceAShrinkEquallingTheTargetFirst() =>
        from value in Gen.Int32().Select(x => (long)x)
        from target in Gen.Int32().Select(x => (long)x)
            where value != target
        select Property.ForThese(() =>
        {
            var func = ShrinkFunc.Towards(target);

            var shrinks = func(value);

            shrinks.First().Should().Be(target);
        });
Beispiel #19
0
        public IGen <Test> ItWillProduceShrinksBetweenTheValueAndTarget() =>
        from value in Gen.Int32().Select(x => (long)x)
        from target in Gen.Int32().Select(x => (long)x)
            where value < target
        select Property.ForThese(() =>
        {
            var func = ShrinkFunc.Towards(target);

            var shrinks = func(value);

            shrinks.Should().NotBeEmpty();
            shrinks.ToList().ForEach(shrink => shrink.Should().BeInRange(value, target));
        });
Beispiel #20
0
        public IGen <Test> ItWillProduceAShrinkForEachElementInTheList() =>
        from minLength in TestGen.MinLength()
        from list in DomainGen.AnyList().WithCountGreaterThan(minLength)
        select Property.ForThese(() =>
        {
            var func = ShrinkFunc.DropOne <object>(minLength);

            var shrinks = func(list.ToList());

            shrinks.Should()
            .NotBeEmpty().And
            .OnlyContain(shrink => shrink.Count == list.Count - 1);
        });
Beispiel #21
0
        public IGen <Test> ItWillNotProduceShrinksLessThanMinimumLength() =>
        from minLength in TestGen.MinLength()
        from list in DomainGen.AnyList().WithCountGreaterThanEqual((minLength + 1) * 2)
        select Property.ForThese(() =>
        {
            var func = ShrinkFunc.Bisect <object>(minLength);

            var shrinks = func(list.ToList());

            shrinks.Should()
            .NotBeEmpty().And
            .OnlyContain(shrink => shrink.Count >= minLength);
        });
 public static IExampleSpace <TResult> Merge <T, TResult>(
     List <IExampleSpace <T> > exampleSpaces,
     Func <List <T>, TResult> mergeValues,
     ShrinkFunc <List <IExampleSpace <T> > > shrinkExampleSpaces,
     MeasureFunc <List <IExampleSpace <T> > > measureMerge,
     bool enableSmallestExampleSpacesOptimization) =>
 MergeHelpers.MergeInternal(
     exampleSpaces,
     mergeValues,
     shrinkExampleSpaces,
     measureMerge,
     ImmutableHashSet.Create <ExampleId>(),
     enableSmallestExampleSpacesOptimization,
     true);
Beispiel #23
0
        public IGen <Test> IfListIsNotOrdered_ItWillProduceASingleOrderedShrink() =>
        from keySelector in Gen.Function <int, int>(Gen.Int32()).NoShrink()
        from list in Gen.Int32().ListOf()
            where list.SequenceEqual(list.OrderBy(keySelector)) == false
        select Property.ForThese(() =>
        {
            var func = ShrinkFunc.Order(keySelector);

            var shrinks = func(list.ToList());

            shrinks.Should()
            .ContainSingle()
            .Subject.Should().BeEquivalentTo(list.OrderBy(keySelector));
        });
        public void Snapshots_TowardsCountOptimized()
        {
            var result = _fixture
                         .Scenarios
                         .Select(scenario =>
            {
                var func = ShrinkFunc.TowardsCountOptimized <int, int>(scenario.MinLength, x => x);

                var shrinks = func(scenario.List);

                return(new
                {
                    Input = scenario,
                    Output = shrinks
                });
            })
                         .ToList();

            Snapshot.Match(result);
        }
Beispiel #25
0
 public NoopContextualShrinker(ShrinkFunc <T> shrinker)
 {
     _shrinker = shrinker;
 }
Beispiel #26
0
 public static ShrinkFunc <TResult> Map <T, TResult>(
     this ShrinkFunc <T> shrink,
     Func <T, TResult> forwardMapper,
     Func <TResult, T> reverseMapper) =>
 value => shrink(reverseMapper(value)).Select(forwardMapper);