Autofixture: рдЬреЗрдирд░реЗрд╢рдирдбреЗрдкреНрде рдмрд┐рд╣реЗрд╡рд┐рдпрд░ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╕реНрддрд╛рд╡ред

рдХреЛ рдирд┐рд░реНрдорд┐рдд 1 рдордИ 2018  ┬╖  12рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: AutoFixture/AutoFixture

рдпрд╣рд╛рдБ рдПрдХ рдкреАрдврд╝реА рдЧрд╣рд░рд╛рдИ рд╕реАрдордХ рд╡реНрдпрд╡рд╣рд╛рд░ рдкреНрд░рд╕реНрддрд╛рд╡ рд╣реИред

рд╕реНрдерд┐рд░рддрд╛ред рд╡реНрдпрд╡рд╣рд╛рд░ред рдЬреЛрдбрд╝реЗрдВ (рдирдИ рдкреАрдврд╝реА рдЧрд╣рд░рд╛рдИ рд╡реНрдпрд╡рд╣рд╛рд░ (2));

рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП ComposeIfMultiple рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдкрдбрд╝рд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЖрдВрддрд░рд┐рдХ рд╣реИред

```рд╕реА#
рдкрдмреНрд▓рд┐рдХ рдХреНрд▓рд╛рд╕ рдЬрдирд░реЗрд╢рдирдбреЗрдкреНрде рдмрд┐рд╣реЗрд╡рд┐рдпрд░: ISpecimenBuilderTransformation
{
рдирд┐рдЬреА рдХреЙрдиреНрд╕ int DefaultGenerationDepth = 1;
рдирд┐рдЬреА рд░реАрдбреЛрдирд▓реА рдЗрдВрдЯ рдЬрдирд░реЗрд╢рдирдбреЗрдкреНрде;

public GenerationDepthBehavior() : this(DefaultGenerationDepth)
{
}

public GenerationDepthBehavior(int generationDepth)
{
    if (generationDepth < 1)
        throw new ArgumentOutOfRangeException(nameof(generationDepth), "Generation depth must be greater than 0.");

    this.generationDepth = generationDepth;
}


public ISpecimenBuilderNode Transform(ISpecimenBuilder builder)
{
    if (builder == null) throw new ArgumentNullException(nameof(builder));

    return new GenerationDepthGuard(builder, new GenerationDepthHandler(), this.generationDepth);
}

}

рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ IGenerationDepthHandler
{

object HandleGenerationDepthLimitRequest(object request, IEnumerable<object> recordedRequests, int depth);

}

рдкрдмреНрд▓рд┐рдХ рдХреНрд▓рд╛рд╕ DepthSeededRequest : SeededRequest
{
рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдЕрдВрддрд░ рдЧрд╣рд░рд╛рдИ { рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ; }
public DepthSeededRequest(рдСрдмреНрдЬреЗрдХреНрдЯ рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ, рдСрдмреНрдЬреЗрдХреНрдЯ рд╕реАрдб, рдЗрдВрдЯ рдбреЗрдкреНрде): рдмреЗрд╕ (рдЕрдиреБрд░реЛрдз, рдмреАрдЬ)
{
рдЧрд╣рд░рд╛рдИ = рдЧрд╣рд░рд╛рдИ;
}
}

рдкрдмреНрд▓рд┐рдХ рдХреНрд▓рд╛рд╕ рдЬрдирд░реЗрд╢рдирдбреЗрдкреНрдердЧрд╛рд░реНрдб: ISpecimenBuilderNode
{
рдирд┐рдЬреА рдкрдардиреАрдп рдереНрд░реЗрдбрд▓реЛрдХрд▓> рдЕрдиреБрд░реЛрдз ByThread
= рдирдпрд╛ рдереНрд░реЗрдбрд▓реЛрдХрд▓>(() => рдирдпрд╛ рд╕реНрдЯреИрдХ());

private Stack<DepthSeededRequest> GetMonitoredRequestsForCurrentThread() => this.requestsByThread.Value;


public GenerationDepthGuard(ISpecimenBuilder builder)
    : this(builder, EqualityComparer<object>.Default)
{
}

public GenerationDepthGuard(
    ISpecimenBuilder builder,
    IGenerationDepthHandler depthHandler)
    : this(
        builder,
        depthHandler,
        EqualityComparer<object>.Default,
        1)
{
}

public GenerationDepthGuard(
    ISpecimenBuilder builder,
    IGenerationDepthHandler depthHandler,
    int generationDepth)
    : this(
        builder,
        depthHandler,
        EqualityComparer<object>.Default,
        generationDepth)
{
}


public GenerationDepthGuard(ISpecimenBuilder builder, IEqualityComparer comparer)
{
    this.Builder = builder ?? throw new ArgumentNullException(nameof(builder));
    this.Comparer = comparer ?? throw new ArgumentNullException(nameof(comparer));
    this.GenerationDepth = 1;
}


public GenerationDepthGuard(
    ISpecimenBuilder builder,
    IGenerationDepthHandler depthHandler,
    IEqualityComparer comparer)
    : this(
    builder,
    depthHandler,
    comparer,
    1)
{
}

public GenerationDepthGuard(
    ISpecimenBuilder builder,
    IGenerationDepthHandler depthHandler,
    IEqualityComparer comparer,
    int generationDepth)
{
    if (builder == null) throw new ArgumentNullException(nameof(builder));
    if (depthHandler == null) throw new ArgumentNullException(nameof(depthHandler));
    if (comparer == null) throw new ArgumentNullException(nameof(comparer));
    if (generationDepth < 1)
        throw new ArgumentOutOfRangeException(nameof(generationDepth), "Generation depth must be greater than 0.");

    this.Builder = builder;
    this.GenerationDepthHandler = depthHandler;
    this.Comparer = comparer;
    this.GenerationDepth = generationDepth;
}


public ISpecimenBuilder Builder { get; }

public IGenerationDepthHandler GenerationDepthHandler { get; }

public int GenerationDepth { get; }

public int CurrentDepth { get; }

public IEqualityComparer Comparer { get; }

protected IEnumerable RecordedRequests => this.GetMonitoredRequestsForCurrentThread();

public virtual object HandleGenerationDepthLimitRequest(object request, int currentDepth)
{
    return this.GenerationDepthHandler.HandleGenerationDepthLimitRequest(
        request,
        this.GetMonitoredRequestsForCurrentThread(), currentDepth);
}

public object Create(object request, ISpecimenContext context)
{
    if (request is SeededRequest)
    {
        int currentDepth = -1;

        var requestsForCurrentThread = this.GetMonitoredRequestsForCurrentThread();

        if (requestsForCurrentThread.Count > 0)
        {
            currentDepth = requestsForCurrentThread.Max(x => x.Depth) + 1;
        }

        DepthSeededRequest depthRequest = new DepthSeededRequest(((SeededRequest)request).Request, ((SeededRequest)request).Seed, currentDepth);

        if (depthRequest.Depth >= this.GenerationDepth)
        {
            return HandleGenerationDepthLimitRequest(request, depthRequest.Depth);
        }

        requestsForCurrentThread.Push(depthRequest);
        try
        {
            return this.Builder.Create(request, context);
        }
        finally
        {
            requestsForCurrentThread.Pop();
        }
    }
    else
    {
        return this.Builder.Create(request, context);
    }
}

public virtual ISpecimenBuilderNode Compose(
    IEnumerable<ISpecimenBuilder> builders)
{
    var composedBuilder = ComposeIfMultiple(
        builders);
    return new GenerationDepthGuard(
        composedBuilder,
        this.GenerationDepthHandler,
        this.Comparer,
        this.GenerationDepth);
}

internal static ISpecimenBuilder ComposeIfMultiple(IEnumerable<ISpecimenBuilder> builders)
{
    ISpecimenBuilder singleItem = null;
    List<ISpecimenBuilder> multipleItems = null;
    bool hasItems = false;

    using (var enumerator = builders.GetEnumerator())
    {
        if (enumerator.MoveNext())
        {
            singleItem = enumerator.Current;
            hasItems = true;

            while (enumerator.MoveNext())
            {
                if (multipleItems == null)
                {
                    multipleItems = new List<ISpecimenBuilder> { singleItem };
                }

                multipleItems.Add(enumerator.Current);
            }
        }
    }

    if (!hasItems)
    {
        return new CompositeSpecimenBuilder();
    }

    if (multipleItems == null)
    {
        return singleItem;
    }

    return new CompositeSpecimenBuilder(multipleItems);
}

public virtual IEnumerator<ISpecimenBuilder> GetEnumerator()
{
    yield return this.Builder;
}

IEnumerator IEnumerable.GetEnumerator()
{
    return this.GetEnumerator();
}

}

рдкрдмреНрд▓рд┐рдХ рдХреНрд▓рд╛рд╕ рдЬрдирд░реЗрд╢рдирдбреЗрдкреНрдерд╣реИрдВрдбрд▓рд░: IGenerationDepthHandler
{
рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╡рд╕реНрддреБ HandleGenerationDepthLimitRequest(
рд╡рд╕реНрддреБ рдЕрдиреБрд░реЛрдз,
IEnumerableрд░рд┐рдХреЙрд░реНрдб рдХрд┐рдП рдЧрдП рдЕрдиреБрд░реЛрдз, рдЗрдВрдЯ рдбреЗрдкреНрде)
{
рдирдпрд╛ OmitSpecimen рд▓реМрдЯрд╛рдПрдВ ();
}
}
```

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

