using CursorLang.Agent.Services; using CursorLang.Core.Models; using CursorLang.Tests.Shared; namespace CursorLang.Agent.Tests.Services; /// /// The lifetime of the tooltip. Its timer ticks on the message loop, /// so everything happens on the pump thread as well. /// public sealed class LayoutPopupServiceTests { private static readonly KeyboardLayout Russian = KeyboardLayout.FromLocaleId(0x0419); private static readonly KeyboardLayout English = KeyboardLayout.FromLocaleId(0x0409); [Fact] public void Showing_puts_out_the_short_name_of_the_layout() { var window = new FakeLayoutPopupWindow(); var settings = new AppSettings { DurationMilliseconds = 10_000 }; Pump.Run(() => { using var service = new LayoutPopupService(window, settings); service.Show(Russian); }); Assert.Equal("RU", window.ShownText); Assert.Equal(1, window.ShowCalls); } [Fact] public void The_tooltip_goes_away_once_its_time_is_up() { var window = new FakeLayoutPopupWindow(); var settings = new AppSettings { DurationMilliseconds = 30 }; Pump.Run(() => { using var service = new LayoutPopupService(window, settings); service.Show(Russian); Assert.Equal(0, window.HideCalls); Pump.WaitFor(() => window.HideCalls == 1, "the tooltip hid itself"); }); } // The duration is read on every show: it is edited in the settings on the fly [Fact] public void A_new_duration_takes_effect_from_the_next_show() { var window = new FakeLayoutPopupWindow(); var settings = new AppSettings { DurationMilliseconds = 10_000 }; Pump.Run(() => { using var service = new LayoutPopupService(window, settings); service.Show(Russian); settings.DurationMilliseconds = 30; service.Show(English); Pump.WaitFor(() => window.HideCalls == 1, "the tooltip hid by the new duration"); }); } // Quick switching must not cut the tooltip off mid-word [Fact] public void Showing_again_extends_the_time_on_screen() { var window = new FakeLayoutPopupWindow(); var settings = new AppSettings { DurationMilliseconds = 60 }; Pump.Run(() => { using var service = new LayoutPopupService(window, settings); for (int i = 0; i < 5; i++) { service.Show(i % 2 == 0 ? Russian : English); Pump.Pause(TimeSpan.FromMilliseconds(20)); Assert.Equal(0, window.HideCalls); } Pump.WaitFor(() => window.HideCalls == 1, "the tooltip hid after the last show"); }); } [Fact] public void A_show_until_hidden_does_not_hide_by_itself() { var window = new FakeLayoutPopupWindow(); var settings = new AppSettings { DurationMilliseconds = 20 }; Pump.Run(() => { using var service = new LayoutPopupService(window, settings); service.ShowUntilHidden(Russian); Pump.Pause(TimeSpan.FromMilliseconds(80)); Assert.Equal(1, window.ShowCalls); Assert.Equal(0, window.HideCalls); service.Hide(); Assert.Equal(1, window.HideCalls); }); } // A show until hidden on top of an ordinary one also cancels the countdown [Fact] public void A_show_until_hidden_stops_a_running_countdown() { var window = new FakeLayoutPopupWindow(); var settings = new AppSettings { DurationMilliseconds = 30 }; Pump.Run(() => { using var service = new LayoutPopupService(window, settings); service.Show(Russian); service.ShowUntilHidden(English); Pump.Pause(TimeSpan.FromMilliseconds(100)); Assert.Equal(0, window.HideCalls); Assert.Equal("EN", window.ShownText); }); } [Fact] public void Hiding_cancels_a_running_countdown() { var window = new FakeLayoutPopupWindow(); var settings = new AppSettings { DurationMilliseconds = 30 }; Pump.Run(() => { using var service = new LayoutPopupService(window, settings); service.Show(Russian); service.Hide(); Pump.Pause(TimeSpan.FromMilliseconds(100)); // There must be no second hide from the timer Assert.Equal(1, window.HideCalls); }); } [Fact] public void Closing_the_service_closes_the_window() { var window = new FakeLayoutPopupWindow(); var settings = new AppSettings(); Pump.Run(() => { var service = new LayoutPopupService(window, settings); service.Show(Russian); service.Dispose(); Pump.Pause(TimeSpan.FromMilliseconds(50)); }); Assert.Equal(1, window.CloseCalls); } [Fact] public void After_the_service_is_closed_the_timer_stays_silent() { var window = new FakeLayoutPopupWindow(); var settings = new AppSettings { DurationMilliseconds = 20 }; Pump.Run(() => { var service = new LayoutPopupService(window, settings); service.Show(Russian); service.Dispose(); Pump.Pause(TimeSpan.FromMilliseconds(80)); Assert.Equal(0, window.HideCalls); }); } [Fact] public void Showing_always_comes_before_hiding() { var window = new FakeLayoutPopupWindow(); var settings = new AppSettings { DurationMilliseconds = 20 }; Pump.Run(() => { using var service = new LayoutPopupService(window, settings); service.Show(Russian); Pump.WaitFor(() => window.HideCalls == 1, "the tooltip hid itself"); Assert.Equal(["show", "hide"], window.Calls); }); } }