test(selftest): pin the top-tab underline invariant
TopTabBar had no observability at all -- no counter, no self-test reaching it. It now exposes LastRenderedUnderlineCount and MainWindow hands the component out the same way it already does for the sidebar. Three cases: one of two tabs active draws exactly one underline, a null active tab draws zero, and an active tab that is not in the list also draws zero. The last one matters because the strip skips popped-out tabs, so the active tab legitimately need not be among the drawn ones.
This commit is contained in:
@@ -455,6 +455,7 @@ public sealed class Plugin : IAsyncDalamudPlugin
|
||||
new SelfTests.CurrentTabCouplingStep(this),
|
||||
new SelfTests.SidebarUnreadDotStep(this),
|
||||
new SelfTests.SidebarActiveSurfaceStep(this),
|
||||
new SelfTests.TopTabUnderlineStep(this),
|
||||
new SelfTests.UnreadDecisionStep(),
|
||||
new SelfTests.CurrentTabGuidedStep(this),
|
||||
new SelfTests.CardClipPlanStep(this),
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Plugin.SelfTest;
|
||||
using HellionChat.Code;
|
||||
|
||||
namespace HellionChat.SelfTests;
|
||||
|
||||
// v1.10.0/D1: the top-tab strip marks the active tab with a fill plus an accent
|
||||
// underline. Drives the real TopTabBar.Draw and reads the render counter.
|
||||
//
|
||||
// "At most one", not "exactly one": the strip skips popped-out tabs, so zero
|
||||
// underlines is a legitimate state.
|
||||
internal sealed class TopTabUnderlineStep : ISelfTestStep
|
||||
{
|
||||
private readonly Plugin _plugin;
|
||||
|
||||
public TopTabUnderlineStep(Plugin plugin) => _plugin = plugin;
|
||||
|
||||
public string Name => "Hellion Chat - Top tab underline";
|
||||
|
||||
public SelfTestStepResult RunStep()
|
||||
{
|
||||
var strip = _plugin.MainWindow.GetTopTabsForSelfTest();
|
||||
if (strip is null)
|
||||
{
|
||||
ImGui.Text("TopTabBar null");
|
||||
SelfTestReport.Append(Name, "FAIL", new[] { "TopTabBar null" });
|
||||
return SelfTestStepResult.Fail;
|
||||
}
|
||||
|
||||
var a = NewProbe("Underline Probe A@SelfTest");
|
||||
var b = NewProbe("Underline Probe B@SelfTest");
|
||||
var list = new List<Tab> { a, b };
|
||||
|
||||
// (a) one of two tabs active -> exactly one underline
|
||||
Tab? active = a;
|
||||
strip.Draw(list, ref active);
|
||||
if (strip.LastRenderedUnderlineCount != 1)
|
||||
return Fail(
|
||||
$"active tab drew {strip.LastRenderedUnderlineCount} underlines, expected 1"
|
||||
);
|
||||
|
||||
// (b) no active tab -> zero, not a crash
|
||||
active = null;
|
||||
strip.Draw(list, ref active);
|
||||
if (strip.LastRenderedUnderlineCount != 0)
|
||||
return Fail($"null active drew {strip.LastRenderedUnderlineCount}, expected 0");
|
||||
|
||||
// (c) an active tab that is not in the list -> still zero
|
||||
active = NewProbe("Absent@SelfTest");
|
||||
strip.Draw(list, ref active);
|
||||
if (strip.LastRenderedUnderlineCount != 0)
|
||||
return Fail($"absent active drew {strip.LastRenderedUnderlineCount}, expected 0");
|
||||
|
||||
SelfTestReport.Append(Name, "PASS", new[] { "1 / 0 / 0 across the three cases" });
|
||||
return SelfTestStepResult.Pass;
|
||||
}
|
||||
|
||||
private static Tab NewProbe(string name) =>
|
||||
new()
|
||||
{
|
||||
Name = name,
|
||||
SelectedChannels = new Dictionary<ChatType, (ChatSource, ChatSource)>
|
||||
{
|
||||
[ChatType.Say] = (ChatSourceExt.All, ChatSourceExt.All),
|
||||
},
|
||||
};
|
||||
|
||||
private SelfTestStepResult Fail(string message)
|
||||
{
|
||||
ImGui.Text(message);
|
||||
SelfTestReport.Append(Name, "FAIL", new[] { message });
|
||||
return SelfTestStepResult.Fail;
|
||||
}
|
||||
|
||||
public void CleanUp() { }
|
||||
}
|
||||
@@ -204,6 +204,8 @@ internal sealed class MainWindow : Window, IFocusableChatWindow
|
||||
|
||||
internal Components.MessageList GetMessageListForSelfTest() => _messages;
|
||||
|
||||
internal Components.TopTabBar GetTopTabsForSelfTest() => _topTabs;
|
||||
|
||||
public override bool DrawConditions() => !_userHidden;
|
||||
|
||||
internal void UserHide() => _userHidden = true;
|
||||
|
||||
Reference in New Issue
Block a user