feat(D.2b): extract ChatCommandRouter — shared chat submit pipeline
Both the ImGui devtools ChatPanel and the upcoming retail chat window now route through ChatCommandRouter.Submit so command handling lives in one place. The ChatPanel inline block (TryHandleClientCommand / EqAny / BuildHelpText) is deleted; ChatCommandRouter carries the same logic verbatim. ChatPanel.Render becomes a 2-line delegate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3d25e8760f
commit
50883e445b
3 changed files with 153 additions and 122 deletions
|
|
@ -0,0 +1,74 @@
|
|||
using AcDream.Core.Chat;
|
||||
using AcDream.UI.Abstractions;
|
||||
using AcDream.UI.Abstractions.Panels.Chat;
|
||||
using Xunit;
|
||||
|
||||
namespace AcDream.UI.Abstractions.Tests.Panels.Chat;
|
||||
|
||||
public class ChatCommandRouterTests
|
||||
{
|
||||
private sealed class CaptureBus : ICommandBus
|
||||
{
|
||||
public SendChatCmd? Last;
|
||||
public void Publish<T>(T command) where T : notnull
|
||||
{
|
||||
if (command is SendChatCmd c) Last = c;
|
||||
}
|
||||
}
|
||||
|
||||
private static (ChatVM vm, ChatLog log, CaptureBus bus) Fixture()
|
||||
{
|
||||
var log = new ChatLog();
|
||||
var vm = new ChatVM(log, displayLimit: 50);
|
||||
return (vm, log, new CaptureBus());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PlainText_PublishesOnDefaultChannel()
|
||||
{
|
||||
var (vm, _, bus) = Fixture();
|
||||
var outcome = ChatCommandRouter.Submit("hello there", vm, bus, ChatChannelKind.Say);
|
||||
Assert.Equal(SubmitOutcome.Sent, outcome);
|
||||
Assert.NotNull(bus.Last);
|
||||
Assert.Equal(ChatChannelKind.Say, bus.Last!.Channel);
|
||||
Assert.Equal("hello there", bus.Last.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DefaultChannel_IsHonored()
|
||||
{
|
||||
var (vm, _, bus) = Fixture();
|
||||
ChatCommandRouter.Submit("hi", vm, bus, ChatChannelKind.Fellowship);
|
||||
Assert.Equal(ChatChannelKind.Fellowship, bus.Last!.Channel);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ClearCommand_DrainsLog_DoesNotPublish()
|
||||
{
|
||||
var (vm, log, bus) = Fixture();
|
||||
log.OnSystemMessage("x", chatType: 0);
|
||||
var outcome = ChatCommandRouter.Submit("/clear", vm, bus, ChatChannelKind.Say);
|
||||
Assert.Equal(SubmitOutcome.ClientHandled, outcome);
|
||||
Assert.Null(bus.Last);
|
||||
Assert.Empty(log.Snapshot());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnknownSlashVerb_ShowsSystemMessage_DoesNotPublish()
|
||||
{
|
||||
var (vm, log, bus) = Fixture();
|
||||
var outcome = ChatCommandRouter.Submit("/notacommand", vm, bus, ChatChannelKind.Say);
|
||||
Assert.Equal(SubmitOutcome.UnknownCommand, outcome);
|
||||
Assert.Null(bus.Last);
|
||||
Assert.Contains(log.Snapshot(), e => e.Text.Contains("Unknown command"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyInput_DoesNothing()
|
||||
{
|
||||
var (vm, _, bus) = Fixture();
|
||||
var outcome = ChatCommandRouter.Submit(" ", vm, bus, ChatChannelKind.Say);
|
||||
Assert.Equal(SubmitOutcome.Empty, outcome);
|
||||
Assert.Null(bus.Last);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue