feat(vtank): slice 7 fix — <menu style> selects plain vs retail art

Wires the new UiMenu.RetailButtonArt switch (previous commit) into
plugin markup: <menu style="plain"> (also the default when the
attribute is absent) builds RetailButtonArt=false so a plugin's
dropdown gets the flat VTank-matching box; style="retail" opts a
panel back into the gold pushbutton face. Any other value throws
FormatException at Build naming the element, matching the existing
<icon iconkind> validation convention (ValidateIconKind).

Mutation check: temporarily stubbed ValidateMenuStyle to always return
true (as if the switch didn't exist) — 3 of the 4 new
MarkupDocumentTests.Menu_* tests failed exactly as expected
(Menu_NoStyleAttribute_DefaultsToPlain_RetailButtonArtFalse,
Menu_StylePlain_Explicit_RetailButtonArtFalse,
Menu_UnknownStyle_ThrowsFormatException_NamingTheElement); the
style="retail" test passed trivially either way, as expected for that
case. Restored before committing.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-09-07 08:15:23 +02:00
parent cc11e077a4
commit 19c831211b
2 changed files with 75 additions and 0 deletions

View file

@ -314,4 +314,58 @@ public class MarkupDocumentTests
Assert.Equal(0.78f, binding.AttackPower);
Assert.Equal(0.78f, slider.ScalarPositionSource!());
}
// ── S7 fix ("BIG gold/yellow buttons has to go" — owner live-client
// report 2026-09-07): <menu style="..."> selects UiMenu.RetailButtonArt.
private sealed class MenuStyleBinding
{
public IReadOnlyList<string> Choices => ["First", "Second"];
public string Selected { get; } = "First";
}
private static string MenuXml(string? styleAttribute) =>
"<panel x=\"0\" y=\"0\" w=\"240\" h=\"60\">" +
$"<menu x=\"4\" y=\"4\" w=\"120\" h=\"20\" items=\"{{Choices}}\" selected=\"{{Selected}}\"{styleAttribute}/>" +
"</panel>";
[Fact]
public void Menu_NoStyleAttribute_DefaultsToPlain_RetailButtonArtFalse()
{
var panel = MarkupDocument.Build(MenuXml(styleAttribute: ""), new MenuStyleBinding(), _ => (1u, 32, 32));
var menu = Assert.IsType<UiMenu>(panel.Children[0]);
Assert.False(menu.RetailButtonArt);
}
[Fact]
public void Menu_StylePlain_Explicit_RetailButtonArtFalse()
{
var panel = MarkupDocument.Build(
MenuXml(" style=\"plain\""), new MenuStyleBinding(), _ => (1u, 32, 32));
var menu = Assert.IsType<UiMenu>(panel.Children[0]);
Assert.False(menu.RetailButtonArt);
}
[Fact]
public void Menu_StyleRetail_OptsIntoTheGoldButtonArt()
{
var panel = MarkupDocument.Build(
MenuXml(" style=\"retail\""), new MenuStyleBinding(), _ => (1u, 32, 32));
var menu = Assert.IsType<UiMenu>(panel.Children[0]);
Assert.True(menu.RetailButtonArt);
}
[Fact]
public void Menu_UnknownStyle_ThrowsFormatException_NamingTheElement()
{
var ex = Assert.Throws<FormatException>(
() => MarkupDocument.Build(
MenuXml(" style=\"chrome\""), new MenuStyleBinding(), _ => (1u, 32, 32)));
Assert.Contains("menu", ex.Message);
Assert.Contains("chrome", ex.Message);
}
}