added sending closing event message to settings windows (#7)
Release / release (push) Successful in 5m7s
Release / release (push) Successful in 5m7s
Reviewed-on: #7 Co-authored-by: Aleksandr Neychev <alexnejchev73@gmail.com>
This commit was merged in pull request #7.
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
using System.Collections.Concurrent;
|
||||
using CursorLang.Core.Services;
|
||||
using CursorLang.Tests.Shared;
|
||||
|
||||
namespace CursorLang.Core.Tests.Services;
|
||||
|
||||
/// <summary>
|
||||
/// The one thing the agent says to the settings window: quit with me.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The event names here are the tests' own. The application's name is fixed, and a test
|
||||
/// listening on it would answer for a settings window someone is using — or, signalling,
|
||||
/// close it.
|
||||
/// </remarks>
|
||||
public sealed class SettingsCloseSignalTests
|
||||
{
|
||||
[Fact]
|
||||
public void The_request_reaches_the_settings_window()
|
||||
{
|
||||
string suffix = UniqueSuffix();
|
||||
var signal = new SettingsCloseSignal(suffix);
|
||||
|
||||
ConcurrentQueue<EventArgs> requests = new();
|
||||
signal.CloseRequested += (_, e) => requests.Enqueue(e);
|
||||
|
||||
try
|
||||
{
|
||||
signal.Listen();
|
||||
|
||||
Assert.True(RequestApart(suffix), "the request found nobody listening");
|
||||
Pump.WaitFor(() => !requests.IsEmpty, "the settings window got the request to close");
|
||||
}
|
||||
finally
|
||||
{
|
||||
signal.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
// The usual case: the user quits from the tray with no settings window on the screen
|
||||
[Fact]
|
||||
public void A_request_with_no_settings_window_open_passes_without_consequence()
|
||||
{
|
||||
Assert.False(RequestApart(UniqueSuffix()));
|
||||
}
|
||||
|
||||
// The window has closed on its own, and the process is on its way out anyway
|
||||
[Fact]
|
||||
public void No_request_arrives_after_the_window_is_gone()
|
||||
{
|
||||
string suffix = UniqueSuffix();
|
||||
var signal = new SettingsCloseSignal(suffix);
|
||||
|
||||
ConcurrentQueue<EventArgs> requests = new();
|
||||
signal.CloseRequested += (_, e) => requests.Enqueue(e);
|
||||
|
||||
signal.Listen();
|
||||
signal.Dispose();
|
||||
|
||||
RequestApart(suffix);
|
||||
Pump.Pause(TimeSpan.FromMilliseconds(80));
|
||||
|
||||
Assert.Empty(requests);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Listening_twice_leaves_one_listener()
|
||||
{
|
||||
string suffix = UniqueSuffix();
|
||||
var signal = new SettingsCloseSignal(suffix);
|
||||
|
||||
var requests = 0;
|
||||
signal.CloseRequested += (_, _) => Interlocked.Increment(ref requests);
|
||||
|
||||
try
|
||||
{
|
||||
signal.Listen();
|
||||
signal.Listen();
|
||||
|
||||
Assert.True(RequestApart(suffix));
|
||||
Pump.WaitFor(() => Volatile.Read(ref requests) > 0, "the request arrived");
|
||||
Pump.Pause(TimeSpan.FromMilliseconds(80));
|
||||
|
||||
Assert.Equal(1, Volatile.Read(ref requests));
|
||||
}
|
||||
finally
|
||||
{
|
||||
signal.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Closing_without_listening_passes_without_consequence()
|
||||
{
|
||||
var signal = new SettingsCloseSignal(UniqueSuffix());
|
||||
|
||||
signal.Dispose();
|
||||
signal.Dispose();
|
||||
}
|
||||
|
||||
// Every test gets a namespace of kernel objects of its own
|
||||
private static string UniqueSuffix() => "." + Guid.NewGuid().ToString("N");
|
||||
|
||||
/// <summary>
|
||||
/// Asks for the close the way the agent does it — from another process, and here
|
||||
/// from another thread, which is as foreign as a test can get.
|
||||
/// </summary>
|
||||
private static bool RequestApart(string suffix)
|
||||
{
|
||||
var heard = false;
|
||||
|
||||
Pump.RunApart(() => heard = SettingsCloseSignal.RequestClose(suffix));
|
||||
|
||||
return heard;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user