| 1 | using Avalonia.Input; |
| 2 | using CascadeIDE.Services; |
| 3 | using Xunit; |
| 4 | |
| 5 | namespace CascadeIDE.Tests; |
| 6 | |
| 7 | public sealed class CascadeChordHotkeyTests |
| 8 | { |
| 9 | private static void AssertGestureEqual(KeyGesture expected, KeyGesture actual) |
| 10 | { |
| 11 | Assert.Equal(expected.Key, actual.Key); |
| 12 | Assert.Equal(expected.KeyModifiers, actual.KeyModifiers); |
| 13 | } |
| 14 | |
| 15 | [Fact] |
| 16 | public void ResolveRootGesture_MissingCascadeChord_UsesDefaultCtrlK() |
| 17 | { |
| 18 | var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) |
| 19 | { |
| 20 | ["toggle_command_palette"] = "Ctrl+Q" |
| 21 | }; |
| 22 | var g = CascadeChordHotkey.ResolveRootGesture(map); |
| 23 | AssertGestureEqual(KeyGesture.Parse(CascadeChordHotkey.DefaultGestureString), g); |
| 24 | } |
| 25 | |
| 26 | [Fact] |
| 27 | public void ResolveRootGesture_EmptyCascadeChord_UsesDefaultCtrlK() |
| 28 | { |
| 29 | var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) |
| 30 | { |
| 31 | [CascadeChordHotkey.TomlKey] = " " |
| 32 | }; |
| 33 | var g = CascadeChordHotkey.ResolveRootGesture(map); |
| 34 | AssertGestureEqual(KeyGesture.Parse(CascadeChordHotkey.DefaultGestureString), g); |
| 35 | } |
| 36 | |
| 37 | [Fact] |
| 38 | public void ResolveRootGesture_ValidCustom_Parses() |
| 39 | { |
| 40 | var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) |
| 41 | { |
| 42 | [CascadeChordHotkey.TomlKey] = "Ctrl+Shift+K" |
| 43 | }; |
| 44 | var g = CascadeChordHotkey.ResolveRootGesture(map); |
| 45 | AssertGestureEqual(KeyGesture.Parse("Ctrl+Shift+K"), g); |
| 46 | } |
| 47 | |
| 48 | [Fact] |
| 49 | public void ResolveRootGesture_InvalidString_FallsBackToCtrlK() |
| 50 | { |
| 51 | var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) |
| 52 | { |
| 53 | [CascadeChordHotkey.TomlKey] = "%%%not_a_valid_gesture%%%" |
| 54 | }; |
| 55 | var g = CascadeChordHotkey.ResolveRootGesture(map); |
| 56 | AssertGestureEqual(KeyGesture.Parse(CascadeChordHotkey.DefaultGestureString), g); |
| 57 | } |
| 58 | |
| 59 | [Fact] |
| 60 | public void MatchesPhysicalKeyFallback_CtrlK_NormalizedModifiers() |
| 61 | { |
| 62 | var resolved = KeyGesture.Parse("Ctrl+K"); |
| 63 | Assert.True(CascadeChordHotkey.MatchesPhysicalKeyFallback(resolved, PhysicalKey.K, KeyModifiers.Control)); |
| 64 | Assert.False(CascadeChordHotkey.MatchesPhysicalKeyFallback(resolved, PhysicalKey.K, KeyModifiers.Control | KeyModifiers.Shift)); |
| 65 | Assert.False(CascadeChordHotkey.MatchesPhysicalKeyFallback(resolved, PhysicalKey.J, KeyModifiers.Control)); |
| 66 | } |
| 67 | |
| 68 | [Fact] |
| 69 | public void NormalizeChordModifiers_StripsBitsOutsideChordMask() |
| 70 | { |
| 71 | var stripped = KeyGestureChordMatching.NormalizeChordModifiers( |
| 72 | KeyModifiers.Control | (KeyModifiers)0x10000); |
| 73 | Assert.Equal(KeyModifiers.Control, stripped); |
| 74 | } |
| 75 | } |
| 76 | |