using AcDream.App.UI;
namespace AcDream.App.Tests.UI;
public class MarkupDocumentTests
{
private sealed class FakeBinding
{
public float HealthPercent => 0.5f;
public uint? HealthCurrent => 109;
public uint? HealthMax => 218;
public float? ManaPercent => null;
public uint? ManaCurrent => null;
public uint? ManaMax => null;
}
[Fact]
public void Build_CreatesPanelWithMeterFillLabelAndGeometry()
{
const string xml =
"" +
" " +
"";
var panel = MarkupDocument.Build(xml, new FakeBinding(), _ => ((uint)1, 32, 32));
Assert.IsType(panel);
Assert.Equal(10f, panel.Left);
Assert.Equal(220f, panel.Width);
Assert.Equal(2, panel.Children.Count); // title UiLabel + 1 meter
var meter = Assert.IsType(panel.Children[1]);
Assert.Equal(8f, meter.Left);
Assert.Equal(200f, meter.Width);
Assert.Equal(0.5f, meter.Fill());
Assert.Equal("109/218", meter.Label());
}
[Fact]
public void Build_NullBindingValuesYieldNullFillAndLabel()
{
const string xml =
"" +
" " +
"";
var panel = MarkupDocument.Build(xml, new FakeBinding(), _ => ((uint)1, 32, 32));
var meter = Assert.IsType(panel.Children[1]);
Assert.Null(meter.Fill());
Assert.Null(meter.Label());
}
[Fact]
public void Build_ResizeAttrX_SetsHorizontalOnly()
{
const string xml = "";
var panel = MarkupDocument.Build(xml, new object(), _ => ((uint)1, 32, 32));
Assert.True(panel.ResizeX);
Assert.False(panel.ResizeY);
}
[Fact]
public void Build_ParsesNineSliceBarSpriteIds()
{
const string xml = "" +
"" +
"";
var panel = MarkupDocument.Build(xml, new FakeBinding(), _ => ((uint)7, 32, 32));
var meter = Assert.IsType(panel.Children[1]);
Assert.Equal(0x06001141u, meter.BackLeft);
Assert.Equal(0x06001140u, meter.BackTile);
Assert.Equal(0x0600113Fu, meter.BackRight);
Assert.Equal(0x06001131u, meter.FrontLeft);
Assert.Equal(0x06001132u, meter.FrontTile);
Assert.Equal(0x06001133u, meter.FrontRight);
Assert.NotNull(meter.SpriteResolve);
}
private sealed class ButtonBinding
{
public int Clicks { get; private set; }
public string Status { get; set; } = "idle";
public Action Go => () => Clicks++;
public Action? Missing => null;
}
[Fact]
public void Build_ButtonInvokesTheBoundActionOnClick()
{
const string xml =
"" +
" ";
var binding = new ButtonBinding();
var panel = MarkupDocument.Build(xml, binding, _ => ((uint)1, 32, 32));
var button = Assert.IsType(panel.Children[0]);
Assert.Equal("Buff", button.Text);
Assert.Equal(60f, button.Width);
button.OnEvent(new UiEvent { Type = UiEventType.Click });
button.OnEvent(new UiEvent { Type = UiEventType.Click });
Assert.Equal(2, binding.Clicks);
}
[Fact]
public void Build_ButtonWithUnresolvableHandlerFailsLoudly()
{
// A silently dead button is worse than a panel that refuses to load:
// the user clicks and nothing happens, with nothing to diagnose.
const string xml =
"" +
" ";
Assert.Throws(
() => MarkupDocument.Build(xml, new ButtonBinding(), _ => ((uint)1, 32, 32)));
}
[Fact]
public void Build_BoundLabelTracksTheBindingRatherThanFreezing()
{
const string xml =
"" +
" ";
var binding = new ButtonBinding();
var panel = MarkupDocument.Build(xml, binding, _ => ((uint)1, 32, 32));
var label = Assert.IsType(panel.Children[0]);
Assert.Equal("idle", label.TextSource!());
binding.Status = "casting";
Assert.Equal("casting", label.TextSource!());
}
[Fact]
public void Build_LiteralLabelTextIsUsedVerbatim()
{
const string xml =
"" +
" ";
var panel = MarkupDocument.Build(xml, new ButtonBinding(), _ => ((uint)1, 32, 32));
var label = Assert.IsType(panel.Children[0]);
Assert.Equal("MossTank", label.TextSource!());
}
}