mirror of
https://github.com/Stone-Red-Code/CuteUtils.git
synced 2026-09-04 08:56:13 +02:00
Update libraries and add SafeRetry and WaitUntil utilites
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
using CuteUtils.Misc;
|
||||
|
||||
namespace CuteUtils.Tests.Misc;
|
||||
|
||||
[TestClass]
|
||||
public class SafeRetryTests
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task RetryAsyncT_SucceedsFirstTry()
|
||||
{
|
||||
int callCount = 0;
|
||||
int result = await SafeRetry.RetryAsync(async () =>
|
||||
{
|
||||
callCount++;
|
||||
await Task.Delay(10);
|
||||
return 42;
|
||||
});
|
||||
Assert.AreEqual(1, callCount);
|
||||
Assert.AreEqual(42, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task RetryAsyncT_RetriesAndSucceeds()
|
||||
{
|
||||
int callCount = 0;
|
||||
int result = await SafeRetry.RetryAsync(async () =>
|
||||
{
|
||||
callCount++;
|
||||
if (callCount < 3)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
await Task.Delay(10);
|
||||
return 99;
|
||||
}, maxRetries: 5, delay: TimeSpan.FromMilliseconds(1));
|
||||
Assert.AreEqual(3, callCount);
|
||||
Assert.AreEqual(99, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task RetryAsyncT_ThrowsAfterMaxRetries()
|
||||
{
|
||||
int callCount = 0;
|
||||
_ = await Assert.ThrowsExceptionAsync<InvalidOperationException>(async () =>
|
||||
{
|
||||
_ = await SafeRetry.RetryAsync<int>(() =>
|
||||
{
|
||||
callCount++;
|
||||
throw new InvalidOperationException("fail");
|
||||
}, maxRetries: 2, delay: TimeSpan.FromMilliseconds(1));
|
||||
});
|
||||
Assert.AreEqual(2, callCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task RetryAsync_SucceedsFirstTry()
|
||||
{
|
||||
int callCount = 0;
|
||||
await SafeRetry.RetryAsync(async () =>
|
||||
{
|
||||
callCount++;
|
||||
await Task.Delay(10);
|
||||
});
|
||||
Assert.AreEqual(1, callCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task RetryAsync_RetriesAndSucceeds()
|
||||
{
|
||||
int callCount = 0;
|
||||
await SafeRetry.RetryAsync(async () =>
|
||||
{
|
||||
callCount++;
|
||||
if (callCount < 2)
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
await Task.Delay(10);
|
||||
}, maxRetries: 3, delay: TimeSpan.FromMilliseconds(1));
|
||||
Assert.AreEqual(2, callCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task RetryAsync_ThrowsAfterMaxRetries()
|
||||
{
|
||||
int callCount = 0;
|
||||
_ = await Assert.ThrowsExceptionAsync<InvalidOperationException>(async () =>
|
||||
{
|
||||
await SafeRetry.RetryAsync(() =>
|
||||
{
|
||||
callCount++;
|
||||
throw new Exception();
|
||||
}, maxRetries: 2, delay: TimeSpan.FromMilliseconds(1));
|
||||
});
|
||||
Assert.AreEqual(2, callCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RetryT_SucceedsFirstTry()
|
||||
{
|
||||
int callCount = 0;
|
||||
int result = SafeRetry.Retry(() =>
|
||||
{
|
||||
callCount++;
|
||||
return 7;
|
||||
});
|
||||
Assert.AreEqual(1, callCount);
|
||||
Assert.AreEqual(7, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RetryT_RetriesAndSucceeds()
|
||||
{
|
||||
int callCount = 0;
|
||||
int result = SafeRetry.Retry(() =>
|
||||
{
|
||||
callCount++;
|
||||
if (callCount < 4)
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
return 123;
|
||||
}, maxRetries: 5, delay: TimeSpan.FromMilliseconds(1));
|
||||
Assert.AreEqual(4, callCount);
|
||||
Assert.AreEqual(123, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RetryT_ThrowsAfterMaxRetries()
|
||||
{
|
||||
int callCount = 0;
|
||||
_ = Assert.ThrowsException<InvalidOperationException>(() =>
|
||||
{
|
||||
_ = SafeRetry.Retry<int>(() =>
|
||||
{
|
||||
callCount++;
|
||||
throw new Exception();
|
||||
}, maxRetries: 3, delay: TimeSpan.FromMilliseconds(1));
|
||||
});
|
||||
Assert.AreEqual(3, callCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Retry_SucceedsFirstTry()
|
||||
{
|
||||
int callCount = 0;
|
||||
SafeRetry.Retry(() =>
|
||||
{
|
||||
callCount++;
|
||||
});
|
||||
Assert.AreEqual(1, callCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Retry_RetriesAndSucceeds()
|
||||
{
|
||||
int callCount = 0;
|
||||
SafeRetry.Retry(() =>
|
||||
{
|
||||
callCount++;
|
||||
if (callCount < 2)
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
}, maxRetries: 3, delay: TimeSpan.FromMilliseconds(1));
|
||||
Assert.AreEqual(2, callCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Retry_ThrowsAfterMaxRetries()
|
||||
{
|
||||
int callCount = 0;
|
||||
_ = Assert.ThrowsException<InvalidOperationException>(() =>
|
||||
{
|
||||
SafeRetry.Retry(() =>
|
||||
{
|
||||
callCount++;
|
||||
throw new Exception();
|
||||
}, maxRetries: 2, delay: TimeSpan.FromMilliseconds(1));
|
||||
});
|
||||
Assert.AreEqual(2, callCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task RetryAsyncT_ThrowsArgumentNullException()
|
||||
{
|
||||
_ = await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () =>
|
||||
{
|
||||
_ = await SafeRetry.RetryAsync<int>(null!);
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task RetryAsync_ThrowsArgumentNullException()
|
||||
{
|
||||
_ = await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () =>
|
||||
{
|
||||
await SafeRetry.RetryAsync(null!);
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RetryT_ThrowsArgumentNullException()
|
||||
{
|
||||
_ = Assert.ThrowsException<ArgumentNullException>(() =>
|
||||
{
|
||||
_ = SafeRetry.Retry<int>(null!);
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Retry_ThrowsArgumentNullException()
|
||||
{
|
||||
_ = Assert.ThrowsException<ArgumentNullException>(() =>
|
||||
{
|
||||
SafeRetry.Retry(null!);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
using CuteUtils.Misc;
|
||||
|
||||
namespace CuteUtils.Tests.Misc;
|
||||
|
||||
[TestClass]
|
||||
public class WaitTests
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task UntilAsync_ConditionMet_CompletesSuccessfully()
|
||||
{
|
||||
bool flag = false;
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
flag = true;
|
||||
});
|
||||
await Wait.UntilAsync(() => flag, TimeSpan.FromMilliseconds(50), TimeSpan.FromSeconds(2));
|
||||
Assert.IsTrue(flag);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(TimeoutException))]
|
||||
public async Task UntilAsync_ConditionNotMet_ThrowsTimeoutException()
|
||||
{
|
||||
await Wait.UntilAsync(() => false, TimeSpan.FromMilliseconds(50), TimeSpan.FromMilliseconds(200));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Until_ConditionMet_CompletesSuccessfully()
|
||||
{
|
||||
bool flag = false;
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
flag = true;
|
||||
});
|
||||
Wait.Until(() => flag, TimeSpan.FromMilliseconds(50), TimeSpan.FromSeconds(2));
|
||||
Assert.IsTrue(flag);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(TimeoutException))]
|
||||
public void Until_ConditionNotMet_ThrowsTimeoutException()
|
||||
{
|
||||
Wait.Until(() => false, TimeSpan.FromMilliseconds(50), TimeSpan.FromMilliseconds(200));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task WaitForEventAsync_EventRaised_CompletesSuccessfully()
|
||||
{
|
||||
void subscribe(Action handler)
|
||||
{
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
handler();
|
||||
});
|
||||
}
|
||||
await Wait.WaitForEventAsync(subscribe, TimeSpan.FromSeconds(2));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(TimeoutException))]
|
||||
public async Task WaitForEventAsync_EventNotRaised_ThrowsTimeoutException()
|
||||
{
|
||||
void subscribe(Action handler) { }
|
||||
await Wait.WaitForEventAsync(subscribe, TimeSpan.FromMilliseconds(200));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task WaitForEventAsyncT_EventRaised_CompletesWithValue()
|
||||
{
|
||||
void subscribe(Action<int> handler)
|
||||
{
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
handler(42);
|
||||
});
|
||||
}
|
||||
int result = await Wait.WaitForEventAsync((Action<Action<int>>)subscribe, TimeSpan.FromSeconds(2));
|
||||
Assert.AreEqual(42, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(TimeoutException))]
|
||||
public async Task WaitForEventAsyncT_EventNotRaised_ThrowsTimeoutException()
|
||||
{
|
||||
void subscribe(Action<int> handler) { }
|
||||
_ = await Wait.WaitForEventAsync((Action<Action<int>>)subscribe, TimeSpan.FromMilliseconds(200));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void WaitForEvent_EventRaised_CompletesSuccessfully()
|
||||
{
|
||||
void subscribe(Action handler)
|
||||
{
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
handler();
|
||||
});
|
||||
}
|
||||
Wait.WaitForEvent(subscribe, TimeSpan.FromSeconds(2));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(TimeoutException))]
|
||||
public void WaitForEvent_EventNotRaised_ThrowsTimeoutException()
|
||||
{
|
||||
void subscribe(Action handler) { }
|
||||
Wait.WaitForEvent(subscribe, TimeSpan.FromMilliseconds(200));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void WaitForEventT_EventRaised_CompletesWithValue()
|
||||
{
|
||||
void subscribe(Action<string> handler)
|
||||
{
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
handler("hello");
|
||||
});
|
||||
}
|
||||
string result = Wait.WaitForEvent((Action<Action<string>>)subscribe, TimeSpan.FromSeconds(2));
|
||||
Assert.AreEqual("hello", result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(TimeoutException))]
|
||||
public void WaitForEventT_EventNotRaised_ThrowsTimeoutException()
|
||||
{
|
||||
void subscribe(Action<string> handler) { }
|
||||
_ = Wait.WaitForEvent((Action<Action<string>>)subscribe, TimeSpan.FromMilliseconds(200));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user