71 lines
3 KiB
C#
71 lines
3 KiB
C#
using AcDream.Core.Chat;
|
|
using AcDream.UI.Abstractions.Panels.Chat;
|
|
|
|
namespace AcDream.UI.Abstractions.Tests.Panels.Chat;
|
|
|
|
/// <summary>
|
|
/// Phase K.2 — Tab fires <see cref="AcDream.UI.Abstractions.Input.InputAction.ToggleChatEntry"/>,
|
|
/// which calls <see cref="ChatPanel.FocusInput"/>. The chat panel honors
|
|
/// the request on the very next <see cref="ChatPanel.Render"/> by emitting
|
|
/// a <c>SetKeyboardFocusHere</c> immediately before the input field. After
|
|
/// it fires once, subsequent renders without another <c>FocusInput</c>
|
|
/// call must not re-fire (one-shot semantics) — otherwise the chat field
|
|
/// would steal focus on every frame and the user could never click out.
|
|
/// </summary>
|
|
public sealed class ChatPanelFocusTests
|
|
{
|
|
private sealed class NullBus : AcDream.Runtime.Chat.ICommandBus
|
|
{
|
|
public void Publish<T>(T command) where T : notnull { }
|
|
}
|
|
|
|
[Fact]
|
|
public void FocusInput_NextRender_EmitsSetKeyboardFocusHereBeforeInput()
|
|
{
|
|
var panel = new ChatPanel(new ChatVM(new ChatLog()));
|
|
var renderer = new FakePanelRenderer();
|
|
|
|
panel.FocusInput();
|
|
panel.Render(new PanelContext(0.016f, new NullBus()), renderer);
|
|
|
|
// Find the SetKeyboardFocusHere call; it must come before the
|
|
// InputTextSubmit call so ImGui applies the focus to that widget.
|
|
int focusIdx = -1, inputIdx = -1;
|
|
for (int i = 0; i < renderer.Calls.Count; i++)
|
|
{
|
|
if (renderer.Calls[i].Method == "SetKeyboardFocusHere") focusIdx = i;
|
|
else if (renderer.Calls[i].Method == "InputTextSubmit") inputIdx = i;
|
|
}
|
|
Assert.True(focusIdx >= 0, "ChatPanel must call SetKeyboardFocusHere when FocusInput requested.");
|
|
Assert.True(inputIdx >= 0, "ChatPanel must still render the InputTextSubmit field.");
|
|
Assert.True(focusIdx < inputIdx, "SetKeyboardFocusHere must precede the InputTextSubmit it targets.");
|
|
}
|
|
|
|
[Fact]
|
|
public void Render_WithoutFocusInputCall_DoesNotEmitSetKeyboardFocusHere()
|
|
{
|
|
var panel = new ChatPanel(new ChatVM(new ChatLog()));
|
|
var renderer = new FakePanelRenderer();
|
|
|
|
panel.Render(new PanelContext(0.016f, new NullBus()), renderer);
|
|
|
|
Assert.DoesNotContain(renderer.Calls, c => c.Method == "SetKeyboardFocusHere");
|
|
}
|
|
|
|
[Fact]
|
|
public void FocusInput_OnlyAffectsTheNextRender_OneShot()
|
|
{
|
|
var panel = new ChatPanel(new ChatVM(new ChatLog()));
|
|
|
|
// Frame 1 — FocusInput requested → expect a SetKeyboardFocusHere.
|
|
var r1 = new FakePanelRenderer();
|
|
panel.FocusInput();
|
|
panel.Render(new PanelContext(0.016f, new NullBus()), r1);
|
|
Assert.Contains(r1.Calls, c => c.Method == "SetKeyboardFocusHere");
|
|
|
|
// Frame 2 — no further FocusInput call → must NOT re-fire.
|
|
var r2 = new FakePanelRenderer();
|
|
panel.Render(new PanelContext(0.016f, new NullBus()), r2);
|
|
Assert.DoesNotContain(r2.Calls, c => c.Method == "SetKeyboardFocusHere");
|
|
}
|
|
}
|