@ malylemire1 рдХреНрдпрд╛ рдЖрдк рдареАрдХ рд░рд╣реЗрдВрдЧреЗ рдпрджрд┐ рд╣рдо рдЗрд╕реЗ рдЕрднреА рдХреЗ рд▓рд┐рдП рд╕реНрдердЧрд┐рдд рдХрд░ рджреЗрдВ рдФрд░ рдЗрд╕реЗ рдмрд╛рдж рдореЗрдВ рддрднреА рд▓рд╛рдЧреВ рдХрд░реЗрдВ рдЬрдм рд╣рдореЗрдВ рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЕрдиреБрд░реЛрдз рджрд┐рдЦрд╛рдИ рджреЗрдВ?

рдореБрдЭреЗ рдЦреЗрдж рд╣реИ рдХрд┐ рд╣рдо рд╣рд░ рд╡рд╛рдВрдЫрд┐рдд рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рдХреЛрд░ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдкреНрд░рджрд╛рди рдХреА рдЧрдИ рд╕реБрд╡рд┐рдзрд╛ рдФрд░ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдпрд╣рд╛рдВ рдмрдирд╛рдП рдЧрдП рдХреЛрдб рдХреА рдорд╛рддреНрд░рд╛ рдХреЗ рдмреАрдЪ рд╕рдВрддреБрд▓рди рдмрдирд╛рдП рд░рдЦрдирд╛ рдереЛрдбрд╝рд╛ рдХрдард┐рди рд╣реИред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЗ рд╕рдорд╛рдзрд╛рди рдореЗрдВ рдЗрд╕ рддрджрд░реНрде рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрдкрдХреЗ рд▓рд┐рдП рдХреЛрдИ рдмрдбрд╝реА рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реЛрдЧреА, рдЗрд╕рд▓рд┐рдП рдЖрдк рдЕрд╡рд░реБрджреНрдз рдирд╣реАрдВ рд╣реИрдВред

рдЖрдкрдХреЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд▓рд┐рдП рдлрд┐рд░ рд╕реЗ рдзрдиреНрдпрд╡рд╛рдж!

рд╕рднреА 12 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рд╣реИрд▓реЛ, рд╡рд┐рдЪрд╛рд░ рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж! :+1:

рдХреНрдпрд╛ рдЖрдк рдХреГрдкрдпрд╛ рдЗрд╕ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рдкреАрдЫреЗ рдХреЗ рддрд░реНрдХ рдХрд╛ рд╡рд░реНрдгрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рдХреНрдпрд╛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреЛрдИ рд╡рд┐рд╢реЗрд╖ рдкрд░рд┐рджреГрд╢реНрдп рд╣реИ рдЬрд╣рд╛рдВ рдЖрдкрдХреЛ рдпрд╣ рдЙрдкрдпреЛрдЧреА рд▓рдЧрд╛?

рд╣рд╛рдп, рдореИрдВ рдЗрд╕реЗ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдУрдЖрд░рдПрдо рдПрдВрдЯрд╛рдЗрдЯреНрд╕ рдпрд╛ рдмрд╛рд╣рд░реА рдПрдкреАрдЖрдИ рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ рдЬрд╣рд╛рдВ рдЧрд╣рд░рд╛рдИ рдЕрдирд┐рд╢реНрдЪрд┐рдд рдХрд╛рд▓ рддрдХ рдлреИрд▓ рд╕рдХрддреА рд╣реИ рд▓реЗрдХрд┐рди рд░рд┐рдХрд░реНрд╕рд┐рд╡ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред
рдореИрдВ рдпреВрдирд┐рдЯ рдЯреЗрд╕реНрдЯ, рдЗрдВрдЯреАрдЧреНрд░реЗрд╢рди рдЯреЗрд╕реНрдЯ рдФрд░ рдлрдВрдХреНрд╢рдирд▓ рдЯреЗрд╕реНрдЯ рдХреЗ рд▓рд┐рдП рдСрдЯреЛрдлрд┐рдХреНрдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред рдХреЛрд░ рдПрдВрдЯрд░рдкреНрд░рд╛рдЗрдЬ рдлреНрд░реЗрдорд╡рд░реНрдХ рдлрдВрдХреНрд╢рдВрд╕ рдХреЗ рд▓рд┐рдП рдпреВрдирд┐рдЯ рдЯреЗрд╕реНрдЯред рд░рд┐рдкреЛрдЬрд┐рдЯрд░реА рдкреИрдЯрд░реНрди рдФрд░ рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛рдмреЗрд╕ рддрдХ рдкрд╣реБрдВрдЪ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХреА рдЬрдЯрд┐рд▓ рдЗрдХрд╛рдЗрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдгред рд╕рдВрдкреВрд░реНрдг рдПрдкреНрд▓рд┐рдХреЗрд╢рди рддрдХ рдкрд╣реБрдВрдЪ рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкрд░реАрдХреНрд╖рдгред

