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)); }
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(",")); }
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(); });
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(); });
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(); });
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(); });
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(); });
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(); });
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); });
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(); });
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); });
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; })); }
/// <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)); }
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); });
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); });
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)); });
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); });
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);
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); }
public NoopContextualShrinker(ShrinkFunc <T> shrinker) { _shrinker = shrinker; }
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);