Campaign CC gate round 1. The Config Resolution dropdown now offers DisplayModeCatalog.WindowedResolutions — the curated hardware modes UNIONed with the static modern-ladder sizes that fit the desktop — because a windowed pick is a plain Size write needing no video mode, and remote/RDP virtual displays advertise almost none (the live RDP display exposed exactly 1920x1080 + the 2056x1290 desktop, leaving the dropdown with nothing below 1920). The fullscreen apply still validates against the hardware Resolutions list plus the switcher's monitor-mode-list hard guard, so a fullscreen pick of a windowed-only entry refuses safely (log-and-stay, #388/#392) — IA-22's offered-implies-supported invariant narrows to the fullscreen half and its register row carries the amendment. Three new pure-union tests including the exact live RDP shape. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
150 lines
5.6 KiB
C#
150 lines
5.6 KiB
C#
using AcDream.App.Rendering;
|
|
using AcDream.UI.Abstractions.Panels.Settings;
|
|
|
|
namespace AcDream.App.Tests.Rendering;
|
|
|
|
/// <summary>#391 (user-directed): the curation rule that turns a monitor's
|
|
/// raw mode enumeration into the modern-only resolution list. Pure-function
|
|
/// tests — the Silk monitor adapter is a thin projection over this.</summary>
|
|
public sealed class DisplayModeCatalogTests
|
|
{
|
|
private static readonly (int W, int H) Desktop2560 = (2560, 1440);
|
|
|
|
[Fact]
|
|
public void Curate_DropsLegacyFormats_KeepsModernFamilies()
|
|
{
|
|
var modes = new (int, int)[]
|
|
{
|
|
(640, 480), (800, 600), (1024, 768), (1280, 1024), // 4:3 / 5:4 legacy
|
|
(1280, 720), (1366, 768), (1600, 900), (1920, 1080), // 16:9
|
|
(1920, 1200), // 16:10
|
|
(2560, 1440),
|
|
};
|
|
|
|
var curated = DisplayModeCatalog.Curate(modes, Desktop2560);
|
|
|
|
Assert.Equal(
|
|
["1280x720", "1366x768", "1600x900", "1920x1080", "1920x1200", "2560x1440"],
|
|
curated);
|
|
}
|
|
|
|
[Fact]
|
|
public void Curate_ExcludesModesLargerThanTheDesktop()
|
|
{
|
|
// A windowed pick larger than the desktop can only silently clamp
|
|
// (measured live 2026-08-13: a 3840x2160 pick on this desktop
|
|
// produced a 2564x1421 window) — if it cannot exist, it is not
|
|
// offered.
|
|
var curated = DisplayModeCatalog.Curate(
|
|
[(1920, 1080), (2560, 1440), (3840, 2160)], Desktop2560);
|
|
|
|
Assert.Equal(["1920x1080", "2560x1440"], curated);
|
|
}
|
|
|
|
[Fact]
|
|
public void Curate_CollapsesRefreshRateDuplicates_AndSortsAscending()
|
|
{
|
|
// Real enumerations repeat each WxH once per refresh rate and are
|
|
// not ordered; the catalog is one entry per size, ascending.
|
|
var curated = DisplayModeCatalog.Curate(
|
|
[(2560, 1440), (1920, 1080), (1920, 1080), (1920, 1080), (1280, 720)],
|
|
Desktop2560);
|
|
|
|
Assert.Equal(["1280x720", "1920x1080", "2560x1440"], curated);
|
|
}
|
|
|
|
[Fact]
|
|
public void Curate_KeepsUltrawideFamilies()
|
|
{
|
|
var curated = DisplayModeCatalog.Curate(
|
|
[(2560, 1080), (3440, 1440), (3840, 1080)], (3840, 1600));
|
|
|
|
Assert.Equal(["2560x1080", "3440x1440", "3840x1080"], curated);
|
|
}
|
|
|
|
[Fact]
|
|
public void Curate_AlwaysIncludesTheDesktopModeItself()
|
|
{
|
|
// The desktop mode is displayable by definition — it stays even when
|
|
// its aspect matches no listed family (and it is the Defaults value).
|
|
var curated = DisplayModeCatalog.Curate(
|
|
[(1920, 1080), (1920, 1440)], (1920, 1440)); // desktop is 4:3!
|
|
|
|
Assert.Contains("1920x1440", curated);
|
|
Assert.Contains("1920x1080", curated);
|
|
}
|
|
|
|
[Fact]
|
|
public void Curate_DropsSubMinimumWidths_EvenWhenWidescreen()
|
|
{
|
|
// 1024x576 is exactly 16:9 but below the modern floor.
|
|
var curated = DisplayModeCatalog.Curate(
|
|
[(1024, 576), (1280, 720)], Desktop2560);
|
|
|
|
Assert.Equal(["1280x720"], curated);
|
|
}
|
|
|
|
[Fact]
|
|
public void FallbackPresetLadder_ItselfPassesTheCurationRule()
|
|
{
|
|
// The static fixture-fallback list must never offer something the
|
|
// production rule would reject (a big desktop accepts all of it).
|
|
var parsed = DisplaySettings.AvailableResolutions
|
|
.Select(static s => s.Split('x'))
|
|
.Select(static p => (int.Parse(p[0]), int.Parse(p[1])));
|
|
|
|
var curated = DisplayModeCatalog.Curate(parsed, (3840, 2160));
|
|
|
|
Assert.Equal(DisplaySettings.AvailableResolutions, curated);
|
|
}
|
|
|
|
[Fact]
|
|
public void FallbackDefault_IsAMemberOfTheFallbackList()
|
|
{
|
|
// The S4 rule survives the curation: the Defaults value must always
|
|
// be re-selectable from the offered list.
|
|
Assert.Contains(DisplaySettings.Default.Resolution, DisplaySettings.AvailableResolutions);
|
|
}
|
|
|
|
// ── #407: the windowed offering union (Campaign CC gate round 1) ────
|
|
|
|
[Fact]
|
|
public void BuildWindowedOffering_RdpStarvedModeList_GainsTheLadderSizesThatFit()
|
|
{
|
|
// The live RDP shape that motivated #407: the virtual display
|
|
// advertised exactly two modes (1920x1080 + the 2056x1290 desktop),
|
|
// so the hardware-gated dropdown offered nothing below 1920. The
|
|
// windowed union restores every static-ladder size that fits.
|
|
var offering = DisplayModeCatalog.BuildWindowedOffering(
|
|
["1920x1080", "2056x1290"], (2056, 1290));
|
|
|
|
Assert.Equal(
|
|
["1280x720", "1366x768", "1600x900", "1920x1080", "2056x1290"],
|
|
offering);
|
|
}
|
|
|
|
[Fact]
|
|
public void BuildWindowedOffering_RichMonitor_IsTheDedupedUnion()
|
|
{
|
|
// On a physical monitor the hardware list already contains the
|
|
// ladder sizes — the union adds nothing and stays ascending/deduped.
|
|
var offering = DisplayModeCatalog.BuildWindowedOffering(
|
|
["1280x720", "1366x768", "1600x900", "1920x1080", "1920x1200", "2560x1440"],
|
|
Desktop2560);
|
|
|
|
Assert.Equal(
|
|
["1280x720", "1366x768", "1600x900", "1920x1080", "1920x1200", "2560x1440"],
|
|
offering);
|
|
}
|
|
|
|
[Fact]
|
|
public void BuildWindowedOffering_LadderEntriesLargerThanTheDesktop_StayExcluded()
|
|
{
|
|
// A 1600x900 desktop admits only the ladder sizes that fit; the
|
|
// desktop's own (hardware-curated) mode always survives the union.
|
|
var offering = DisplayModeCatalog.BuildWindowedOffering(
|
|
["1600x900"], (1600, 900));
|
|
|
|
Assert.Equal(["1280x720", "1366x768", "1600x900"], offering);
|
|
}
|
|
}
|