рдореИрдВрдиреЗ рдЗрд╕реЗ рд╕реАрдзреЗ AutoMoqDataAttribute рдкрд░ рд░рдЦрд╛ рд╣реИ

```рд╕реА#
рдкрдмреНрд▓рд┐рдХ рдХреНрд▓рд╛рд╕ AutoMoqDataAttribute: AutoDataAttribute
{
///


/// рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ред
///

/// рдЕрд╕реАрдорд┐рдд рдкреАрдврд╝реА рдХреА рдЧрд╣рд░рд╛рдИ рдХреЗ рд▓рд┐рдП рдбрд┐рдлрд╝реЙрд▓реНрдЯ 0ред
рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ AutoMoqDataAttribute (рдЗрдВрдЯ рдЬрдирд░реЗрд╢рди рдбреЗрдкреНрде = 0)
: рдЖрдзрд╛рд░ (() =>
{
IFixture рд╕реНрдерд┐рд░рддрд╛ = рдирдИ рд╕реНрдерд┐рд░рддрд╛ ()ред рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░реЗрдВ (рдирдпрд╛ AutoMoq Customization ());

        fixture.Behaviors.OfType<ThrowingRecursionBehavior>().ToList()
                .ForEach(b => fixture.Behaviors.Remove(b));

        fixture.Behaviors.Add(new OmitOnRecursionBehavior());

        if (generationDepth > 0)
        {
            fixture.Behaviors.Add(new GenerationDepthBehavior(generationDepth));
        }

        return fixture;
    })
{
}

}
```

