Fix 1: Added a <para> to the VitalsController class summary citing docs/research/2026-06-15-layoutdesc-format.md §11 as the source of the three dat element ids, giving a paper trail back to the evidence per the project's cite-in-comments rule. Fix 2: Changed FakeLayout in VitalsBindingTests to accept (uint id, UiElement e) tuples instead of (string idHex, UiElement e), and updated all three call sites to pass VitalsController.Health/.Stamina/.Mana. Tests now follow the constants automatically if they ever change rather than silently passing with stale hex literals. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
101 lines
3.5 KiB
C#
101 lines
3.5 KiB
C#
using AcDream.App.UI;
|
|
using AcDream.App.UI.Layout;
|
|
|
|
namespace AcDream.App.Tests.UI.Layout;
|
|
|
|
/// <summary>
|
|
/// Unit tests for <see cref="VitalsController.Bind"/>: verifies that the controller
|
|
/// correctly maps element ids to UiMeter instances and wires the Fill / Label providers.
|
|
/// No dats, no GL — pure data-wiring tests.
|
|
/// </summary>
|
|
public class VitalsBindingTests
|
|
{
|
|
// ── Test 1: Health meter Fill + Label providers are bound ─────────────────
|
|
|
|
[Fact]
|
|
public void Bind_SetsHealthMeterFillFromProvider()
|
|
{
|
|
var health = new UiMeter();
|
|
var layout = FakeLayout((VitalsController.Health, health));
|
|
float hp = 0.42f;
|
|
|
|
VitalsController.Bind(layout,
|
|
healthPct: () => hp,
|
|
staminaPct: () => 1f,
|
|
manaPct: () => 1f,
|
|
healthText: () => "42/100",
|
|
staminaText: () => "",
|
|
manaText: () => "");
|
|
|
|
Assert.Equal(0.42f, health.Fill()!.Value);
|
|
Assert.Equal("42/100", health.Label());
|
|
}
|
|
|
|
// ── Test 2: All three meters wired to distinct providers ──────────────────
|
|
|
|
[Fact]
|
|
public void Bind_AllThreeMeters_EachBoundToOwnProvider()
|
|
{
|
|
var health = new UiMeter();
|
|
var stamina = new UiMeter();
|
|
var mana = new UiMeter();
|
|
var layout = FakeLayout(
|
|
(VitalsController.Health, health),
|
|
(VitalsController.Stamina, stamina),
|
|
(VitalsController.Mana, mana));
|
|
|
|
VitalsController.Bind(layout,
|
|
healthPct: () => 0.25f,
|
|
staminaPct: () => 0.50f,
|
|
manaPct: () => 0.75f,
|
|
healthText: () => "25/100",
|
|
staminaText: () => "50/100",
|
|
manaText: () => "75/100");
|
|
|
|
// Each meter should reflect its own provider, not another's.
|
|
Assert.Equal(0.25f, health.Fill()!.Value);
|
|
Assert.Equal("25/100", health.Label());
|
|
|
|
Assert.Equal(0.50f, stamina.Fill()!.Value);
|
|
Assert.Equal("50/100", stamina.Label());
|
|
|
|
Assert.Equal(0.75f, mana.Fill()!.Value);
|
|
Assert.Equal("75/100", mana.Label());
|
|
}
|
|
|
|
// ── Test 3: Missing meter ids are silently skipped (no throw) ─────────────
|
|
|
|
[Fact]
|
|
public void Bind_MissingMeterIds_DoesNotThrow()
|
|
{
|
|
// Only Health is present; Stamina and Mana are absent from the layout.
|
|
var health = new UiMeter();
|
|
var layout = FakeLayout((VitalsController.Health, health));
|
|
|
|
// Should not throw even though Stamina/Mana are missing.
|
|
VitalsController.Bind(layout,
|
|
healthPct: () => 1f,
|
|
staminaPct: () => 1f,
|
|
manaPct: () => 1f,
|
|
healthText: () => "100/100",
|
|
staminaText: () => "100/100",
|
|
manaText: () => "100/100");
|
|
|
|
// Health was present — it should be wired.
|
|
Assert.Equal(1f, health.Fill()!.Value);
|
|
}
|
|
|
|
// ── Helpers ───────────────────────────────────────────────────────────────
|
|
|
|
private static ImportedLayout FakeLayout(params (uint id, UiElement e)[] items)
|
|
{
|
|
var dict = new Dictionary<uint, UiElement>();
|
|
var root = new UiPanel();
|
|
foreach (var (id, e) in items)
|
|
{
|
|
root.AddChild(e);
|
|
dict[id] = e;
|
|
}
|
|
return new ImportedLayout(root, dict);
|
|
}
|
|
}
|