using System.Reflection;
using System.Xml.Linq;
using OpenAC.MosswartMassacre.Views;
namespace OpenAC.MosswartMassacre.Tests.Views;
///
/// Every {Binding} in a markup file names a public property of the
/// shape the host expects, so a typo fails here instead of as a panel that
/// refuses to build in the client.
///
public sealed class MarkupContractTests
{
public static TheoryData MarkupFiles => new()
{
{ MainWindow.MarkupFile, typeof(MainWindow) },
};
[Theory]
[MemberData(nameof(MarkupFiles))]
public void EveryBindingResolvesWithTheRightShape(string file, Type bindingType)
{
XElement root = XDocument.Load(MarkupPath(file)).Root!;
Dictionary properties = bindingType
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.ToDictionary(property => property.Name, StringComparer.Ordinal);
foreach (XAttribute attribute in root.DescendantsAndSelf().Attributes())
{
string value = attribute.Value;
if (!value.StartsWith('{'))
continue;
Assert.Matches("^\\{[^{}]+\\}$", value);
string name = value[1..^1];
Assert.True(properties.TryGetValue(name, out PropertyInfo? property),
$"{file}: {value} on <{attribute.Parent!.Name}> names no public property.");
string element = attribute.Parent!.Name.LocalName;
Type expected = (element, attribute.Name.LocalName) switch
{
(_, "onclick") => typeof(Action),
("field", "onchange" or "onsubmit") => typeof(Action),
("menu", "onchange") => typeof(Action),
("list", "onchange") => typeof(Action),
("slider", "onchange") => typeof(Action),
(_, "checked" or "selected" or "visible" or "enabled") when element != "list" && element != "menu" => typeof(bool),
_ => typeof(object),
};
if (expected != typeof(object))
Assert.True(property!.PropertyType == expected,
$"{file}: {value} on <{element} {attribute.Name}> is {property.PropertyType.Name}, expected {expected.Name}.");
}
}
[Fact]
public void The_main_window_builds_its_bindings_without_a_host_ui()
{
using var harness = new PluginHarness();
harness.Login();
MainWindow window = harness.Feature();
Assert.Equal("Total Kills: 0", window.TotalKillsText);
Assert.Equal("Meta State: Unknown", window.MetaStateText);
Assert.Equal("WebSocket: [DISCONNECTED]", window.WebSocketText);
Assert.Equal("Never", window.LastKillValue);
window.ShowStatistics();
Assert.True(window.StatisticsSelected);
Assert.False(window.MainSelected);
}
private static string MarkupPath(string file) => Path.Combine(AppContext.BaseDirectory, file);
}