рдореИрдВ ComposeIfMultiple рдХреЛ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдХрд░рдиреЗ рдХрд╛ рднреА рд╕реБрдЭрд╛рд╡ рджреВрдВрдЧрд╛ред рдпрд╣ рдХрд╕реНрдЯрдо рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛ рджреЗрдЧрд╛ред

рдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдВ рдХрд┐ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреНрдпрд╛ рдХрд░рддрд╛ рд╣реИ, рдореБрдЦреНрдп рдкреНрд░рд╢реНрди рдЙрджреНрджреЗрд╢реНрдп рдФрд░ рдкрд░рд┐рджреГрд╢реНрдп рд╣реИред

рд╣рд╛рдп, рдореИрдВ рдЗрд╕реЗ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдУрдЖрд░рдПрдо рдПрдВрдЯрд╛рдЗрдЯреНрд╕ рдпрд╛ рдмрд╛рд╣рд░реА рдПрдкреАрдЖрдИ рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ рдЬрд╣рд╛рдВ рдЧрд╣рд░рд╛рдИ рдЕрдирд┐рд╢реНрдЪрд┐рдд рдХрд╛рд▓ рддрдХ рдлреИрд▓ рд╕рдХрддреА рд╣реИ рд▓реЗрдХрд┐рди рд░рд┐рдХрд░реНрд╕рд┐рд╡ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред

рдЗрд╕рд▓рд┐рдП, рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛрдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдВ, рдЖрдкрдХрд╛ рдореБрдЦреНрдп рд▓рдХреНрд╖реНрдп рдкреНрд░рджрд░реНрд╢рди рд╣реИред рдХрд╛рд░реНрдпрд╛рддреНрдордХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рд╕рдм рдХреБрдЫ рдареАрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЖрдк рдмрд╕ рдХреБрдЫ рд╕реАрдкреАрдпреВ рдЯрд┐рдХ рдмрдЪрд╛рдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗред

рдпрд╣ рддрдп рдХрд░рдирд╛ рдереЛрдбрд╝рд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ рдХрд┐ рд╣рдо рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд╕рд╛рде рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдпрд╛ рдирд╣реАрдВред рдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрд╣реБрдд рдЧрд╣рд░реЗ рдШреЛрдВрд╕рд▓реЗ рдХреЗ рд╕рд╛рде рдЯрд╛рдЗрдк рдореЙрдбрд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рд╡рд╣рд╛рдВ рдкреНрд░рджрд░реНрд╢рди рдЬреАрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рд╕рд╛рде рдХреБрдЫ рдХрдорд┐рдпрд╛рдВ рднреА рд╣реИрдВ:

  • рдпрд╣ рдЖрдкрдХреЗ рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рдкрд╛рд░рджрд░реНрд╢рд┐рддрд╛ рдХреЛ рддреЛрдбрд╝рддрд╛ рд╣реИред рдЕрдм рдЖрдкрдХреЛ рдкрд░реАрдХреНрд╖рдг рдХреЗ рджреМрд░рд╛рди рд╕рдмрд╕реЗ рдЧрд╣рд░реА рдкрд╣реБрдВрдЪ рд╡рд╛рд▓реА рд╡рд╕реНрддреБ рдХреЗ рд╕реНрддрд░ рдХреЛ рдЬрд╛рдирдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред рдпрджрд┐ рдЖрдк рдмрд╛рдж рдореЗрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдмрджрд▓рддреЗ рд╣реИрдВ, рддреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рдиреЛрдВ рдХреЗ рдХрд╛рд░рдг рдкрд░реАрдХреНрд╖рдг рдЯреВрдЯрдирд╛ рд╢реБрд░реВ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЖрдкрдХреЛ рд╢рд╛рдпрдж рд╕реНрддрд░ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред
  • рдпрд╣ рдкрд░реАрдХреНрд╖рдг рд░рдЦрд░рдЦрд╛рд╡ рдмрдврд╝рд╛рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЕрдм рдЖрдкрдХреЛ рдЗрд╕ рддрдереНрдп рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдЧреНрд░рд╛рдл рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкреНрд░рд╛рд░рдВрдн рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдареАрдХ рд╣реИ рдХрд┐ рдЖрдкрдХреА рдЯреАрдо рдореЗрдВ рдЖрдкрдХреЛ рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдФрд░ рдЖрдк рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╣рдордд рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдореИрдВ рдЗрд╕реЗ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдЙрдкрдпреЛрдЧ рджреЗрдиреЗ рдХрд╛ рддрд░реНрдХ рджреВрдВрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЪреАрдЬреЛрдВ рдХреЛ рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рдХрд░рддрд╛ рд╣реИред

рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╕рдВрднрд╛рд╡рд┐рдд рдкрд░рд┐рджреГрд╢реНрдп рд╣реИрдВ рдФрд░ AutoFixture рдХреЗрд╡рд▓ рд╕рдмрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рд╢рд┐рдк рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддрд╛ рд╣реИред рдЕрдзрд┐рдХ рдЙрдиреНрдирдд рдмрд┐рдЯреНрд╕ рдПрдХреНрд╕реНрдЯреЗрдВрд╕рд┐рдмрд┐рд▓рд┐рдЯреА рдХреНрд╖рдорддрд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рдХрд╡рд░ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдЗрд╕ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓реЗ рдореЗрдВ рдореИрдВ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдпрд╣ рд╕реБрд╡рд┐рдзрд╛ рдЙрддреНрдкрд╛рдж рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдп рдирд╣реАрдВ рд╣реИред рдПрдХ рдЕрдиреНрдп рдмрд┐рдВрджреБ рдпрд╣ рд╣реИ рдХрд┐ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдмрд╣реБрдд рдЫреЛрдЯрд╛ рд╣реИ (рдиреАрдЪреЗ рджреЗрдЦреЗрдВ), рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдг рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдореЗрдВ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред

рдореИрдВ ComposeIfMultiple рдХреЛ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдХрд░рдиреЗ рдХрд╛ рднреА рд╕реБрдЭрд╛рд╡ рджреВрдВрдЧрд╛ред рдпрд╣ рдХрд╕реНрдЯрдо рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛ рджреЗрдЧрд╛ред

рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА # 657 рдкрд░ рдЪрд░реНрдЪрд╛ рдХреА рдЬрд╛ рдЪреБрдХреА рд╣реИред


рд╡реИрд╕реЗ, рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдереЛрдбрд╝рд╛ рд╕рд░рд▓ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдпрджрд┐ рдореБрдЭреЗ рдХреБрдЫ рдпрд╛рдж рдирд╣реАрдВ рдЖ рд░рд╣рд╛ рд╣реИ):
```рд╕реА#
рдкрдмреНрд▓рд┐рдХ рдХреНрд▓рд╛рд╕ рдЬрдирд░реЗрд╢рдирдбреЗрдкреНрде рдмрд┐рд╣реЗрд╡рд┐рдпрд░: рдЖрдИрд╕реНрдкреЗрд╕рд┐рдореЗрдирдмрд┐рд▓реНрдбрд░рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдореЗрд╢рди
{
рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдЕрдВрддрд░ рдЧрд╣рд░рд╛рдИ { рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ; }

public GenerationDepthBehavior(int depth)
{
    Depth = depth;
}

public ISpecimenBuilderNode Transform(ISpecimenBuilder builder)
{
    return new RecursionGuard(builder, new OmitOnRecursionHandler(), new IsSeededRequestComparer(), Depth);
}

private class IsSeededRequestComparer : IEqualityComparer
{
    bool IEqualityComparer.Equals(object x, object y)
    {
        return x is SeededRequest && y is SeededRequest;
    }

    int IEqualityComparer.GetHashCode(object obj)
    {
        return obj is SeededRequest ? 0 : EqualityComparer<object>.Default.GetHashCode(obj);
    }
}

}
```


