Creator's defaults: white text, Background ON (black, 20%), speed capped at 200 px/s, text size shown in real pixels, and "plate" dropped from the label. The important find is underneath those: `ScoreboardStyle` is a record STRUCT, and `new ScoreboardStyle()` zero-initialises — it does NOT run the constructor's parameter defaults. So the shipped strip had null text colour, NO background and zero opacity, whatever the source said. That is why the Background checkbox and the opacity slider looked like they had no code behind them: the renderer was faithfully drawing the zeros it was handed. An explicit parameterless constructor now carries the real defaults, and the renderer test asserts them (white / on / black / 0.20 / max speed 200) so this class of silent-zero cannot return. Readouts fixed too: the opacity and text-size setters never raised their own property, so the numbers never moved while the render did. Text size now reads "24 px" instead of a bare slider value, and snaps to whole pixels.
83 lines
4.2 KiB
C#
83 lines
4.2 KiB
C#
using System.Reflection;
|
|
using Xunit;
|
|
using ytLive.ViewModels;
|
|
|
|
namespace ytLive.Tests;
|
|
|
|
/// <summary>The scoreboard's look and its eight fact switches live in the LAYER PROPERTIES, and the
|
|
/// panel must use the app's widgets — a hand-painted control is the TASK 58/63 defect, and the
|
|
/// guard that catches it is here because the type-based sweep cannot see a bespoke picker.</summary>
|
|
public class ScoreboardPropertiesTests
|
|
{
|
|
[Fact]
|
|
public void The_scoreboard_properties_are_themed_controls_bound_to_the_layer_surface()
|
|
{
|
|
var panel = SourceAssert.Text("Controls", "LeftPanel.xaml");
|
|
|
|
// Gated on the selected layer being a scoreboard.
|
|
Assert.Contains("SelectedElement.IsScoreboard", panel);
|
|
|
|
// Signed out: the block is inert with a one-line explanation — EXCEPT in a DEBUG build, where
|
|
// CanUseScoreboard is true so the strip can be previewed without an account.
|
|
var block = panel[panel.IndexOf("Scoreboard config", System.StringComparison.Ordinal)..];
|
|
block = block[..block.IndexOf("<!-- Countdown config -->", System.StringComparison.Ordinal)];
|
|
Assert.Contains("IsEnabled=\"{Binding CanUseScoreboard}\"", block);
|
|
Assert.Contains("Sign in to YouTube to use the scoreboard.", block);
|
|
Assert.Contains("CanUseScoreboard, Converter={StaticResource InverseBoolToVis}", block);
|
|
|
|
// Defaults the creator asked for, and readouts that actually move.
|
|
Assert.Contains("Background", block);
|
|
Assert.DoesNotContain("Background plate", block);
|
|
Assert.Contains("ScoreboardFontSizeLabel", block); // "24 px", not a bare number
|
|
|
|
var vm = SourceAssert.Text("ViewModels", "MainViewModel.Scoreboard.cs");
|
|
Assert.Contains("OnPropertyChanged(nameof(ScoreboardBackgroundOpacity));", vm);
|
|
Assert.Contains("OnPropertyChanged(nameof(ScoreboardFontSize));", vm);
|
|
|
|
// Dev-only labels are ORANGE, so a development affordance cannot pass for product.
|
|
Assert.Contains("Simulate (dev)", block);
|
|
Assert.Contains("Brush.Attention", block);
|
|
|
|
// Scroll speed: a real dial, persisted, with its range owned by the presenter.
|
|
Assert.Contains("ScoreboardScrollSpeed", block);
|
|
Assert.Contains("Minimum=\"20\" Maximum=\"200\"", block);
|
|
Assert.Contains("Scoreboard.ScrollSpeed", SourceAssert.Text("Services", "LayoutStore.Settings.cs"));
|
|
|
|
// The master switch sits in the same panel: off hides the strip and stops the polling.
|
|
Assert.Contains("ScoreboardEnabled", panel);
|
|
|
|
// The eight fact switches.
|
|
foreach (var binding in new[]
|
|
{
|
|
"ScoreboardShowSubscribers", "ScoreboardShowWatchHours", "ScoreboardShowSuperChats",
|
|
"ScoreboardShowNewMembers", "ScoreboardShowMilestones", "ScoreboardShowLastMember",
|
|
"ScoreboardShowLastSuperChat", "ScoreboardShowLastGift",
|
|
})
|
|
Assert.Contains(binding, panel);
|
|
|
|
// Look controls: text colour, plate colour, plate opacity, text size.
|
|
foreach (var binding in new[]
|
|
{
|
|
"ScoreboardTextColor", "ScoreboardBackgroundColor",
|
|
"ScoreboardBackgroundOpacity", "ScoreboardFontSize",
|
|
})
|
|
Assert.Contains(binding, panel);
|
|
|
|
// Theme widgets only: the colour pickers are the app's drop-down (YtComboBox), never a
|
|
// hand-built menu, and the toggles are YtCheckBox.
|
|
Assert.Contains("Style=\"{StaticResource YtComboBox}\"", block);
|
|
Assert.Contains("Style=\"{StaticResource YtCheckBox}\"", block);
|
|
Assert.DoesNotContain("ContextMenu", block);
|
|
|
|
// The VM surface exists for every binding above (a typo would bind to nothing silently).
|
|
var type = typeof(MainViewModel);
|
|
foreach (var name in new[]
|
|
{
|
|
"ScoreboardTextColor", "ScoreboardBackgroundColor", "ScoreboardBackgroundOpacity",
|
|
"ScoreboardFontSize", "ScoreboardColorOptions", "ScoreboardShowSubscribers",
|
|
"ScoreboardEnabled", "CanUseScoreboard", "ScoreboardScrollSpeed",
|
|
})
|
|
Assert.NotNull(type.GetProperty(name));
|
|
}
|
|
}
|