Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions Keybinding.Test/ExecuteChordTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) 2023-2026 ktsu-dev contributors

namespace ktsu.Keybinding.Test;

using ktsu.Keybinding.Core.Models;
using ktsu.Keybinding.Core.Services;

[TestClass]
public class ExecuteChordTests
{
private CommandRegistry _registry = null!;
private KeybindingService _service = null!;

[TestInitialize]
public void Setup()
{
_registry = new CommandRegistry();
ProfileManager profiles = new();
profiles.CreateProfile("p", "Profile");
profiles.SetActiveProfile("p");
_service = new KeybindingService(_registry, profiles);

_registry.RegisterCommand(new Command("a", "A"));
_registry.RegisterCommand(new Command("b", "B"));
}

[TestMethod]
public void ExecuteChord_FirstBindingUnregistered_RunsTheRegisteredCommandSharingTheChord()
{
Chord chord = Chord.Parse("Ctrl+S");
Assert.IsTrue(_service.BindChord("a", chord));
Assert.IsTrue(_service.BindChord("b", chord));

_registry.UnregisterCommand("a");

Assert.AreEqual("b", _service.ExecuteChord(chord), "The only registered command bound to the chord should run.");
Assert.AreEqual("b", _service.ExecuteChord("p", chord));
}

[TestMethod]
public void ExecuteChord_BothRegistered_RunsTheFirstBinding()
{
Chord chord = Chord.Parse("Ctrl+S");
_service.BindChord("a", chord);
_service.BindChord("b", chord);

Assert.AreEqual(_service.FindCommandByChord(chord), _service.ExecuteChord(chord));
}

[TestMethod]
public void ExecuteChord_OnlyBindingUnregistered_ReturnsNull()
{
Chord chord = Chord.Parse("Ctrl+S");
_service.BindChord("a", chord);

_registry.UnregisterCommand("a");

Assert.IsNull(_service.ExecuteChord(chord));
}

[TestMethod]
public void ExecuteChord_UnknownProfile_ReturnsNull()
{
Chord chord = Chord.Parse("Ctrl+S");
_service.BindChord("a", chord);

Assert.IsNull(_service.ExecuteChord("missing", chord));
Assert.IsNull(_service.ExecuteChord(" ", chord));
}
}
19 changes: 13 additions & 6 deletions Keybinding/Services/KeybindingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
throw new ArgumentException("Profile ID cannot be null or whitespace", nameof(id));
}

ArgumentException.ThrowIfNullOrWhiteSpace(name, nameof(name));

Check warning on line 39 in Keybinding/Services/KeybindingService.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Remove this argument from the method call; it hides the caller information.

Check warning on line 39 in Keybinding/Services/KeybindingService.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Remove this argument from the method call; it hides the caller information.

Check warning on line 39 in Keybinding/Services/KeybindingService.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Remove this argument from the method call; it hides the caller information.

Check warning on line 39 in Keybinding/Services/KeybindingService.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Remove this argument from the method call; it hides the caller information.

Check warning on line 39 in Keybinding/Services/KeybindingService.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Remove this argument from the method call; it hides the caller information.

Check warning on line 39 in Keybinding/Services/KeybindingService.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Remove this argument from the method call; it hides the caller information.

Check warning on line 39 in Keybinding/Services/KeybindingService.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Remove this argument from the method call; it hides the caller information.

Check warning on line 39 in Keybinding/Services/KeybindingService.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Remove this argument from the method call; it hides the caller information.

Check warning on line 39 in Keybinding/Services/KeybindingService.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Remove this argument from the method call; it hides the caller information.

Check warning on line 39 in Keybinding/Services/KeybindingService.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Remove this argument from the method call; it hides the caller information.

return _profileManager.CreateProfile(id, name, description);
}
Expand Down Expand Up @@ -228,15 +228,22 @@
{
Ensure.NotNull(chord);

string? commandId = FindCommandByChord(profileId, chord);
if (commandId is not null && _commandRegistry.IsCommandRegistered(commandId))
if (string.IsNullOrWhiteSpace(profileId))
{
// In a real implementation, this would trigger command execution
// For now, we just return the command ID that would be executed
return commandId;
return null;
}

return null;
// A chord can be bound to more than one command, and unregistering a command leaves its
// bindings in place, so skip bindings whose command is no longer registered rather than
// giving up on the first match.
Profile? profile = _profileManager.GetProfile(profileId);
string? commandId = profile?.Chords
.FirstOrDefault(kvp => kvp.Value.Equals(chord) && _commandRegistry.IsCommandRegistered(kvp.Key))
.Key;

// In a real implementation, this would trigger command execution
// For now, we just return the command ID that would be executed
return commandId;
}

/// <inheritdoc/>
Expand Down
Loading