public async Task StartAsync_CommandThrowsInvalidOperationException_RaisesErrorOccuredEvent() { // ARRANGE var contextMock = new Mock <ICommandLoopContext>(); contextMock.SetupGet(x => x.HasNextIteration).Returns(true); contextMock.SetupGet(x => x.CanPlayerGiveCommand).Returns(true); var context = contextMock.Object; var tcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); var eventWasInvokedTask = tcs.Task; var commandMock = new Mock <ICommand>(); commandMock.Setup(x => x.Execute()).Throws <InvalidOperationException>(); var command = commandMock.Object; var commandPool = new TestCommandPool(); commandPool.Push(command); var commandLoopUpdater = new CommandLoopUpdater(context, commandPool); ErrorOccuredEventArgs?expectedRaisedErrorArgs = null; var raiseCount = 0; commandLoopUpdater.ErrorOccured += (s, e) => { expectedRaisedErrorArgs = e; // Count raises to prevent errors with multiple events. raiseCount++; tcs.SetResult(true); }; // ACT using var monitor = commandLoopUpdater.Monitor(); #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed commandLoopUpdater.StartAsync(CancellationToken.None).ConfigureAwait(false); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed var expectedEventWasRaised = await eventWasInvokedTask.ConfigureAwait(false); // ASSERT expectedEventWasRaised.Should().BeTrue(); expectedRaisedErrorArgs.Should().BeOfType <CommandErrorOccuredEventArgs>(); raiseCount.Should().Be(1); }
public async Task StartAsync_CommandIsRepeatableOnce_ExecutesCommandTwice() { // ARRANGE var contextMock = new Mock <ICommandLoopContext>(); contextMock.SetupGet(x => x.HasNextIteration).Returns(true); contextMock.SetupGet(x => x.CanPlayerGiveCommand).Returns(true); var context = contextMock.Object; var tcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); var waitCommandExecutedTask = tcs.Task; var repeatIteration = 0; var commandMock = new Mock <IRepeatableCommand>(); commandMock.Setup(x => x.Execute()).Callback(() => { if (repeatIteration >= 1) { tcs.SetResult(true); } }); commandMock.Setup(x => x.CanRepeat()).Callback(() => { repeatIteration++; }) .Returns(() => repeatIteration <= 1); commandMock.Setup(x => x.CanExecute()).Returns(new CanExecuteCheckResult { IsSuccess = true }); var command = commandMock.Object; var commandPool = new TestCommandPool(); commandPool.Push(command); var commandLoopUpdater = new CommandLoopUpdater(context, commandPool); // ACT #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed commandLoopUpdater.StartAsync(CancellationToken.None).ConfigureAwait(false); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed await waitCommandExecutedTask.ConfigureAwait(false); // ASSERT commandMock.Verify(x => x.Execute(), Times.Exactly(2)); }
public async Task StartAsync_CommandInPoolAfterStart_ExecutesCommand() { // ARRANGE var contextMock = new Mock <ICommandLoopContext>(); contextMock.SetupGet(x => x.HasNextIteration).Returns(true); contextMock.SetupGet(x => x.CanPlayerGiveCommand).Returns(true); var context = contextMock.Object; var tcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); var testTask = tcs.Task; var commandMock = new Mock <ICommand>(); commandMock.Setup(x => x.Execute()).Callback(() => tcs.SetResult(true)); var command = commandMock.Object; var commandPool = new TestCommandPool(); var commandLoopUpdater = new CommandLoopUpdater(context, commandPool); // ACT #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed commandLoopUpdater.StartAsync(CancellationToken.None).ConfigureAwait(false); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed commandPool.Push(command); // Delay to take some time to command loop updater to perform some iterations. await testTask.ConfigureAwait(false); // ASSERT commandMock.Verify(x => x.Execute(), Times.Once); }
public async Task StartAsync_CommandInPoolBeforeStart_RaisesCompleteCommandEvent() { // ARRANGE var contextMock = new Mock <ICommandLoopContext>(); contextMock.SetupGet(x => x.HasNextIteration).Returns(true); contextMock.SetupGet(x => x.CanPlayerGiveCommand).Returns(true); var context = contextMock.Object; var tcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); var eventTask = tcs.Task; var commandMock = new Mock <ICommand>(); var command = commandMock.Object; var commandPool = new TestCommandPool(); commandPool.Push(command); var commandLoopUpdater = new CommandLoopUpdater(context, commandPool); commandLoopUpdater.CommandProcessed += (s, e) => { tcs.SetResult(true); }; // ACT #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed commandLoopUpdater.StartAsync(CancellationToken.None).ConfigureAwait(false); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed // ASSERT var expectedEventWasRaised = await eventTask.ConfigureAwait(false); expectedEventWasRaised.Should().BeTrue(); }