OverviewFilesCommitsIssuesDocsReleasesPeers

ifsrenderer-linux / AvaloniaShell.Tests / SliderRangeTests.cs

102 lines · csharp ref:
using Avalonia;
using Avalonia.Controls;
using Avalonia.Headless.XUnit;
using Avalonia.Threading;

using IFSRenderer.AvaloniaShell.Controls;

using Xunit;

namespace IFSRenderer.AvaloniaShell.Tests;

/// <summary>
/// "fog is not supposed to be capped at 1".
/// </summary>
/// <remarks>
/// <para>
/// A maximum the canonical does not declare is a correctness bug, not a cosmetic one: it puts
/// values the original can reach permanently out of reach, and it changes what a given slider
/// position means. The port shipped a batch of invented ranges; they were corrected once, but
/// Fog effect was missed because its cap of 1 looks plausible.
/// </para>
/// <para>
/// Each expectation below cites the canonical view-model that declares — or declines to
/// declare — the bound.
/// </para>
/// </remarks>
public class SliderRangeTests
{
    private static MainWindow Ready()
    {
        (MainWindow window, _) = MainWindowHarness.Start();
        window.Measure(new Size(1500, 900));
        window.Arrange(new Rect(0, 0, 1500, 900));
        Dispatcher.UIThread.RunJobs();
        return window;
    }

    private static ValueSlider Slider(MainWindow w, string name)
    {
        var s = w.FindControl<ValueSlider>(name);
        Assert.NotNull(s);
        return s;
    }

    /// <summary>IFSViewModel.cs:107-116 — MinValue 0, and no maximum.</summary>
    [AvaloniaFact]
    public void Fog_effect_has_no_upper_bound()
    {
        ValueSlider fog = Slider(Ready(), "FogSlider");

        Assert.Equal(0, fog.MinValue);
        Assert.Null(fog.MaxValue);
    }

    /// <summary>
    /// The parameters the canonical deliberately leaves open-ended. Capping any of these makes
    /// part of the original's range unreachable.
    /// </summary>
    [AvaloniaTheory]
    // ToneMappingViewModel: brightness, gamma, gamma threshold and vibrancy declare no maximum.
    [InlineData("BrightnessSlider")]
    [InlineData("GammaSlider")]
    [InlineData("GammaThresholdSlider")]
    [InlineData("VibrancySlider")]
    // CameraSettingsViewModel.cs:166-192 — aperture and focus distance are unbounded above.
    [InlineData("ApertureSlider")]
    [InlineData("FocusSlider")]
    // QualitySettingsViewModel — warmup has a minimum but no maximum.
    [InlineData("WarmupSlider")]
    // IteratorViewModel — weights, colour speed, mix and add are all open-ended.
    [InlineData("ItStartWeight")]
    [InlineData("ItWeight")]
    [InlineData("ItColorSpeed")]
    [InlineData("ItMix")]
    [InlineData("ItAdd")]
    public void Open_ended_parameters_declare_no_maximum(string name)
    {
        ValueSlider slider = Slider(Ready(), name);
        Assert.Null(slider.MaxValue);
    }

    /// <summary>
    /// The bounds the canonical DOES declare, so a future "unbound everything" sweep cannot
    /// quietly remove a real constraint.
    /// </summary>
    [AvaloniaTheory]
    [InlineData("FovSlider", 1.0, 179.0)]            // CameraSettingsViewModel.cs:157-158
    [InlineData("QualitySlider", 1.0, 50.0)]         // QualitySettingsViewModel.cs:73-74
    [InlineData("SyntropySlider", 10.0, 1000000.0)]  // QualitySettingsViewModel.cs:124-125
    [InlineData("FilterRadiusSlider", 0.0, 3.0)]     // QualitySettingsViewModel.cs:148-149
    [InlineData("DeRadiusSlider", 0.0, 20.0)]        // QualitySettingsViewModel.cs:84-85
    [InlineData("DePowerSlider", 0.0, 1.0)]          // QualitySettingsViewModel.cs:95-96
    [InlineData("DeThresholdSlider", 0.0, 1.0)]      // QualitySettingsViewModel.cs:106-107
    [InlineData("ItColorIndex", 0.0, 1.0)]           // IteratorViewModel.cs:92-93
    public void Bounded_parameters_keep_the_canonical_range(string name, double min, double max)
    {
        ValueSlider slider = Slider(Ready(), name);
        Assert.Equal(min, slider.MinValue);
        Assert.Equal(max, slider.MaxValue);
    }
}