130 lines
3.3 KiB
C#
130 lines
3.3 KiB
C#
using CursorLang.Core.Threading;
|
|
using CursorLang.Tests.Shared;
|
|
|
|
namespace CursorLang.Core.Tests.Threading;
|
|
|
|
/// <summary>
|
|
/// The timer the agent has instead of a dispatcher timer.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// It ticks on the message loop, so everything here runs on the pump thread — a timer
|
|
/// started on one thread and awaited on another would never be seen to fire.
|
|
/// </remarks>
|
|
public sealed class MessageTimerTests
|
|
{
|
|
[Fact]
|
|
public void A_started_timer_ticks()
|
|
{
|
|
int ticks = 0;
|
|
|
|
Pump.Run(() =>
|
|
{
|
|
using var timer = new MessageTimer();
|
|
timer.Interval = TimeSpan.FromMilliseconds(15);
|
|
timer.Tick += (_, _) => ticks++;
|
|
timer.Start();
|
|
|
|
Pump.WaitFor(() => ticks > 0, "the timer ticked");
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void A_timer_keeps_ticking_until_it_is_stopped()
|
|
{
|
|
var ticks = 0;
|
|
|
|
Pump.Run(() =>
|
|
{
|
|
using var timer = new MessageTimer();
|
|
timer.Interval = TimeSpan.FromMilliseconds(15);
|
|
timer.Tick += (_, _) => ticks++;
|
|
timer.Start();
|
|
|
|
Pump.WaitFor(() => ticks >= 3, "the timer ticked more than once");
|
|
});
|
|
}
|
|
|
|
// A stopped countdown does not go off, however long the loop runs afterwards
|
|
[Fact]
|
|
public void A_stopped_timer_does_not_tick()
|
|
{
|
|
var ticks = 0;
|
|
|
|
Pump.Run(() =>
|
|
{
|
|
using var timer = new MessageTimer();
|
|
timer.Interval = TimeSpan.FromMilliseconds(10);
|
|
timer.Tick += (_, _) => ticks++;
|
|
timer.Start();
|
|
timer.Stop();
|
|
|
|
Pump.Pause(TimeSpan.FromMilliseconds(80));
|
|
});
|
|
|
|
Assert.Equal(0, ticks);
|
|
}
|
|
|
|
// Restarting means from zero, so a countdown kept short by repeated restarts
|
|
// never reaches its end
|
|
[Fact]
|
|
public void Restarting_begins_the_countdown_again()
|
|
{
|
|
var ticks = 0;
|
|
|
|
Pump.Run(() =>
|
|
{
|
|
using var timer = new MessageTimer();
|
|
timer.Interval = TimeSpan.FromMilliseconds(60);
|
|
timer.Tick += (_, _) => ticks++;
|
|
|
|
for (var i = 0; i < 6; i++)
|
|
{
|
|
timer.Start();
|
|
Pump.Pause(TimeSpan.FromMilliseconds(20));
|
|
}
|
|
|
|
Assert.Equal(0, ticks);
|
|
|
|
Pump.WaitFor(() => ticks > 0, "left alone, the timer reached its end");
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void Closing_the_timer_ends_the_ticking()
|
|
{
|
|
var ticks = 0;
|
|
|
|
Pump.Run(() =>
|
|
{
|
|
var timer = new MessageTimer { Interval = TimeSpan.FromMilliseconds(15) };
|
|
timer.Tick += (_, _) => ticks++;
|
|
timer.Start();
|
|
|
|
Pump.WaitFor(() => ticks > 0, "the timer ticked");
|
|
timer.Dispose();
|
|
|
|
int seen = ticks;
|
|
Pump.Pause(TimeSpan.FromMilliseconds(80));
|
|
|
|
Assert.Equal(seen, ticks);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void A_timer_that_was_never_started_says_so()
|
|
{
|
|
Pump.Run(() =>
|
|
{
|
|
using var timer = new MessageTimer();
|
|
|
|
Assert.False(timer.IsRunning);
|
|
|
|
timer.Start();
|
|
Assert.True(timer.IsRunning);
|
|
|
|
timer.Stop();
|
|
Assert.False(timer.IsRunning);
|
|
});
|
|
}
|
|
}
|