-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: fix some small issues, updated dependency and added tests
- Loading branch information
1 parent
a04b0ed
commit 92830fd
Showing
8 changed files
with
206 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
using Moq; | ||
using NUnit.Framework; | ||
using System; | ||
using System.Diagnostics; | ||
using System.Linq.Expressions; | ||
using System.Threading.Tasks; | ||
|
||
namespace AsyncVerifyForMoq | ||
{ | ||
/// <summary> | ||
/// Allows to do a async Verify() that wait for the Verification expression to become verified within a given timeout. | ||
/// </summary> | ||
public static class MoqAsyncVerifyExtensions | ||
{ | ||
const int GRANULARITY = 100; | ||
|
||
/// <summary> | ||
/// Prevents having multiple implementations for the timeout handling. | ||
/// </summary> | ||
/// <param name="action">The verification action that is called.</param> | ||
/// <param name="timeout">The timeout within the Verification should be successful.</param> | ||
/// <returns></returns> | ||
public async static Task SomeVerifyWithTimeout(Action action, TimeSpan timeout) | ||
{ | ||
var stopWatch = new Stopwatch(); | ||
stopWatch.Start(); | ||
Exception verificationException = null; | ||
|
||
while (stopWatch.Elapsed < timeout) | ||
{ | ||
try | ||
{ | ||
action(); | ||
return; | ||
} | ||
catch (Exception mockException) | ||
{ | ||
verificationException = mockException; | ||
await Task.Delay(GRANULARITY); | ||
} | ||
} | ||
throw new TimeoutException($"Verification expression always failed within given timespan of {timeout}.", verificationException); | ||
} | ||
|
||
/// <summary> | ||
/// Extension for Mock<typeparamref name="T"/> allowing a asynchronous Verify() that should be successful in a specified time period. | ||
/// </summary> | ||
/// <typeparam name="T">Type to mock, which can be an interface, a class, or a delegate.</typeparam> | ||
/// <typeparam name="TExpressionResult">Result type of the expression used for verification.</typeparam> | ||
/// <param name="mock">The mock that is used as this for this extension</param> | ||
/// <param name="expression">Expression to verify.</param> | ||
/// <param name="times">The number of times a method is expected to be called as in the regular Verify() call.</param> | ||
/// <param name="timeout">The timeout within the verify should be successful.</param> | ||
/// <returns>A task to wait on. The task will fail with a TimeoutException in case the Verify() was not successful within the given timeout.</returns> | ||
public async static Task AsyncVerify<T, TExpressionResult>(this Mock<T> mock, Expression<Func<T, TExpressionResult>> expression, Times times, TimeSpan timeout) where T : class | ||
{ | ||
await SomeVerifyWithTimeout(() => mock.Verify(expression, times), timeout); | ||
} | ||
|
||
/// <summary> | ||
/// Extension for Mock<typeparamref name="T"/> allowing a asynchronous Verify() that should be successful in a specified time period. | ||
/// Variant for expressions without a return value and one parameter. | ||
/// </summary> | ||
/// <typeparam name="T">Type to mock, which can be an interface, a class, or a delegate.</typeparam> | ||
/// <param name="mock">The mock that is used as this for this extension</param> | ||
/// <param name="expression">Expression to verify.</param> | ||
/// <param name="times">The number of times a method is expected to be called as in the regular Verify() call.</param> | ||
/// <param name="timeout">The timeout within the verify should be successful.</param> | ||
/// <returns>A task to wait on. The task will fail with a TimeoutException in case the Verify() was not successful within the given timeout.</returns> | ||
public async static Task AsyncVerify<T>(this Mock<T> mock, Expression<Action<T>> expression, Times times, TimeSpan timeout) where T : class | ||
{ | ||
await SomeVerifyWithTimeout(() => mock.Verify(expression, times), timeout); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
using System.Collections.Generic; | ||
using System.Text.Json; | ||
using System.Threading.Tasks; | ||
using NUnit.Framework; | ||
using Oxide.Ext.GamingApi.MessageQueue; | ||
using System; | ||
using AsyncVerifyForMoq; | ||
using Moq; | ||
|
||
namespace Oxide.Ext.GamingApi.Tests | ||
{ | ||
[TestFixture()] | ||
public class GamingApiMessageQueueTest | ||
{ | ||
GamingApiMessageQueue queue; | ||
|
||
[SetUp()] | ||
public void setup() | ||
{ | ||
queue = GamingApiMessageQueue.Instance; | ||
} | ||
|
||
[Test()] | ||
public async Task shouldConsumeMessage() | ||
{ | ||
var timeSpan = TimeSpan.FromSeconds(10); | ||
var mock = new Mock<Action<Action, Action>>(); | ||
mock.Setup((m) => m(It.IsAny<Action>(), It.IsAny<Action>())) | ||
.Callback((Action success, Action failure) => success()); | ||
|
||
queue.AddToMessageQueue(MessageImportance.LOW, mock.Object); | ||
|
||
var asyncVerification = new List<Task>() | ||
{ | ||
MoqAsyncVerifyExtensions.SomeVerifyWithTimeout(() => | ||
{ | ||
//Cannot use assertion as it will be caught by the test itself | ||
if(0 != queue.GetCurrentMessagesInQueue()) throw new Exception($"{queue.GetCurrentMessagesInQueue()}"); | ||
}, timeSpan) | ||
}; | ||
await Task.WhenAll(asyncVerification); | ||
} | ||
[Test()] | ||
public async Task shouldConsumeRetryMessage() | ||
{ | ||
var timeSpan = TimeSpan.FromSeconds(10); | ||
var mock = new Mock<Action<Action, Action>>(); | ||
mock.Setup((m) => m(It.IsAny<Action>(), It.IsAny<Action>())) | ||
.Callback((Action success, Action failure) => success()); | ||
|
||
queue.AddToRetryMessageQueue(MessageImportance.LOW, mock.Object); | ||
|
||
var asyncVerification = new List<Task>() | ||
{ | ||
MoqAsyncVerifyExtensions.SomeVerifyWithTimeout(() => | ||
{ | ||
//Cannot use assertion as it will be caught by the test itself | ||
if(0 != queue.GetCurrentMessagesInQueue()) throw new Exception($"{queue.GetCurrentMessagesInQueue()}"); | ||
}, timeSpan) | ||
}; | ||
await Task.WhenAll(asyncVerification); | ||
} | ||
[Test()] | ||
public async Task shouldBeAbleToProcessMessagesInDueTime() | ||
{ | ||
var timeSpan = TimeSpan.FromSeconds(12); | ||
queue.SetInterval(1000); | ||
var mock = new Mock<Action<Action, Action>>(); | ||
mock.Setup((m) => m(It.IsAny<Action>(), It.IsAny<Action>())) | ||
.Callback((Action success, Action failure) => success()); | ||
|
||
for (int i = 0; i < 10; i++) | ||
{ | ||
queue.AddToRetryMessageQueue(MessageImportance.LOW, mock.Object); | ||
} | ||
|
||
var asyncVerification = new List<Task>() | ||
{ | ||
MoqAsyncVerifyExtensions.SomeVerifyWithTimeout(() => | ||
{ | ||
//Cannot use assertion as it will be caught by the test itself | ||
if(0 != queue.GetCurrentMessagesInQueue()) throw new Exception($"{queue.GetCurrentMessagesInQueue()}"); | ||
}, timeSpan) | ||
}; | ||
await Task.WhenAll(asyncVerification); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters