using System.ComponentModel; using CursorLang.Core.Models; using CursorLang.Core.Services; namespace CursorLang.Tests.Shared; /// /// The keyboard layout, with the test in charge of it. /// public sealed class FakeKeyboardLayoutService : IKeyboardLayoutService { public int StartCalls { get; private set; } public int StopCalls { get; private set; } public int SwitchCalls { get; private set; } public KeyboardLayout CurrentLayout { get; set; } = KeyboardLayout.FromLocaleId(0x0409); public KeyboardLayout Current => CurrentLayout; public event EventHandler? LayoutChanged; public void Start() => StartCalls++; public void Stop() => StopCalls++; public void SwitchToNext() => SwitchCalls++; public void RaiseLayoutChanged(KeyboardLayout layout, LayoutChangeReason reason) => LayoutChanged?.Invoke(this, new LayoutChangedEventArgs(layout, reason)); public bool HasSubscribers => LayoutChanged is not null; } /// /// A tooltip that pops up nowhere and merely remembers what it was asked for. /// public sealed class FakeLayoutPopupService : ILayoutPopupService { public List Shown { get; } = []; public List ShownUntilHidden { get; } = []; public int HideCalls { get; private set; } public void Show(KeyboardLayout layout) => Shown.Add(layout); public void ShowUntilHidden(KeyboardLayout layout) => ShownUntilHidden.Add(layout); public void Hide() => HideCalls++; } /// /// The Caps Lock interception without intercepting anything: the test supplies the presses. /// public sealed class FakeCapsLockHotkeyService : ICapsLockHotkeyService { public event EventHandler? Tapped; public event EventHandler? HoldStarted; public event EventHandler? HoldEnded; public bool IsRunning { get; private set; } public int StartCalls { get; private set; } public int StopCalls { get; private set; } public void Start() { StartCalls++; IsRunning = true; } public void Stop() { StopCalls++; IsRunning = false; } public void RaiseTapped() => Tapped?.Invoke(this, EventArgs.Empty); public void RaiseHoldStarted() => HoldStarted?.Invoke(this, EventArgs.Empty); public void RaiseHoldEnded() => HoldEnded?.Invoke(this, EventArgs.Empty); public bool HasSubscribers => Tapped is not null || HoldStarted is not null || HoldEnded is not null; } /// /// Startup whose state the test assigns. /// public sealed class FakeStartupService : IStartupService { public StartupState State { get; set; } = StartupState.Disabled; public StartupState? AnswerOnEnable { get; set; } public List Requests { get; } = []; public int GetStateCalls { get; private set; } public Task GetStateAsync() { GetStateCalls++; return Task.FromResult(State); } public Task SetEnabledAsync(bool enabled) { Requests.Add(enabled); State = enabled ? AnswerOnEnable ?? StartupState.Enabled : StartupState.Disabled; return Task.FromResult(State); } } /// /// Interface strings without resources: the key comes back as is, tagged with the language. /// public sealed class FakeLocalizationService : ILocalizationService { private string _currentLanguage = "en"; public event PropertyChangedEventHandler? PropertyChanged; public List RequestedKeys { get; } = []; /// /// Strings the test writes out in full — for the ones it puts values into. /// public Dictionary Strings { get; } = []; public string this[string key] { get { RequestedKeys.Add(key); return Strings.TryGetValue(key, out string? value) ? value : $"{_currentLanguage}:{key}"; } } public IReadOnlyList AvailableLanguages { get; } = [ new("en", "English"), new("ru", "Русский"), ]; public string CurrentLanguage { get => _currentLanguage; set { if (string.IsNullOrWhiteSpace(value) || value == _currentLanguage) { return; } _currentLanguage = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurrentLanguage))); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(LocalizationService.IndexerName)); } } } /// /// A tooltip window that shows nothing. /// public sealed class FakeLayoutPopupWindow : ILayoutPopupWindow { public int ShowCalls { get; private set; } public int HideCalls { get; private set; } public int CloseCalls { get; private set; } public List Calls { get; } = []; public string? ShownText { get; private set; } public void ShowPopup(string shortName) { ShowCalls++; ShownText = shortName; Calls.Add("show"); } public void Hide() { HideCalls++; Calls.Add("hide"); } public void Close() { CloseCalls++; Calls.Add("close"); } }