The first sweep matched a character class that swallowed the digit, so a bare B1 slipped through while B1-2 was caught. Searching the whole A-Z space instead of guessing prefixes turned up 130-odd more: B0 through B6, C2, C3, D1, H2, M6, P7, P8, T2, W2, plus GP-04, KB-01, OD-1, PM-1, PM-3, SEC-01, TR-4, TR-7, UI-11, UI-12, XC-8 and API-3. Kept deliberately: 41 B4 01 is a byte signature, "N0" a format string, #L119-L128 a source anchor, LS4/LS6 are linkshells, and A=FF B=0C G=41 R=C2 explains a colour-channel order. Those look like codes and are not. Also translated the eight German comments left in the theme files and ImGuiUtil. Seven of them described what a palette does to which channel, which is worth reading -- just not in a second language in an otherwise English codebase.
60 lines
2.1 KiB
C#
60 lines
2.1 KiB
C#
using Dalamud.Bindings.ImGui;
|
|
using Dalamud.Plugin.SelfTest;
|
|
|
|
namespace HellionChat.SelfTests;
|
|
|
|
// Only the snap decision is headless-testable. Scroll detection + bar +
|
|
// hit-test are smoke-only (the scroll child exists only in-game; GetScrollY is
|
|
// garbage headless). Drives ResolveSnapToBottom via the SelfTest accessor and
|
|
// asserts the OR + the request reset invariant.
|
|
// Uses the mandatory RequestScrollToBottomForSelfTest() setter (added in Step 1)
|
|
// to flip _scrollToBottomRequested without a real click — REQUIRED for the reset
|
|
// invariant assert; without it only the OR branch is testable.
|
|
internal sealed class ScrollSnapDecisionStep : ISelfTestStep
|
|
{
|
|
private readonly Plugin plugin;
|
|
|
|
public ScrollSnapDecisionStep(Plugin plugin) => this.plugin = plugin;
|
|
|
|
public string Name => "Hellion Chat - Scroll snap decision";
|
|
|
|
public SelfTestStepResult RunStep()
|
|
{
|
|
var messages = plugin.MainWindow.GetMessageListForSelfTest();
|
|
if (messages is null)
|
|
{
|
|
ImGui.Text("MessageList null");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
// Start-state hygiene: a real click this frame could leave a pending
|
|
// request behind. Drain it so the asserts below are order-independent.
|
|
// Acceptable side effect: the drained click is swallowed and its snap
|
|
// never happens — losing one click mid-selftest is irrelevant.
|
|
messages.ResolveSnapToBottom(false);
|
|
|
|
if (!messages.ResolveSnapToBottom(true))
|
|
{
|
|
ImGui.Text("pinnedToBottom=true must snap");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
messages.RequestScrollToBottomForSelfTest();
|
|
if (!messages.ResolveSnapToBottom(false))
|
|
{
|
|
ImGui.Text("pending request must snap even when not pinned");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
if (messages.ResolveSnapToBottom(false))
|
|
{
|
|
ImGui.Text("request must be consumed by one snap (reset invariant)");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
return SelfTestStepResult.Pass;
|
|
}
|
|
|
|
public void CleanUp() { }
|
|
}
|