diff --git a/Source/Mockolate/Setup/Callback.cs b/Source/Mockolate/Setup/Callback.cs index 9b4ac1ac..2307e5cc 100644 --- a/Source/Mockolate/Setup/Callback.cs +++ b/Source/Mockolate/Setup/Callback.cs @@ -195,7 +195,6 @@ public bool Invoke(ref int index, Func callbac _invocationCount++; _matchingCount++; returnValue = callback(_invocationCount - 1, @delegate)!; - return true; } diff --git a/Tests/Mockolate.Internal.Tests/CallbackTests.cs b/Tests/Mockolate.Internal.Tests/CallbackTests.cs new file mode 100644 index 00000000..f5a48f9c --- /dev/null +++ b/Tests/Mockolate.Internal.Tests/CallbackTests.cs @@ -0,0 +1,90 @@ +using System.Collections.Generic; +using Mockolate.Setup; + +namespace Mockolate.Internal.Tests; + +public class CallbackTests +{ + [Fact] + public async Task Invoke_ShouldIncludeIndexWhenMatching() + { + List values = []; + Callback sut = new(() => { }); + sut.For(2); + sut.When(v => v > 1); + + int index = 0; + for (int i = 0; i < 5; i++) + { + sut.Invoke(ref index, (v, _) => values.Add(v)); + } + + await That(values).IsEqualTo([2, 3,]); + } + + [Theory] + [InlineData(1, false)] + [InlineData(2, false)] + [InlineData(3, true)] + [InlineData(4, true)] + [InlineData(5, false)] + public async Task Invoke_WithForAndWhen_ShouldMatchInExpectedIterations(int invocationCount, bool expectResult) + { + Callback sut = new(() => { }); + sut.For(2); + sut.When(v => v > 1); + + int index = 0; + bool result = false; + for (int iteration = 1; iteration <= invocationCount; iteration++) + { + result = sut.Invoke(ref index, (_, _) => { }); + } + + await That(result).IsEqualTo(expectResult); + } + + [Fact] + public async Task Invoke_WithReturnValue_ShouldIncludeIndexWhenMatching() + { + List values = []; + Callback sut = new(() => { }); + sut.For(2); + sut.When(v => v > 1); + + int index = 0; + for (int i = 0; i < 5; i++) + { + sut.Invoke(ref index, (v, _) => + { + values.Add(v); + return $"foo-{v}"; + }, out string? _); + } + + await That(values).IsEqualTo([2, 3,]); + } + + [Theory] + [InlineData(1, false)] + [InlineData(2, false)] + [InlineData(3, true)] + [InlineData(4, true)] + [InlineData(5, false)] + public async Task Invoke_WithReturnValue_WithForAndWhen_ShouldMatchInExpectedIterations(int invocationCount, + bool expectResult) + { + Callback sut = new(() => { }); + sut.For(2); + sut.When(v => v > 1); + + int index = 0; + bool result = false; + for (int iteration = 1; iteration <= invocationCount; iteration++) + { + result = sut.Invoke(ref index, (_, _) => "foo", out string? _); + } + + await That(result).IsEqualTo(expectResult); + } +} diff --git a/Tests/Mockolate.Tests/MockMethods/SetupMethodTests.CallbackTests.cs b/Tests/Mockolate.Tests/MockMethods/SetupMethodTests.CallbackTests.cs index e5ac7371..2b91e968 100644 --- a/Tests/Mockolate.Tests/MockMethods/SetupMethodTests.CallbackTests.cs +++ b/Tests/Mockolate.Tests/MockMethods/SetupMethodTests.CallbackTests.cs @@ -39,6 +39,44 @@ public async Task Callback_ShouldNotExecuteWhenOtherMethodIsInvoked() await That(callCount).IsEqualTo(0); } + [Fact] + public async Task For_InParallel_ShouldLimitMatches() + { + List callIndices = []; + IReturnMethodSetupTest sut = Mock.Create(); + + sut.SetupMock.Method.Method0() + .Do(v => { callIndices.Add(v); }).InParallel().When(v => v > 1).For(2) + .Returns("a"); + + sut.Method0(); + sut.Method0(); + sut.Method0(); + sut.Method0(); + sut.Method0(); + + await That(callIndices).IsEqualTo([2, 3,]); + } + + [Fact] + public async Task For_ShouldLimitMatches() + { + List callIndices = []; + IReturnMethodSetupTest sut = Mock.Create(); + + sut.SetupMock.Method.Method0() + .Do(v => { callIndices.Add(v); }).When(v => v > 1).For(2) + .Returns("a"); + + sut.Method0(); + sut.Method0(); + sut.Method0(); + sut.Method0(); + sut.Method0(); + + await That(callIndices).IsEqualTo([2, 3,]); + } + [Fact] public async Task For_ShouldStopExecutingCallbackAfterTheGivenTimes() { @@ -1898,6 +1936,42 @@ public async Task Callback_ShouldNotExecuteWhenOtherMethodIsInvoked() await That(callCount).IsEqualTo(0); } + [Fact] + public async Task For_InParallel_ShouldLimitMatches() + { + List callIndices = []; + IVoidMethodSetupTest sut = Mock.Create(); + + sut.SetupMock.Method.Method0() + .Do(v => { callIndices.Add(v); }).InParallel().When(v => v > 1).For(2); + + sut.Method0(); + sut.Method0(); + sut.Method0(); + sut.Method0(); + sut.Method0(); + + await That(callIndices).IsEqualTo([2, 3,]); + } + + [Fact] + public async Task For_ShouldLimitMatches() + { + List callIndices = []; + IVoidMethodSetupTest sut = Mock.Create(); + + sut.SetupMock.Method.Method0() + .Do(v => { callIndices.Add(v); }).When(v => v > 1).For(2); + + sut.Method0(); + sut.Method0(); + sut.Method0(); + sut.Method0(); + sut.Method0(); + + await That(callIndices).IsEqualTo([2, 3,]); + } + [Fact] public async Task For_ShouldStopExecutingCallbackAfterTheGivenTimes() { diff --git a/Tests/Mockolate.Tests/MockMethods/SetupMethodTests.ReturnsThrowsTests.cs b/Tests/Mockolate.Tests/MockMethods/SetupMethodTests.ReturnsThrowsTests.cs index b5a5615b..3ef1f534 100644 --- a/Tests/Mockolate.Tests/MockMethods/SetupMethodTests.ReturnsThrowsTests.cs +++ b/Tests/Mockolate.Tests/MockMethods/SetupMethodTests.ReturnsThrowsTests.cs @@ -26,6 +26,24 @@ await That(Act).Throws() .WithMessage("Times must be greater than zero.").AsPrefix(); } + [Fact] + public async Task For_ShouldLimitMatches() + { + List results = []; + IReturnMethodSetupTest sut = Mock.Create(); + + sut.SetupMock.Method.Method0() + .Returns("a").When(v => v > 1).For(2); + + results.Add(sut.Method0()); + results.Add(sut.Method0()); + results.Add(sut.Method0()); + results.Add(sut.Method0()); + results.Add(sut.Method0()); + + await That(results).IsEqualTo(["", "", "a", "a", "",]); + } + [Fact] public async Task MixReturnsAndThrows_ShouldIterateThroughBoth() { @@ -2056,6 +2074,31 @@ await That(Act).Throws() .WithMessage("Times must be greater than zero.").AsPrefix(); } + [Fact] + public async Task For_ShouldLimitMatches() + { + List results = []; + IVoidMethodSetupTest sut = Mock.Create(); + + sut.SetupMock.Method.Method0() + .Throws(new Exception("a")).When(v => v > 1).For(2); + + for (int i = 0; i < 5; i++) + { + try + { + sut.Method0(); + results.Add(""); + } + catch (Exception ex) + { + results.Add(ex.Message); + } + } + + await That(results).IsEqualTo(["", "", "a", "a", "",]); + } + [Fact] public async Task MixDoesNotThrowAndThrow_ShouldIterateThroughBoth() {