@moodmosaic рдХреНрдпрд╛ рдЖрдк рдХреГрдкрдпрд╛ рдЕрдкрдиреА рд░рд╛рдп рднреА рд╕рд╛рдЭрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рдореИрдВ

https://github.com/AutoFixture/AutoFixture/issues/1032#issuecomment -385724150 рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рдЙрджрд╛рд╣рд░рдг рдЗрд╕ рддрджрд░реНрде рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкрд╕рдВрджреАрджрд╛ рддрд░реАрдХрд╛ рд╣реИред рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рд╣рдореЗрдВ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдПрд▓реНрдЧреЛрд░рд┐рдердо рдХреЛ рдмрджрд▓рдирд╛ рдЪрд╛рд╣рд┐рдПред


рд╣рд╛рд▓рд╛рдБрдХрд┐, рд╣рдо рдЬрд┐рд╕ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ , рд╡рд╣ рд╣реИ

  • рдПрдХ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдкреАрдЖрд░рдПрдирдЬреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ (рд╡рд░реНрддрдорд╛рди рдПрдХ рд╡рд┐рднрд╛рдЬрд┐рдд рдирд╣реАрдВ рд╣реИ)
  • рдпрд╛рджреГрдЪреНрдЫрд┐рдХрддрд╛ рдкрд░реАрдХреНрд╖рдг рдЬреЛрдбрд╝реЗрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП https://github.com/hedgehogqa/haskell-hedgehog/issues/125 рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдВ)
  • рдорд╛рдирдХ

рдФрд░ рдлрд┐рд░ , рд╣рдо рдЗрд╕ рддрд░рд╣ рдХреЗ рдФрд░ рдЕрдиреБрдХреВрд▓рди рдХрд░рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

@moodmosaic рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕реБрдЭрд╛рд╡ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рд╣реИ, рдмрд▓реНрдХрд┐ GenerationDepthBehavior рдХреЛ AutoFixture рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ (рддрд╛рдХрд┐ рдЖрдк рдЗрд╕реЗ рдорд╛рдВрдЧ рдкрд░ рд╕рдХреНрд╖рдо рдХрд░ рд╕рдХреЗрдВ)ред рддреЛ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдЖрдкрдХреА рдХреНрдпрд╛ рд░рд╛рдп рд╣реИ? :рдЖрдБрдЦ рдорд╛рд░рдирд╛:

@zvirja рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рди рдХрд╛рд░рдгреЛрдВ рд╕реЗ рдирд╣реАрдВ рд╣реИред рдЕрдирд┐рд╢реНрдЪрд┐рддрдХрд╛рд▓реАрди рдкреНрд░рд╕рд╛рд░ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рд╕реНрдореГрддрд┐ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде рд╡рд┐рдлрд▓ рдкрд░реАрдХреНрд╖рдг рд╣реИред

@zvirja , @ malylemire1 , рдЬрдм рддрдХ рдХрд┐ рдпрд╣ рддрджрд░реНрде рд╡реНрдпрд╡рд╣рд╛рд░ рдкрд░рд┐рджреГрд╢реНрдпреЛрдВ рдХреА рдПрдХ рд╡рд┐рд╕реНрддреГрдд рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЛ рд╕рдВрдмреЛрдзрд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЗрд╕реЗ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред


рдореИрдВ рдПрдХ рдПрдорд╕реАрд╡реАрдИ рдирд╣реАрдВ рджреЗрдЦ рд╕рдХрддрд╛, рд▓реЗрдХрд┐рди AFAICT, рд╕рдорд╕реНрдпрд╛рдПрдВ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд-рдкрд░реАрдХреНрд╖рдгреЛрдВ рд╕реЗ рдЖ рд░рд╣реА рд╣реИрдВ рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рд╣реИрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рд╕реАрдорд╛/рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдг)ред

AutoFixture рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдгреЛрдВ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдирд╣реАрдВ рддреЛ рдХреБрдЫ рддрджрд░реНрде рд╡реНрдпрд╡рд╣рд╛рд░ (рдпрд╣рд╛рдБ рджрд┐рдЦрд╛рдП рдЧрдП рдЬреИрд╕рд╛) warranted рд░рд╣реЗ рд╣реИрдВ: +1: рдореИрдВ, рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдХреЛрд░ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИред

@ malylemire1 рдХреНрдпрд╛ рдЖрдк рдареАрдХ рд░рд╣реЗрдВрдЧреЗ рдпрджрд┐ рд╣рдо рдЗрд╕реЗ рдЕрднреА рдХреЗ рд▓рд┐рдП рд╕реНрдердЧрд┐рдд рдХрд░ рджреЗрдВ рдФрд░ рдЗрд╕реЗ рдмрд╛рдж рдореЗрдВ рддрднреА рд▓рд╛рдЧреВ рдХрд░реЗрдВ рдЬрдм рд╣рдореЗрдВ рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЕрдиреБрд░реЛрдз рджрд┐рдЦрд╛рдИ рджреЗрдВ?

рдореБрдЭреЗ рдЦреЗрдж рд╣реИ рдХрд┐ рд╣рдо рд╣рд░ рд╡рд╛рдВрдЫрд┐рдд рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рдХреЛрд░ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдкреНрд░рджрд╛рди рдХреА рдЧрдИ рд╕реБрд╡рд┐рдзрд╛ рдФрд░ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдпрд╣рд╛рдВ рдмрдирд╛рдП рдЧрдП рдХреЛрдб рдХреА рдорд╛рддреНрд░рд╛ рдХреЗ рдмреАрдЪ рд╕рдВрддреБрд▓рди рдмрдирд╛рдП рд░рдЦрдирд╛ рдереЛрдбрд╝рд╛ рдХрдард┐рди рд╣реИред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЗ рд╕рдорд╛рдзрд╛рди рдореЗрдВ рдЗрд╕ рддрджрд░реНрде рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрдкрдХреЗ рд▓рд┐рдП рдХреЛрдИ рдмрдбрд╝реА рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реЛрдЧреА, рдЗрд╕рд▓рд┐рдП рдЖрдк рдЕрд╡рд░реБрджреНрдз рдирд╣реАрдВ рд╣реИрдВред

рдЖрдкрдХреЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд▓рд┐рдП рдлрд┐рд░ рд╕реЗ рдзрдиреНрдпрд╡рд╛рдж!

рд╕рдлрд╛рдИ рдХреЗ рдПрдХ рднрд╛рдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдмрдВрдж рдХрд░рдирд╛ред рд╡рд┐рдЪрд╛рд░ рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд┐рд░ рд╕реЗ рдзрдиреНрдпрд╡рд╛рдж! рдореИрдВ

@ malylemire1 рдореИрдВ 100% рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдХреЛ рд╕рдордЭрддрд╛ рд╣реВрдВред
рдХреНрдпрд╛ рдпрд╣ рдХреБрдЫ рдРрд╕рд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдк рдирдЧреЗрдЯ рдкреИрдХреЗрдЬ рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдХрд░рд╛ рд╕рдХрддреЗ рд╣реИрдВ?

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

tomasaschan picture tomasaschan  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

JoshKeegan picture JoshKeegan  ┬╖  6рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

malylemire1 picture malylemire1  ┬╖  7рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

zvirja picture zvirja  ┬╖  8рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

gtbuchanan picture gtbuchanan  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