Files
LlamaCasty/ytLive.Tests/PropertiesStyleTests.cs
T
gramps 54902cb838 ui(properties): no raw typography left in the panel, and one heading rank
The earlier pass checked wiring only; this is the typography sweep. Raw Foreground/FontSize
labels are gone from the elements panel:

- Opacity, Timer (minutes) and URI are headings above their control (PropertyHeader), with the
  control row on the panel's 10px indent — the same shape as Border Thickness/Opacity.
- Scroll speed, scoreboard Opacity/Text size and their value readouts are PropertyFieldLabel.
- The drag hint and the scoreboard sign-in note are PropertyHint.
- Simulate (dev) keeps its orange, gains the field-label typography.
- Edge, Text colour and Background were PropertySubHeader/SubHeader: ONE heading rank now, so
  PropertySubHeader and the legacy SubHeader are deleted from Themes/Controls.xaml.
- DeveloperPanel — the last panel with raw typography and an unstyled CheckBox — now uses the
  same styles, and PropertiesStyleTests accepts PropertyPillCheck (the guard went stale when
  every check box became a pill switch). 18 tests pass; Release 0 warnings.
2026-11-01 16:26:20 -08:00

93 lines
4.5 KiB
C#

using System.IO;
using System.Linq;
using System.Xml.Linq;
using Xunit;
namespace ytLive.Tests;
/// <summary>TASK 58 — the creator's style audit (2026-10-21): "in the Live scene, for the
/// layer Stream Alerts, the properties → display — why is the drop-down box not in the same
/// style as the others?" It was never given the theme's <c>YtComboBox</c> style — only a
/// hand-painted Background/Foreground — so WPF fell back to the light system template, and
/// the chat Font drop-down (copied from it) was the same. The sweep found the same smell in
/// every check box and every properties field.
///
/// <para>This test is the guard: every drop-down and check box in the app carries the theme's
/// style, and every field in the properties panel carries the compact theme style and paints
/// no colour of its own — the theme owns the look, so it cannot drift back.</para></summary>
public class PropertiesStyleTests
{
private static readonly XNamespace Xaml = "http://schemas.microsoft.com/winfx/2006/xaml";
[Fact]
public void Every_drop_down_check_box_and_properties_field_carries_the_theme_style()
{
// 1. The theme defines the styles the app relies on.
var theme = XDocument.Load(SourceAssert.RepoPath("Themes", "Controls.xaml"));
var keys = theme.Descendants()
.Where(e => e.Name.LocalName == "Style")
.Select(e => (string?)e.Attribute(Xaml + "Key"))
.Where(k => k != null)
.ToHashSet();
foreach (var required in new[] { "YtComboBox", "YtCheckBox", "YtTextBox", "YtTextBoxCompact" })
Assert.Contains(required, keys);
// 2. Every drop-down and check box in the app carries the theme style — an unstyled
// one falls back to the light WPF system template.
foreach (var file in AppXamlFiles())
{
var doc = XDocument.Load(file);
var where = Path.GetFileName(file);
foreach (var combo in doc.Descendants().Where(e => e.Name.LocalName == "ComboBox"))
AssertStyled(combo, "YtComboBox",
$"{where}: a ComboBox is not styled with YtComboBox — it renders with the light system template");
// Every check box is a pill switch (creator ruling, 2026-11-01: "all checkboxes as
// pill switches"), so PropertyPillCheck is the theme style that matters here; YtCheckBox
// is still accepted where a plain box is deliberate.
foreach (var check in doc.Descendants().Where(e => e.Name.LocalName == "CheckBox"))
{
var style = (string?)check.Attribute("Style") ?? string.Empty;
Assert.True(
style.Contains("PropertyPillCheck", StringComparison.Ordinal)
|| style.Contains("YtCheckBox", StringComparison.Ordinal),
$"{where}: a CheckBox carries no theme style — it renders with the light system template");
}
}
// 3. Every field in the properties panel carries the compact theme style and paints
// no colours of its own.
var left = XDocument.Load(SourceAssert.RepoPath("Controls", "LeftPanel.xaml"));
var properties = left.Descendants().Single(e => e.Name.LocalName == "StackPanel"
&& (string?)e.Attribute(Xaml + "Name") == "ElementsPanel");
var fields = properties.Descendants().Where(e => e.Name.LocalName == "TextBox").ToList();
Assert.NotEmpty(fields);
foreach (var box in fields)
{
AssertStyled(box, "YtTextBoxCompact",
"a properties field is not styled with YtTextBoxCompact");
Assert.Null(box.Attribute("Background"));
Assert.Null(box.Attribute("BorderBrush"));
}
}
/// <summary>The app's XAML: the windows at the repo root plus the carved-up controls.</summary>
private static string[] AppXamlFiles()
{
var root = Path.GetDirectoryName(SourceAssert.RepoPath("ytLive.csproj"))!;
return Directory.GetFiles(root, "*.xaml", SearchOption.TopDirectoryOnly)
.Concat(Directory.GetFiles(Path.Combine(root, "Controls"), "*.xaml", SearchOption.TopDirectoryOnly))
.OrderBy(f => f)
.ToArray();
}
/// <summary>Asserts the element carries the named theme style.</summary>
private static void AssertStyled(XElement element, string key, string message)
{
var style = (string?)element.Attribute("Style");
Assert.True(style is not null && style.Contains(key, StringComparison.Ordinal), message);
}
}