From 76f4bb1ca08d9257f1dbac24493f4a83d4d15dbf Mon Sep 17 00:00:00 2001
From: smoogipoo <smoogipoo@smgi.me>
Date: Tue, 2 Jan 2018 17:00:51 +0900
Subject: [PATCH] Add automated test cases

---
 .../Visual/TestCaseSliderBarPercentage.cs     | 123 +++++++++++++
 .../Visual/TestCaseSliderBarPrecision.cs      | 172 ++++++++++++++++++
 osu.Game.Tests/osu.Game.Tests.csproj          |   2 +
 3 files changed, 297 insertions(+)
 create mode 100644 osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs
 create mode 100644 osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs

diff --git a/osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs b/osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs
new file mode 100644
index 0000000000..5c4d545348
--- /dev/null
+++ b/osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs
@@ -0,0 +1,123 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE
+
+using System;
+using System.Collections.Generic;
+using osu.Framework.Graphics;
+using osu.Framework.Configuration;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Sprites;
+using osu.Game.Graphics.Sprites;
+using osu.Game.Graphics.UserInterface;
+using OpenTK;
+
+namespace osu.Game.Tests.Visual
+{
+    public class TestCaseSliderBarPercentage : OsuTestCase
+    {
+        public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(OsuSliderBar<>) };
+
+        private readonly BindableFloat floatValue;
+        private readonly BindableDouble doubleValue;
+
+        private readonly TestSliderBar<float> floatSliderBar;
+        private readonly TestSliderBar<double> doubleSliderBar;
+
+        public TestCaseSliderBarPercentage()
+        {
+            floatValue = new BindableFloat
+            {
+                MinValue = -1,
+                MaxValue = 1,
+            };
+
+            doubleValue = new BindableDouble
+            {
+                MinValue = -1,
+                MaxValue = 1
+            };
+
+            Child = new FillFlowContainer
+            {
+                AutoSizeAxes = Axes.Y,
+                Width = 300,
+                Direction = FillDirection.Vertical,
+                Spacing = new Vector2(0, 20),
+                Children = new Drawable[]
+                {
+                    floatSliderBar = new TestSliderBar<float> { RelativeSizeAxes = Axes.X },
+                    doubleSliderBar = new TestSliderBar<double> { RelativeSizeAxes = Axes.X }
+                }
+            };
+
+            floatSliderBar.Current.BindTo(floatValue);
+            doubleSliderBar.Current.BindTo(doubleValue);
+
+            floatValue.ValueChanged += setValue;
+            doubleValue.ValueChanged += setValue;
+
+            AddStep("Digits = 0", () => setPercentageDigits(0));
+            AddStep("Value = 0", () => setValue(0));
+            AddAssert("Check 0%", () => checkExact(0));
+
+            AddStep("Value = 0.5", () => setValue(0.5));
+            AddAssert("Check 50%", () => checkExact(0.5m));
+
+            AddStep("Value = 0.54", () => setValue(0.54));
+            AddAssert("Check 54%", () => checkExact(0.54m));
+
+            AddStep("Value = 0.544", () => setValue(0.544));
+            AddAssert("Check 54%", () => checkExact(0.54m));
+
+            AddStep("Value = 0.548", () => setValue(0.548));
+            AddAssert("Check 55%", () => checkExact(0.55m));
+
+            AddStep("Digits = 1", () => setPercentageDigits(1));
+            AddAssert("Check 54.8%", () => checkExact(0.548m));
+
+            AddSliderStep("Percentage", -1.0, 1.0, 0.0, setValue);
+            AddSliderStep("Digits", 0, 7, 1, setPercentageDigits);
+        }
+
+        private bool checkExact(decimal percentage)
+        {
+            string expectedValue = percentage.ToString("P", floatSliderBar.Format);
+            return floatSliderBar.TooltipText == expectedValue && doubleSliderBar.TooltipText == expectedValue;
+        }
+
+        private void setValue<T>(T value)
+        {
+            floatValue.Value = Convert.ToSingle(value);
+            doubleValue.Value = Convert.ToDouble(value);
+        }
+
+        private void setPercentageDigits(int digits)
+        {
+            floatSliderBar.Format.PercentDecimalDigits = digits;
+            doubleSliderBar.Format.PercentDecimalDigits = digits;
+
+            // Make sure that the text referenced in TestSliderBar is updated
+            // This doesn't break any assertions if missing, but breaks the visual display
+            floatSliderBar.Current.TriggerChange();
+            doubleSliderBar.Current.TriggerChange();
+        }
+
+        private class TestSliderBar<T> : OsuSliderBar<T>
+            where T : struct, IEquatable<T>
+        {
+            public TestSliderBar()
+            {
+                SpriteText valueText;
+                AddInternal(valueText = new OsuSpriteText
+                {
+                    Anchor = Anchor.CentreRight,
+                    Origin = Anchor.CentreLeft,
+                    X = 5,
+                    Text = TooltipText
+                });
+
+                Current.ValueChanged += v => valueText.Text = TooltipText;
+            }
+        }
+    }
+}
diff --git a/osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs b/osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs
new file mode 100644
index 0000000000..928ba0d825
--- /dev/null
+++ b/osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs
@@ -0,0 +1,172 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE
+
+using System;
+using System.Collections.Generic;
+using osu.Framework.Configuration;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Sprites;
+using osu.Game.Graphics.Sprites;
+using osu.Game.Graphics.UserInterface;
+using OpenTK;
+
+namespace osu.Game.Tests.Visual
+{
+    public class TestCaseSliderBarPrecision : OsuTestCase
+    {
+        public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(OsuSliderBar<>) };
+
+        private readonly BindableInt intValue;
+        private readonly BindableFloat floatValue;
+        private readonly BindableDouble doubleValue;
+
+        private readonly TestSliderBar<int> intSliderBar;
+        private readonly TestSliderBar<float> floatSliderBar;
+        private readonly TestSliderBar<double> doubleSliderBar;
+
+        public TestCaseSliderBarPrecision()
+        {
+            intValue = new BindableInt
+            {
+                MinValue = -1000,
+                MaxValue = 1000,
+            };
+
+            floatValue = new BindableFloat
+            {
+                MinValue = -1000,
+                MaxValue = 1000,
+            };
+
+            doubleValue = new BindableDouble
+            {
+                MinValue = -1000,
+                MaxValue = 1000
+            };
+
+            Child = new FillFlowContainer
+            {
+                AutoSizeAxes = Axes.Y,
+                Width = 300,
+                Direction = FillDirection.Vertical,
+                Spacing = new Vector2(0, 20),
+                Children = new Drawable[]
+                {
+                    intSliderBar = new TestSliderBar<int> { RelativeSizeAxes = Axes.X },
+                    floatSliderBar = new TestSliderBar<float> { RelativeSizeAxes = Axes.X },
+                    doubleSliderBar = new TestSliderBar<double> { RelativeSizeAxes = Axes.X }
+                }
+            };
+
+            intSliderBar.Current.BindTo(intValue);
+            floatSliderBar.Current.BindTo(floatValue);
+            doubleSliderBar.Current.BindTo(doubleValue);
+
+            intValue.ValueChanged += setValue;
+            floatValue.ValueChanged += setValue;
+            doubleValue.ValueChanged += setValue;
+
+            AddStep("Value = 0", () => setValue(0));
+            AddStep("Digits = 0", () => setDecimalDigits(0));
+            AddAssert("Check all 0", () => checkExact("0"));
+
+            AddStep("Digits = 3", () => setDecimalDigits(3));
+            AddAssert("Check 0.000", () => checkExact(0.000m));
+
+            AddStep("Value = 0.5", () => setValue(0.5));
+            AddAssert("Check 0.500", () => checkExact(0.500m));
+
+            AddStep("Value = 123.4567", () => setValue(123.4567));
+            AddAssert("Check 123.457", () => checkExact(123.457m));
+
+            AddStep("Value = 765.4312", () => setValue(765.4312));
+            AddAssert("Check 765.431", () => checkExact(765.431m));
+
+            AddStep("Value = -12.3456", () => setValue(-12.3456));
+            AddAssert("Check -12.346", () => checkExact(-12.346m));
+            AddStep("Digits = 1", () => setDecimalDigits(1));
+            AddAssert("Check -12.3", () => checkExact(-12.3m));
+            AddStep("Digits = 0", () => setDecimalDigits(0));
+            AddAssert("Check -12", () => checkExact(-12m));
+
+            AddStep("Value = -12.8", () => setValue(-12.8));
+            AddAssert("Check -13", () => checkExact(-13m));
+            AddStep("Digits = 1", () => setDecimalDigits(1));
+            AddAssert("Check -12.8", () => checkExact(-12.8m));
+
+            AddSliderStep("Digits", 0, 7, 1, setDecimalDigits);
+        }
+
+        /// <summary>
+        /// Checks whether all sliderbar tooltips display an exact value.
+        /// </summary>
+        /// <param name="value">The expected value that should be displayed.</param>
+        private bool checkExact(string value)
+            => intSliderBar.TooltipText == value
+               && floatSliderBar.TooltipText == value
+               && doubleSliderBar.TooltipText == value;
+
+        /// <summary>
+        /// Checks whether all sliderbar tooltips display an exact value.
+        /// </summary>
+        /// <param name="value">The expected value that should be displayed.</param>
+        private bool checkExact(decimal value)
+        {
+            var expectedDecimal = value.ToString(intSliderBar.Format);
+
+            return intSliderBar.TooltipText == Convert.ToInt32(value).ToString("N0")
+                   && floatSliderBar.TooltipText == expectedDecimal
+                   && doubleSliderBar.TooltipText == expectedDecimal;
+        }
+
+        /// <summary>
+        /// Checks whether all floating-point sliderbar tooltips have a certain number of decimal digits.
+        /// </summary>
+        /// <param name="decimals">The expected number of decimal digits.</param>
+        private bool checkDecimalDigits(int decimals)
+            => checkDecimalDigits(decimals, floatSliderBar.TooltipText)
+               && checkDecimalDigits(decimals, doubleSliderBar.TooltipText);
+
+        private bool checkDecimalDigits(int decimals, string value)
+            => value.Length - value.IndexOf(intSliderBar.Format.NumberDecimalSeparator, StringComparison.InvariantCulture) - 1 == decimals;
+
+        private void setValue<T>(T value)
+        {
+            intValue.Value = Convert.ToInt32(value);
+            floatValue.Value = Convert.ToSingle(value);
+            doubleValue.Value = Convert.ToDouble(value);
+        }
+
+        private void setDecimalDigits(int digits)
+        {
+            intSliderBar.Format.NumberDecimalDigits = digits;
+            floatSliderBar.Format.NumberDecimalDigits = digits;
+            doubleSliderBar.Format.NumberDecimalDigits = digits;
+
+            // Make sure that the text referenced in TestSliderBar is updated
+            // This doesn't break any assertions if missing, but breaks the visual display
+            intSliderBar.Current.TriggerChange();
+            floatSliderBar.Current.TriggerChange();
+            doubleSliderBar.Current.TriggerChange();
+        }
+
+        private class TestSliderBar<T> : OsuSliderBar<T>
+            where T : struct, IEquatable<T>
+        {
+            public TestSliderBar()
+            {
+                SpriteText valueText;
+                AddInternal(valueText = new OsuSpriteText
+                {
+                    Anchor = Anchor.CentreRight,
+                    Origin = Anchor.CentreLeft,
+                    X = 5,
+                    Text = TooltipText
+                });
+
+                Current.ValueChanged += v => valueText.Text = TooltipText;
+            }
+        }
+    }
+}
diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj
index 8c04874e75..53d971a0b3 100644
--- a/osu.Game.Tests/osu.Game.Tests.csproj
+++ b/osu.Game.Tests/osu.Game.Tests.csproj
@@ -132,6 +132,8 @@
     <Compile Include="Visual\TestCaseOnScreenDisplay.cs" />
     <Compile Include="Visual\TestCaseAllPlayers.cs" />
     <Compile Include="Visual\TestCaseOsuGame.cs" />
+    <Compile Include="Visual\TestCaseSliderBarPercentage.cs" />
+    <Compile Include="Visual\TestCaseSliderBarPrecision.cs" />
     <Compile Include="Visual\TestCasePlaybackControl.cs" />
     <Compile Include="Visual\TestCasePlaySongSelect.cs" />
     <Compile Include="Visual\TestCasePopupDialog.cs" />