diff --git a/docs/TimeProviderExtensions.ManualTimeProvider.md b/docs/TimeProviderExtensions.ManualTimeProvider.md
index 9f66d85..1185759 100644
--- a/docs/TimeProviderExtensions.ManualTimeProvider.md
+++ b/docs/TimeProviderExtensions.ManualTimeProvider.md
@@ -12,7 +12,7 @@ public class ManualTimeProvider : System.TimeProvider
Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 [System.TimeProvider](https://docs.microsoft.com/en-us/dotnet/api/System.TimeProvider 'System.TimeProvider') 🡒 ManualTimeProvider
### Remarks
-Learn more at [https://github.com/egil/TimeProviderExtensions](https://github.com/egil/TimeProviderExtensions 'https://github.com/egil/TimeProviderExtensions').
+Learn more at TimeProviderExtensions on GitHub.
### Constructors
@@ -193,7 +193,7 @@ var timer = manualTimeProvider.CreateTimer(
dueTime: Span.FromSecond(1),
period: TimeSpan.FromSecond(1));
-manualtTimeProvider.Advance(TimeSpan.FromSecond(3));
+manualTimeProvider.Advance(TimeSpan.FromSecond(3));
```
The call to `Advance(TimeSpan.FromSecond(3))` causes the `timer`s callback to be invoked three times,
and the result of the `manualTimeProvider.GetElapsedTime(start)` in the callback call will be 1 second, 2 seconds,
@@ -204,7 +204,7 @@ If the desired result is to jump time by [delta](TimeProviderExtensions.ManualTi
the expected number of times, i.e. such that the result of `manualTimeProvider.GetElapsedTime(start)` in the callback is
3 seconds, 3 seconds, and 3 seconds, use [Jump(DateTimeOffset)](TimeProviderExtensions.ManualTimeProvider.md#TimeProviderExtensions.ManualTimeProvider.Jump(System.DateTimeOffset) 'TimeProviderExtensions.ManualTimeProvider.Jump(System.DateTimeOffset)') or [Jump(TimeSpan)](TimeProviderExtensions.ManualTimeProvider.md#TimeProviderExtensions.ManualTimeProvider.Jump(System.TimeSpan) 'TimeProviderExtensions.ManualTimeProvider.Jump(System.TimeSpan)') instead.
-Learn more about this behavior at [https://github.com/egil/TimeProviderExtensions/#difference-between-manualtimeprovider-and-faketimeprovider](https://github.com/egil/TimeProviderExtensions/#difference-between-manualtimeprovider-and-faketimeprovider 'https://github.com/egil/TimeProviderExtensions/#difference-between-manualtimeprovider-and-faketimeprovider').
+Learn more about this behavior at in the documentation.
@@ -397,9 +397,9 @@ var timer = manualTimeProvider.CreateTimer(
dueTime: Span.FromSecond(1),
period: TimeSpan.FromSecond(1));
-manualtTimeProvider.Jump(manualtTimeProvider.Start + TimeSpan.FromSecond(3));
+manualTimeProvider.Jump(manualTimeProvider.Start + TimeSpan.FromSecond(3));
```
-The call to `Jump(manualtTimeProvider.Start + TimeSpan.FromSecond(3))` causes the `timer`s callback to be invoked three times,
+The call to `Jump(manualTimeProvider.Start + TimeSpan.FromSecond(3))` causes the `timer`s callback to be invoked three times,
and the result of the `manualTimeProvider.GetElapsedTime(start)` in the callback call will be 3 seconds
during all three invocations.
@@ -407,7 +407,7 @@ If the desired result is that timer callbacks happens exactly at their scheduled
of `manualTimeProvider.GetElapsedTime(start)` in the callback will be 1 second, 2 seconds, and 3 seconds,
use [Advance(TimeSpan)](TimeProviderExtensions.ManualTimeProvider.md#TimeProviderExtensions.ManualTimeProvider.Advance(System.TimeSpan) 'TimeProviderExtensions.ManualTimeProvider.Advance(System.TimeSpan)') or [SetUtcNow(DateTimeOffset)](TimeProviderExtensions.ManualTimeProvider.md#TimeProviderExtensions.ManualTimeProvider.SetUtcNow(System.DateTimeOffset) 'TimeProviderExtensions.ManualTimeProvider.SetUtcNow(System.DateTimeOffset)') instead.
-Learn more about this behavior at [https://github.com/egil/TimeProviderExtensions/#difference-between-manualtimeprovider-and-faketimeprovider](https://github.com/egil/TimeProviderExtensions/#difference-between-manualtimeprovider-and-faketimeprovider 'https://github.com/egil/TimeProviderExtensions/#difference-between-manualtimeprovider-and-faketimeprovider').
+Learn more about this behavior at in the documentation. ///
@@ -452,7 +452,7 @@ var timer = manualTimeProvider.CreateTimer(
dueTime: Span.FromSecond(1),
period: TimeSpan.FromSecond(1));
-manualtTimeProvider.Jump(TimeSpan.FromSecond(3));
+manualTimeProvider.Jump(TimeSpan.FromSecond(3));
```
The call to `Jump(TimeSpan.FromSecond(3))` causes the `timer`s callback to be invoked three times,
and the result of the `manualTimeProvider.GetElapsedTime(start)` in the callback call will be 3 seconds
@@ -462,7 +462,7 @@ If the desired result is that timer callbacks happens exactly at their scheduled
of `manualTimeProvider.GetElapsedTime(start)` in the callback will be 1 second, 2 seconds, and 3 seconds,
use [Advance(TimeSpan)](TimeProviderExtensions.ManualTimeProvider.md#TimeProviderExtensions.ManualTimeProvider.Advance(System.TimeSpan) 'TimeProviderExtensions.ManualTimeProvider.Advance(System.TimeSpan)') or [SetUtcNow(DateTimeOffset)](TimeProviderExtensions.ManualTimeProvider.md#TimeProviderExtensions.ManualTimeProvider.SetUtcNow(System.DateTimeOffset) 'TimeProviderExtensions.ManualTimeProvider.SetUtcNow(System.DateTimeOffset)') instead.
-Learn more about this behavior at [https://github.com/egil/TimeProviderExtensions/#difference-between-manualtimeprovider-and-faketimeprovider](https://github.com/egil/TimeProviderExtensions/#difference-between-manualtimeprovider-and-faketimeprovider 'https://github.com/egil/TimeProviderExtensions/#difference-between-manualtimeprovider-and-faketimeprovider').
+Learn more about this behavior at in the documentation. ///
@@ -525,9 +525,9 @@ var timer = manualTimeProvider.CreateTimer(
dueTime: Span.FromSecond(1),
period: TimeSpan.FromSecond(1));
-manualtTimeProvider.SetUtcNow(manualtTimeProvider.Start + TimeSpan.FromSecond(3));
+manualTimeProvider.SetUtcNow(manualTimeProvider.Start + TimeSpan.FromSecond(3));
```
-The call to `SetUtcNow(manualtTimeProvider.Start + TimeSpan.FromSecond(3))` causes the `timer`s callback to be invoked three times,
+The call to `SetUtcNow(manualTimeProvider.Start + TimeSpan.FromSecond(3))` causes the `timer`s callback to be invoked three times,
and the result of the `manualTimeProvider.GetElapsedTime(start)` in the callback call will be 1 second, 2 seconds,
and 3 seconds. In other words, the time of the provider is set before the time callback is invoked
to the time that the callback is scheduled to be invoked at.
@@ -536,7 +536,7 @@ If the desired result is to jump to the time specified in [value](TimeProviderEx
the expected number of times, i.e. such that the result of `manualTimeProvider.GetElapsedTime(start)` in the callback is
3 seconds, 3 seconds, and 3 seconds, use [Jump(DateTimeOffset)](TimeProviderExtensions.ManualTimeProvider.md#TimeProviderExtensions.ManualTimeProvider.Jump(System.DateTimeOffset) 'TimeProviderExtensions.ManualTimeProvider.Jump(System.DateTimeOffset)') or [Jump(TimeSpan)](TimeProviderExtensions.ManualTimeProvider.md#TimeProviderExtensions.ManualTimeProvider.Jump(System.TimeSpan) 'TimeProviderExtensions.ManualTimeProvider.Jump(System.TimeSpan)') instead.
-Learn more about this behavior at [https://github.com/egil/TimeProviderExtensions/#difference-between-manualtimeprovider-and-faketimeprovider](https://github.com/egil/TimeProviderExtensions/#difference-between-manualtimeprovider-and-faketimeprovider 'https://github.com/egil/TimeProviderExtensions/#difference-between-manualtimeprovider-and-faketimeprovider').
+Learn more about this behavior at in the documentation. ///
diff --git a/src/TimeProviderExtensions/ManualTimeProvider.cs b/src/TimeProviderExtensions/ManualTimeProvider.cs
index 5a77ffb..9f5458e 100644
--- a/src/TimeProviderExtensions/ManualTimeProvider.cs
+++ b/src/TimeProviderExtensions/ManualTimeProvider.cs
@@ -8,7 +8,7 @@ namespace TimeProviderExtensions;
/// Represents a synthetic time provider that can be used to enable deterministic behavior in tests.
///
///
-/// Learn more at .
+/// Learn more at TimeProviderExtensions on GitHub.
///
[DebuggerDisplay("UtcNow: {ToString(),nq}. Active timers: {ActiveTimers}. {AutoAdvanceBehavior,nq}.")]
public class ManualTimeProvider : TimeProvider
@@ -232,14 +232,14 @@ public void SetLocalTimeZone(TimeZoneInfo localTimeZone)
/// For example:
///
/// var start = sut.GetTimestamp();
- ///
+ ///
/// var timer = manualTimeProvider.CreateTimer(
/// callback: _ => manualTimeProvider.GetElapsedTime(start),
/// state: null,
/// dueTime: Span.FromSecond(1),
/// period: TimeSpan.FromSecond(1));
- ///
- /// manualtTimeProvider.Advance(TimeSpan.FromSecond(3));
+ ///
+ /// manualTimeProvider.Advance(TimeSpan.FromSecond(3));
///
/// The call to Advance(TimeSpan.FromSecond(3)) causes the timers callback to be invoked three times,
/// and the result of the manualTimeProvider.GetElapsedTime(start) in the callback call will be 1 second, 2 seconds,
@@ -252,7 +252,7 @@ public void SetLocalTimeZone(TimeZoneInfo localTimeZone)
/// 3 seconds, 3 seconds, and 3 seconds, use or instead.
///
///
- /// Learn more about this behavior at .
+ /// Learn more about this behavior at in the documentation.
///
///
/// Thrown if is negative. Going back in time is not supported.
@@ -290,16 +290,16 @@ public void Advance(TimeSpan delta)
/// For example:
///
/// var start = sut.GetTimestamp();
- ///
+ ///
/// var timer = manualTimeProvider.CreateTimer(
/// callback: _ => manualTimeProvider.GetElapsedTime(start),
/// state: null,
/// dueTime: Span.FromSecond(1),
/// period: TimeSpan.FromSecond(1));
- ///
- /// manualtTimeProvider.SetUtcNow(manualtTimeProvider.Start + TimeSpan.FromSecond(3));
+ ///
+ /// manualTimeProvider.SetUtcNow(manualTimeProvider.Start + TimeSpan.FromSecond(3));
///
- /// The call to SetUtcNow(manualtTimeProvider.Start + TimeSpan.FromSecond(3)) causes the timers callback to be invoked three times,
+ /// The call to SetUtcNow(manualTimeProvider.Start + TimeSpan.FromSecond(3)) causes the timers callback to be invoked three times,
/// and the result of the manualTimeProvider.GetElapsedTime(start) in the callback call will be 1 second, 2 seconds,
/// and 3 seconds. In other words, the time of the provider is set before the time callback is invoked
/// to the time that the callback is scheduled to be invoked at.
@@ -310,8 +310,7 @@ public void Advance(TimeSpan delta)
/// 3 seconds, 3 seconds, and 3 seconds, use or instead.
///
///
- /// Learn more about this behavior at .
- ///
+ /// Learn more about this behavior at in the documentation. ///
///
/// Thrown if is less than the value returned by . Going back in time is not supported.
public void SetUtcNow(DateTimeOffset value)
@@ -376,14 +375,14 @@ public void SetUtcNow(DateTimeOffset value)
/// For example:
///
/// var start = sut.GetTimestamp();
- ///
+ ///
/// var timer = manualTimeProvider.CreateTimer(
/// callback: _ => manualTimeProvider.GetElapsedTime(start),
/// state: null,
/// dueTime: Span.FromSecond(1),
/// period: TimeSpan.FromSecond(1));
- ///
- /// manualtTimeProvider.Jump(TimeSpan.FromSecond(3));
+ ///
+ /// manualTimeProvider.Jump(TimeSpan.FromSecond(3));
///
/// The call to Jump(TimeSpan.FromSecond(3)) causes the timers callback to be invoked three times,
/// and the result of the manualTimeProvider.GetElapsedTime(start) in the callback call will be 3 seconds
@@ -395,8 +394,7 @@ public void SetUtcNow(DateTimeOffset value)
/// use or instead.
///
///
- /// Learn more about this behavior at .
- ///
+ /// Learn more about this behavior at in the documentation. ///
///
/// Thrown if is negative. Going back in time is not supported.
public void Jump(TimeSpan delta)
@@ -433,16 +431,16 @@ public void Jump(TimeSpan delta)
/// For example:
///
/// var start = sut.GetTimestamp();
- ///
+ ///
/// var timer = manualTimeProvider.CreateTimer(
/// callback: _ => manualTimeProvider.GetElapsedTime(start),
/// state: null,
/// dueTime: Span.FromSecond(1),
/// period: TimeSpan.FromSecond(1));
///
- /// manualtTimeProvider.Jump(manualtTimeProvider.Start + TimeSpan.FromSecond(3));
+ /// manualTimeProvider.Jump(manualTimeProvider.Start + TimeSpan.FromSecond(3));
///
- /// The call to Jump(manualtTimeProvider.Start + TimeSpan.FromSecond(3)) causes the timers callback to be invoked three times,
+ /// The call to Jump(manualTimeProvider.Start + TimeSpan.FromSecond(3)) causes the timers callback to be invoked three times,
/// and the result of the manualTimeProvider.GetElapsedTime(start) in the callback call will be 3 seconds
/// during all three invocations.
///
@@ -452,8 +450,7 @@ public void Jump(TimeSpan delta)
/// use or instead.
///
///
- /// Learn more about this behavior at .
- ///
+ /// Learn more about this behavior at in the documentation. ///
///
/// Thrown if is less than the value returned by . Going back in time is not supported.
public void Jump(DateTimeOffset value)
diff --git a/src/TimeProviderExtensions/System.Runtime.CompilerServices/CallerArgumentExpressionAttribute.cs b/src/TimeProviderExtensions/System.Runtime.CompilerServices/CallerArgumentExpressionAttribute.cs
index 192e1d5..e74b875 100644
--- a/src/TimeProviderExtensions/System.Runtime.CompilerServices/CallerArgumentExpressionAttribute.cs
+++ b/src/TimeProviderExtensions/System.Runtime.CompilerServices/CallerArgumentExpressionAttribute.cs
@@ -1,6 +1,9 @@
#if !NET6_0_OR_GREATER
+using System.Diagnostics.CodeAnalysis;
+
namespace System.Runtime.CompilerServices;
+[ExcludeFromCodeCoverage]
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
internal sealed class CallerArgumentExpressionAttribute : Attribute
{
diff --git a/src/TimeProviderExtensions/System.Runtime.CompilerServices/IsExternalInit.cs b/src/TimeProviderExtensions/System.Runtime.CompilerServices/IsExternalInit.cs
index c3e1e82..ea5d893 100644
--- a/src/TimeProviderExtensions/System.Runtime.CompilerServices/IsExternalInit.cs
+++ b/src/TimeProviderExtensions/System.Runtime.CompilerServices/IsExternalInit.cs
@@ -1,9 +1,10 @@
#if NETSTANDARD2_0
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-
+
using System.ComponentModel;
-
+using System.Diagnostics.CodeAnalysis;
+
namespace System.Runtime.CompilerServices
{
///
@@ -11,6 +12,7 @@ namespace System.Runtime.CompilerServices
/// This class should not be used by developers in source code.
/// This dummy class is required to compile records when targeting .NET Standard
///
+ [ExcludeFromCodeCoverage]
[EditorBrowsable(EditorBrowsableState.Never)]
internal static class IsExternalInit
{
diff --git a/src/TimeProviderExtensions/System.Threading/PeriodicTimerPort.cs b/src/TimeProviderExtensions/System.Threading/PeriodicTimerPort.cs
index 1a9abf6..4fdeeb7 100644
--- a/src/TimeProviderExtensions/System.Threading/PeriodicTimerPort.cs
+++ b/src/TimeProviderExtensions/System.Threading/PeriodicTimerPort.cs
@@ -18,6 +18,7 @@ namespace TimeProviderExtensions;
/// may be in flight at any given moment. may be used concurrently with an active
/// to interrupt it and cause it to return false.
///
+[ExcludeFromCodeCoverage]
internal sealed class PeriodicTimerPort : IDisposable
{
internal const uint MaxSupportedTimeout = 0xfffffffe;
diff --git a/src/TimeProviderExtensions/System.Threading/PeriodicTimerWrapper.cs b/src/TimeProviderExtensions/System.Threading/PeriodicTimerWrapper.cs
index e9b5dbb..5c562ed 100644
--- a/src/TimeProviderExtensions/System.Threading/PeriodicTimerWrapper.cs
+++ b/src/TimeProviderExtensions/System.Threading/PeriodicTimerWrapper.cs
@@ -1,4 +1,5 @@
#if NET6_0_OR_GREATER && !NET8_0_OR_GREATER
+using System.Diagnostics.CodeAnalysis;
using TimeProviderExtensions;
namespace System.Threading;
@@ -14,6 +15,7 @@ namespace System.Threading;
/// to interrupt it and cause it to return false.
///
///
+[ExcludeFromCodeCoverage]
public abstract class PeriodicTimerWrapper : IDisposable
{
/// Wait for the next tick of the timer, or for the timer to be stopped.
diff --git a/test/TimeProviderExtensions.Tests/ManualTimeProviderTests.cs b/test/TimeProviderExtensions.Tests/ManualTimeProviderTests.cs
index 42e0b2f..ae36146 100644
--- a/test/TimeProviderExtensions.Tests/ManualTimeProviderTests.cs
+++ b/test/TimeProviderExtensions.Tests/ManualTimeProviderTests.cs
@@ -134,9 +134,9 @@ public async Task Callbacks_happens_in_schedule_order()
periodicTimer.Dispose();
await callbacksTask;
- async Task AsyncCallbacks(PeriodicTimer periodicTimer)
+ async Task AsyncCallbacks(PeriodicTimer timer)
{
- while (await periodicTimer.WaitForNextTickAsync().ConfigureAwait(false))
+ while (await timer.WaitForNextTickAsync().ConfigureAwait(false))
{
callbacks.Add(sut.GetUtcNow());
await sut.Delay(TimeSpan.FromSeconds(3));
@@ -292,7 +292,7 @@ public void ActiveTimers_with_active_timers()
{
var sut = new ManualTimeProvider();
- var timer = sut.CreateTimer(_ => { }, null, 1.Seconds(), Timeout.InfiniteTimeSpan);
+ using var timer = sut.CreateTimer(_ => { }, null, 1.Seconds(), Timeout.InfiniteTimeSpan);
sut.ActiveTimers.Should().Be(1);
}
@@ -302,7 +302,7 @@ public void ActiveTimers_with_inactive_timers()
{
var sut = new ManualTimeProvider();
- var timer = sut.CreateTimer(_ => { }, null, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
+ using var timer = sut.CreateTimer(_ => { }, null, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
sut.ActiveTimers.Should().Be(0);
}
@@ -312,7 +312,7 @@ public void ActiveTimers_with_after_timer_state_change()
{
var sut = new ManualTimeProvider();
- var timer = sut.CreateTimer(_ => { }, null, 1.Seconds(), Timeout.InfiniteTimeSpan);
+ using var timer = sut.CreateTimer(_ => { }, null, 1.Seconds(), Timeout.InfiniteTimeSpan);
sut.Advance(1.Seconds());
sut.ActiveTimers.Should().Be(0);
diff --git a/test/TimeProviderExtensions.Tests/ManualTimeProviderTimerTests.cs b/test/TimeProviderExtensions.Tests/ManualTimeProviderTimerTests.cs
deleted file mode 100644
index 7165f86..0000000
--- a/test/TimeProviderExtensions.Tests/ManualTimeProviderTimerTests.cs
+++ /dev/null
@@ -1,238 +0,0 @@
-namespace TimeProviderExtensions;
-
-public class ManualTimeProviderTimerTests
-{
- [Fact]
- public void CreateTimer_with_positive_DueTime_and_infinite_Period()
- {
- var callbackCount = 0;
- var dueTime = TimeSpan.FromSeconds(1);
- var period = Timeout.InfiniteTimeSpan;
- var sut = new ManualTimeProvider();
- using var timer = sut.CreateTimer(_ => callbackCount++, null, dueTime, period);
-
- sut.Advance(dueTime);
- callbackCount.Should().Be(1);
-
- sut.Advance(dueTime);
- callbackCount.Should().Be(1);
- }
-
- [Fact]
- public void CreateTimer_with_positive_DueTime_and_Period()
- {
- var callbackCount = 0;
- var dueTime = TimeSpan.FromSeconds(1);
- var period = TimeSpan.FromSeconds(2);
- var sut = new ManualTimeProvider();
- using var timer = sut.CreateTimer(_ => callbackCount++, null, dueTime, period);
-
- sut.Advance(dueTime);
- callbackCount.Should().Be(1);
-
- sut.Advance(period);
- callbackCount.Should().Be(2);
-
- sut.Advance(period);
- callbackCount.Should().Be(3);
- }
-
- [Fact]
- public void CreateTimer_with_infinite_DueTime_and_Period()
- {
- var callbackCount = 0;
- var dueTime = Timeout.InfiniteTimeSpan;
- var period = Timeout.InfiniteTimeSpan;
- var sut = new ManualTimeProvider();
- using var timer = sut.CreateTimer(_ => callbackCount++, null, dueTime, period);
-
- sut.Advance(TimeSpan.FromSeconds(1));
-
- callbackCount.Should().Be(0);
- }
-
- [Fact]
- public void Change_timer_from_stopped_to_started()
- {
- // Arrange
- var callbackCount = 0;
- var sut = new ManualTimeProvider();
- using var timer = sut.CreateTimer(_ => callbackCount++, null, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
- var dueTime = TimeSpan.FromSeconds(1);
- var period = TimeSpan.FromSeconds(2);
-
- // Act
- timer.Change(dueTime, period);
-
- // Assert
- sut.Advance(dueTime);
- callbackCount.Should().Be(1);
-
- sut.Advance(period);
- callbackCount.Should().Be(2);
-
- sut.Advance(period);
- callbackCount.Should().Be(3);
- }
-
- [Fact]
- public void Change_timer()
- {
- // Arrange
- var callbackCount = 0;
- var sut = new ManualTimeProvider();
- var originalDueTime = TimeSpan.FromSeconds(3);
- var period = TimeSpan.FromSeconds(5);
- using var timer = sut.CreateTimer(_ => callbackCount++, null, originalDueTime, period);
- var dueTime = TimeSpan.FromSeconds(4);
-
- // Change to a larger value
- timer.Change(dueTime, period);
-
- // Assert that previous dueTime is ignored
- sut.Advance(originalDueTime);
- callbackCount.Should().Be(0);
-
- sut.Advance(dueTime);
- callbackCount.Should().Be(1);
-
- sut.Advance(period);
- callbackCount.Should().Be(2);
- }
-
- [Fact]
- public void Timer_callback_invoked_multiple_times_single_advance()
- {
- var sut = new ManualTimeProvider();
- var callbackCount = 0;
- var dueTime = TimeSpan.FromSeconds(3);
- var period = TimeSpan.FromSeconds(5);
- using var timer = sut.CreateTimer(_ => callbackCount++, null, dueTime, period);
-
- sut.Advance(TimeSpan.FromSeconds(13));
-
- callbackCount.Should().Be(3);
- }
-
- [Fact]
- public void Advancing_GetUtcNow_matches_time_at_callback_time()
- {
- var sut = new ManualTimeProvider();
- var startTime = sut.GetUtcNow();
- var callbackTimes = new List();
- var interval = TimeSpan.FromSeconds(3);
- using var timer = sut.CreateTimer(_ => callbackTimes.Add(sut.GetUtcNow()), null, interval, interval);
-
- sut.Advance(interval + interval + interval);
-
- callbackTimes.Should().ContainInOrder(
- startTime + interval,
- startTime + interval + interval,
- startTime + interval + interval + interval);
- }
-
- [Fact]
- public void Disposing_timer_in_callback()
- {
- var interval = TimeSpan.FromSeconds(3);
- var sut = new ManualTimeProvider();
- ITimer timer = default!;
- timer = sut.CreateTimer(_ => timer!.Dispose(), null, interval, interval);
-
- sut.Advance(interval);
- }
-
- [Fact]
- public void Advancing_causes_multiple_timers_invokes_callback_in_order()
- {
- var oneSec = TimeSpan.FromSeconds(1);
- var callbacks = new List<(int TimerNumber, TimeSpan CallbackTime)>();
- var sut = new ManualTimeProvider();
- var startTime = sut.GetTimestamp();
- using var timer1 = sut.CreateTimer(_ => callbacks.Add((1, sut.GetElapsedTime(startTime))), null, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2));
- using var timer2 = sut.CreateTimer(_ => callbacks.Add((2, sut.GetElapsedTime(startTime))), null, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3));
-
- sut.Advance(TimeSpan.FromSeconds(11));
-
- callbacks.Should().Equal(
- (1, TimeSpan.FromSeconds(2)),
- (2, TimeSpan.FromSeconds(3)),
- (1, TimeSpan.FromSeconds(4)),
- (2, TimeSpan.FromSeconds(6)),
- (1, TimeSpan.FromSeconds(6)),
- (1, TimeSpan.FromSeconds(8)),
- (2, TimeSpan.FromSeconds(9)),
- (1, TimeSpan.FromSeconds(10)));
- }
-
- [Fact]
- public void Jumping_causes_multiple_timers_invokes_callback_in_order()
- {
- var oneSec = TimeSpan.FromSeconds(1);
- var callbacks = new List();
- var sut = new ManualTimeProvider();
- var startTime = sut.GetTimestamp();
- using var timer1 = sut.CreateTimer(_ => callbacks.Add(1), null, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2));
- using var timer2 = sut.CreateTimer(_ => callbacks.Add(2), null, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3));
-
- sut.Advance(TimeSpan.FromSeconds(11));
-
- callbacks.Should().Equal(1, 2, 1, 2, 1, 1, 2, 1);
- }
-
- [Fact]
- public void Jumping_GetUtcNow_matches_jump_target()
- {
- var sut = new ManualTimeProvider();
- var startTime = sut.GetUtcNow();
- var callbackTimes = new List();
- var interval = TimeSpan.FromSeconds(3);
- var target = interval + interval + interval;
- using var timer = sut.CreateTimer(_ => callbackTimes.Add(sut.GetUtcNow()), null, interval, interval);
-
- sut.Jump(target);
-
- callbackTimes.Should().Equal(startTime + target, startTime + target, startTime + target);
- }
-
- [Fact]
- public void Jumping_past_longer_than_recurrence()
- {
- var sut = new ManualTimeProvider();
- var startTime = sut.GetUtcNow();
- var callbackTimes = new List();
- var interval = TimeSpan.FromSeconds(3);
- var target = TimeSpan.FromSeconds(4);
- using var timer = sut.CreateTimer(_ => callbackTimes.Add(sut.GetUtcNow()), null, interval, interval);
-
- sut.Jump(target);
-
- callbackTimes.Should().Equal(startTime + target);
- }
-
- [Fact]
- public void jumping_causes_multiple_timers_invokes_callback_in_order()
- {
- var sut = new ManualTimeProvider();
- var callbacks = new List<(int timerId, TimeSpan callbackTime)>();
- var startTime = sut.GetTimestamp();
- using var timer1 = sut.CreateTimer(_ => callbacks.Add((1, sut.GetElapsedTime(startTime))), null, TimeSpan.FromMilliseconds(3), TimeSpan.FromMilliseconds(3));
- using var timer2 = sut.CreateTimer(_ => callbacks.Add((2, sut.GetElapsedTime(startTime))), null, TimeSpan.FromMilliseconds(3), TimeSpan.FromMilliseconds(3));
- using var timer3 = sut.CreateTimer(_ => callbacks.Add((3, sut.GetElapsedTime(startTime))), null, TimeSpan.FromMilliseconds(6), TimeSpan.FromMilliseconds(5));
-
- sut.Jump(TimeSpan.FromMilliseconds(3));
- sut.Jump(TimeSpan.FromMilliseconds(3));
- sut.Jump(TimeSpan.FromMilliseconds(3));
- sut.Jump(TimeSpan.FromMilliseconds(2));
-
- callbacks.Should().Equal(
- (1, TimeSpan.FromMilliseconds(3)),
- (2, TimeSpan.FromMilliseconds(3)),
- (3, TimeSpan.FromMilliseconds(6)),
- (1, TimeSpan.FromMilliseconds(6)),
- (2, TimeSpan.FromMilliseconds(6)),
- (1, TimeSpan.FromMilliseconds(9)),
- (2, TimeSpan.FromMilliseconds(9)),
- (3, TimeSpan.FromMilliseconds(11)));
- }
-}
\ No newline at end of file
diff --git a/test/TimeProviderExtensions.Tests/ManualTimeProviderWaitAsyncTests.cs b/test/TimeProviderExtensions.Tests/ManualTimeProviderWaitAsyncTests.cs
index 01aa7bb..ab0335f 100644
--- a/test/TimeProviderExtensions.Tests/ManualTimeProviderWaitAsyncTests.cs
+++ b/test/TimeProviderExtensions.Tests/ManualTimeProviderWaitAsyncTests.cs
@@ -4,9 +4,9 @@ namespace TimeProviderExtensions;
public class ManualTimeProviderWaitAsyncTests
{
- internal const uint MaxSupportedTimeout = 0xfffffffe;
- private readonly static TimeSpan DelayedTaskDelay = TimeSpan.FromMilliseconds(2);
- private readonly static string StringTaskResult = Guid.NewGuid().ToString();
+ private const uint MaxSupportedTimeout = 0xfffffffe;
+ private static readonly TimeSpan DelayedTaskDelay = TimeSpan.FromMilliseconds(2);
+ private static readonly string StringTaskResult = Guid.NewGuid().ToString();
private static async Task DelayedTask(TimeProvider provider) => await provider.Delay(DelayedTaskDelay);
diff --git a/test/TimeProviderExtensions.Tests/ManualTimerTests.cs b/test/TimeProviderExtensions.Tests/ManualTimerTests.cs
index e531d9e..1651325 100644
--- a/test/TimeProviderExtensions.Tests/ManualTimerTests.cs
+++ b/test/TimeProviderExtensions.Tests/ManualTimerTests.cs
@@ -137,4 +137,238 @@ public void CallbackInvokeCount_with_disposed_timer()
sut.CallbackInvokeCount.Should().Be(1);
}
+
+ [Fact]
+ public void CreateTimer_with_positive_DueTime_and_infinite_Period()
+ {
+ var callbackCount = 0;
+ var dueTime = TimeSpan.FromSeconds(1);
+ var period = Timeout.InfiniteTimeSpan;
+ var sut = new ManualTimeProvider();
+ using var timer = sut.CreateTimer(_ => callbackCount++, null, dueTime, period);
+
+ sut.Advance(dueTime);
+ callbackCount.Should().Be(1);
+
+ sut.Advance(dueTime);
+ callbackCount.Should().Be(1);
+ }
+
+ [Fact]
+ public void CreateTimer_with_positive_DueTime_and_Period()
+ {
+ var callbackCount = 0;
+ var dueTime = TimeSpan.FromSeconds(1);
+ var period = TimeSpan.FromSeconds(2);
+ var sut = new ManualTimeProvider();
+ using var timer = sut.CreateTimer(_ => callbackCount++, null, dueTime, period);
+
+ sut.Advance(dueTime);
+ callbackCount.Should().Be(1);
+
+ sut.Advance(period);
+ callbackCount.Should().Be(2);
+
+ sut.Advance(period);
+ callbackCount.Should().Be(3);
+ }
+
+ [Fact]
+ public void CreateTimer_with_infinite_DueTime_and_Period()
+ {
+ var callbackCount = 0;
+ var dueTime = Timeout.InfiniteTimeSpan;
+ var period = Timeout.InfiniteTimeSpan;
+ var sut = new ManualTimeProvider();
+ using var timer = sut.CreateTimer(_ => callbackCount++, null, dueTime, period);
+
+ sut.Advance(TimeSpan.FromSeconds(1));
+
+ callbackCount.Should().Be(0);
+ }
+
+ [Fact]
+ public void Change_timer_from_stopped_to_started()
+ {
+ // Arrange
+ var callbackCount = 0;
+ var sut = new ManualTimeProvider();
+ using var timer = sut.CreateTimer(_ => callbackCount++, null, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
+ var dueTime = TimeSpan.FromSeconds(1);
+ var period = TimeSpan.FromSeconds(2);
+
+ // Act
+ timer.Change(dueTime, period);
+
+ // Assert
+ sut.Advance(dueTime);
+ callbackCount.Should().Be(1);
+
+ sut.Advance(period);
+ callbackCount.Should().Be(2);
+
+ sut.Advance(period);
+ callbackCount.Should().Be(3);
+ }
+
+ [Fact]
+ public void Change_timer()
+ {
+ // Arrange
+ var callbackCount = 0;
+ var sut = new ManualTimeProvider();
+ var originalDueTime = TimeSpan.FromSeconds(3);
+ var period = TimeSpan.FromSeconds(5);
+ using var timer = sut.CreateTimer(_ => callbackCount++, null, originalDueTime, period);
+ var dueTime = TimeSpan.FromSeconds(4);
+
+ // Change to a larger value
+ timer.Change(dueTime, period);
+
+ // Assert that previous dueTime is ignored
+ sut.Advance(originalDueTime);
+ callbackCount.Should().Be(0);
+
+ sut.Advance(dueTime);
+ callbackCount.Should().Be(1);
+
+ sut.Advance(period);
+ callbackCount.Should().Be(2);
+ }
+
+ [Fact]
+ public void Timer_callback_invoked_multiple_times_single_advance()
+ {
+ var sut = new ManualTimeProvider();
+ var callbackCount = 0;
+ var dueTime = TimeSpan.FromSeconds(3);
+ var period = TimeSpan.FromSeconds(5);
+ using var timer = sut.CreateTimer(_ => callbackCount++, null, dueTime, period);
+
+ sut.Advance(TimeSpan.FromSeconds(13));
+
+ callbackCount.Should().Be(3);
+ }
+
+ [Fact]
+ public void Advancing_GetUtcNow_matches_time_at_callback_time()
+ {
+ var sut = new ManualTimeProvider();
+ var startTime = sut.GetUtcNow();
+ var callbackTimes = new List();
+ var interval = TimeSpan.FromSeconds(3);
+ using var timer = sut.CreateTimer(_ => callbackTimes.Add(sut.GetUtcNow()), null, interval, interval);
+
+ sut.Advance(interval + interval + interval);
+
+ callbackTimes.Should().ContainInOrder(
+ startTime + interval,
+ startTime + interval + interval,
+ startTime + interval + interval + interval);
+ }
+
+ [Fact]
+ public void Disposing_timer_in_callback()
+ {
+ var interval = TimeSpan.FromSeconds(3);
+ var sut = new ManualTimeProvider();
+ ITimer timer = default!;
+ timer = sut.CreateTimer(_ => timer!.Dispose(), null, interval, interval);
+
+ sut.Advance(interval);
+ }
+
+ [Fact]
+ public void Advancing_causes_multiple_timers_invokes_callback_in_order()
+ {
+ var oneSec = TimeSpan.FromSeconds(1);
+ var callbacks = new List<(int TimerNumber, TimeSpan CallbackTime)>();
+ var sut = new ManualTimeProvider();
+ var startTime = sut.GetTimestamp();
+ using var timer1 = sut.CreateTimer(_ => callbacks.Add((1, sut.GetElapsedTime(startTime))), null, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2));
+ using var timer2 = sut.CreateTimer(_ => callbacks.Add((2, sut.GetElapsedTime(startTime))), null, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3));
+
+ sut.Advance(TimeSpan.FromSeconds(11));
+
+ callbacks.Should().Equal(
+ (1, TimeSpan.FromSeconds(2)),
+ (2, TimeSpan.FromSeconds(3)),
+ (1, TimeSpan.FromSeconds(4)),
+ (2, TimeSpan.FromSeconds(6)),
+ (1, TimeSpan.FromSeconds(6)),
+ (1, TimeSpan.FromSeconds(8)),
+ (2, TimeSpan.FromSeconds(9)),
+ (1, TimeSpan.FromSeconds(10)));
+ }
+
+ [Fact]
+ public void Jumping_causes_multiple_timers_invokes_callback_in_order()
+ {
+ var oneSec = TimeSpan.FromSeconds(1);
+ var callbacks = new List();
+ var sut = new ManualTimeProvider();
+ var startTime = sut.GetTimestamp();
+ using var timer1 = sut.CreateTimer(_ => callbacks.Add(1), null, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2));
+ using var timer2 = sut.CreateTimer(_ => callbacks.Add(2), null, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3));
+
+ sut.Advance(TimeSpan.FromSeconds(11));
+
+ callbacks.Should().Equal(1, 2, 1, 2, 1, 1, 2, 1);
+ }
+
+ [Fact]
+ public void Jumping_GetUtcNow_matches_jump_target()
+ {
+ var sut = new ManualTimeProvider();
+ var startTime = sut.GetUtcNow();
+ var callbackTimes = new List();
+ var interval = TimeSpan.FromSeconds(3);
+ var target = interval + interval + interval;
+ using var timer = sut.CreateTimer(_ => callbackTimes.Add(sut.GetUtcNow()), null, interval, interval);
+
+ sut.Jump(target);
+
+ callbackTimes.Should().Equal(startTime + target, startTime + target, startTime + target);
+ }
+
+ [Fact]
+ public void Jumping_past_longer_than_recurrence()
+ {
+ var sut = new ManualTimeProvider();
+ var startTime = sut.GetUtcNow();
+ var callbackTimes = new List();
+ var interval = TimeSpan.FromSeconds(3);
+ var target = TimeSpan.FromSeconds(4);
+ using var timer = sut.CreateTimer(_ => callbackTimes.Add(sut.GetUtcNow()), null, interval, interval);
+
+ sut.Jump(target);
+
+ callbackTimes.Should().Equal(startTime + target);
+ }
+
+ [Fact]
+ public void jumping_causes_multiple_timers_invokes_callback_in_order()
+ {
+ var sut = new ManualTimeProvider();
+ var callbacks = new List<(int timerId, TimeSpan callbackTime)>();
+ var startTime = sut.GetTimestamp();
+ using var timer1 = sut.CreateTimer(_ => callbacks.Add((1, sut.GetElapsedTime(startTime))), null, TimeSpan.FromMilliseconds(3), TimeSpan.FromMilliseconds(3));
+ using var timer2 = sut.CreateTimer(_ => callbacks.Add((2, sut.GetElapsedTime(startTime))), null, TimeSpan.FromMilliseconds(3), TimeSpan.FromMilliseconds(3));
+ using var timer3 = sut.CreateTimer(_ => callbacks.Add((3, sut.GetElapsedTime(startTime))), null, TimeSpan.FromMilliseconds(6), TimeSpan.FromMilliseconds(5));
+
+ sut.Jump(TimeSpan.FromMilliseconds(3));
+ sut.Jump(TimeSpan.FromMilliseconds(3));
+ sut.Jump(TimeSpan.FromMilliseconds(3));
+ sut.Jump(TimeSpan.FromMilliseconds(2));
+
+ callbacks.Should().Equal(
+ (1, TimeSpan.FromMilliseconds(3)),
+ (2, TimeSpan.FromMilliseconds(3)),
+ (3, TimeSpan.FromMilliseconds(6)),
+ (1, TimeSpan.FromMilliseconds(6)),
+ (2, TimeSpan.FromMilliseconds(6)),
+ (1, TimeSpan.FromMilliseconds(9)),
+ (2, TimeSpan.FromMilliseconds(9)),
+ (3, TimeSpan.FromMilliseconds(11)));
+ }
}