diff --git a/Source/Mockolate/Setup/Callback.cs b/Source/Mockolate/Setup/Callback.cs index 538a93ff..b036cadc 100644 --- a/Source/Mockolate/Setup/Callback.cs +++ b/Source/Mockolate/Setup/Callback.cs @@ -108,48 +108,42 @@ public class Callback(TDelegate @delegate) : Callback where TDelegate /// public bool Invoke(bool wasInvoked, ref int index, Action callback) { - if (IsActive(_matchingCount) && CheckInvocations(_invocationCount)) + if (!IsActive(_matchingCount) || !CheckInvocations(_invocationCount) || !CheckMatching(_forIterationCount)) { - if (CheckMatching(_forIterationCount)) + _invocationCount++; + return false; + } + + _invocationCount++; + + if (RunInParallel) + { + if (!wasInvoked) { - _invocationCount++; - - if (RunInParallel) - { - if (!wasInvoked) - { - Interlocked.Increment(ref index); - } - - _forIterationCount++; - _matchingCount++; - callback(_invocationCount - 1, @delegate); - } - else if (!wasInvoked) - { - if (!HasForSpecified || !CheckMatching(_forIterationCount + 1)) - { - Interlocked.Increment(ref index); - _forIterationCount = 0; - } - else - { - _forIterationCount++; - } - - _matchingCount++; - callback(_invocationCount - 1, @delegate); - } - - return !RunInParallel; + Interlocked.Increment(ref index); } _forIterationCount++; _matchingCount++; + callback(_invocationCount - 1, @delegate); + } + else if (!wasInvoked) + { + if (!HasForSpecified || !CheckMatching(_forIterationCount + 1)) + { + Interlocked.Increment(ref index); + _forIterationCount = 0; + } + else + { + _forIterationCount++; + } + + _matchingCount++; + callback(_invocationCount - 1, @delegate); } - _invocationCount++; - return false; + return !RunInParallel; } #pragma warning restore S3776 // Cognitive Complexity of methods should not be too high @@ -158,33 +152,27 @@ public bool Invoke(bool wasInvoked, ref int index, Action callba /// public bool Invoke(ref int index, Action callback) { - if (IsActive(_matchingCount) && CheckInvocations(_invocationCount)) + if (!IsActive(_matchingCount) || !CheckInvocations(_invocationCount) || !CheckMatching(_forIterationCount)) { - if (CheckMatching(_forIterationCount)) - { - if (!HasForSpecified || !CheckMatching(_forIterationCount + 1)) - { - Interlocked.Increment(ref index); - _forIterationCount = 0; - } - else - { - _forIterationCount++; - } - - _invocationCount++; - _matchingCount++; - callback(_invocationCount - 1, @delegate); - return true; - } + _invocationCount++; + Interlocked.Increment(ref index); + return false; + } + if (!HasForSpecified || !CheckMatching(_forIterationCount + 1)) + { + Interlocked.Increment(ref index); + _forIterationCount = 0; + } + else + { _forIterationCount++; - _matchingCount++; } _invocationCount++; - Interlocked.Increment(ref index); - return false; + _matchingCount++; + callback(_invocationCount - 1, @delegate); + return true; } /// @@ -193,33 +181,27 @@ public bool Invoke(ref int index, Action callback) public bool Invoke(ref int index, Func callback, [NotNullWhen(true)] out TReturn? returnValue) { - if (IsActive(_matchingCount) && CheckInvocations(_invocationCount)) + if (!IsActive(_matchingCount) || !CheckInvocations(_invocationCount) || !CheckMatching(_forIterationCount)) { - if (CheckMatching(_forIterationCount)) - { - if (!HasForSpecified || !CheckMatching(_forIterationCount + 1)) - { - Interlocked.Increment(ref index); - _forIterationCount = 0; - } - else - { - _forIterationCount++; - } - - _invocationCount++; - _matchingCount++; - returnValue = callback(_invocationCount - 1, @delegate)!; - return true; - } + _invocationCount++; + returnValue = default; + Interlocked.Increment(ref index); + return false; + } + if (!HasForSpecified || !CheckMatching(_forIterationCount + 1)) + { + Interlocked.Increment(ref index); + _forIterationCount = 0; + } + else + { _forIterationCount++; - _matchingCount++; } _invocationCount++; - returnValue = default; - Interlocked.Increment(ref index); - return false; + _matchingCount++; + returnValue = callback(_invocationCount - 1, @delegate)!; + return true; } } diff --git a/Tests/Mockolate.Internal.Tests/CallbackTests.cs b/Tests/Mockolate.Internal.Tests/CallbackTests.cs index 37d66f29..eabf9482 100644 --- a/Tests/Mockolate.Internal.Tests/CallbackTests.cs +++ b/Tests/Mockolate.Internal.Tests/CallbackTests.cs @@ -47,6 +47,46 @@ public async Task ShouldIncrementIndexOnceWhenCallbackIsExhausted( await That(indexValues).IsEqualTo(expectResult); } + [Theory] + [InlineData(2, 2, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2)] + [InlineData(2, 3, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3)] + public async Task ShouldIncrementIndexWheneverForIsExhausted( + int @for, int only, params int[] expectResult) + { + bool wasInvoked = false; + List indexValues = []; + Callback sut = new(() => { }); + sut.For(@for); + sut.Only(only); + + int index = 0; + for (int iteration = 1; iteration <= 10; iteration++) + { + sut.Invoke(wasInvoked, ref index, (_, _) => { }); + indexValues.Add(index); + } + + await That(indexValues).IsEqualTo(expectResult); + } + + [Fact] + public async Task ShouldLimitExecutionWhenRunningInParallel() + { + bool wasInvoked = false; + List values = []; + Callback sut = new(() => { }); + sut.Only(2); + sut.InParallel(); + + int index = 0; + for (int i = 0; i < 5; i++) + { + sut.Invoke(wasInvoked, ref index, (v, _) => values.Add(v)); + } + + await That(values).IsEqualTo([0, 1,]); + } + [Fact] public async Task WhenCheck_ShouldOnlyBeCalledWhenOnlyLimitIsNotReached() {