// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using System.Diagnostics; using System.Linq; using NUnit.Framework; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Game.Rulesets; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play.HUD.JudgementCounter; namespace osu.Game.Tests.Visual.Gameplay { public partial class TestSceneJudgementCounter : OsuTestScene { private ScoreProcessor scoreProcessor = null!; private JudgementCountController judgementCountController = null!; private TestJudgementCounterDisplay counterDisplay = null!; private DependencyProvidingContainer content = null!; protected override Container Content => content; private readonly Bindable lastJudgementResult = new Bindable(); private int iteration; [SetUpSteps] public void SetUpSteps() => AddStep("Create components", () => { var ruleset = CreateRuleset(); Debug.Assert(ruleset != null); scoreProcessor = new ScoreProcessor(ruleset); base.Content.Child = new DependencyProvidingContainer { RelativeSizeAxes = Axes.Both, CachedDependencies = new (Type, object)[] { (typeof(ScoreProcessor), scoreProcessor), (typeof(Ruleset), ruleset) }, Children = new Drawable[] { judgementCountController = new JudgementCountController(), content = new DependencyProvidingContainer { RelativeSizeAxes = Axes.Both, CachedDependencies = new (Type, object)[] { (typeof(JudgementCountController), judgementCountController) }, } }, }; }); protected override Ruleset CreateRuleset() => new OsuRuleset(); private void applyOneJudgement(HitResult result) { lastJudgementResult.Value = new OsuJudgementResult(new HitObject { StartTime = iteration * 10000 }, new OsuJudgement()) { Type = result, }; scoreProcessor.ApplyResult(lastJudgementResult.Value); iteration++; } [Test] public void TestAddJudgementsToCounters() { AddStep("create counter", () => Child = counterDisplay = new TestJudgementCounterDisplay()); AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Great), 2); AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Miss), 2); AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Meh), 2); } [Test] public void TestAddWhilstHidden() { AddStep("create counter", () => Child = counterDisplay = new TestJudgementCounterDisplay()); AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.LargeTickHit), 2); AddAssert("Check value added whilst hidden", () => hiddenCount() == 2); AddStep("Show all judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.All); } [Test] public void TestChangeFlowDirection() { AddStep("create counter", () => Child = counterDisplay = new TestJudgementCounterDisplay()); AddStep("Set direction vertical", () => counterDisplay.FlowDirection.Value = Direction.Vertical); AddStep("Set direction horizontal", () => counterDisplay.FlowDirection.Value = Direction.Horizontal); } [Test] public void TestToggleJudgementNames() { AddStep("create counter", () => Child = counterDisplay = new TestJudgementCounterDisplay()); AddStep("Hide judgement names", () => counterDisplay.ShowJudgementNames.Value = false); AddWaitStep("wait some", 2); AddAssert("Assert hidden", () => counterDisplay.CounterFlow.Children.First().ResultName.Alpha == 0); AddStep("Hide judgement names", () => counterDisplay.ShowJudgementNames.Value = true); AddWaitStep("wait some", 2); AddAssert("Assert shown", () => counterDisplay.CounterFlow.Children.First().ResultName.Alpha == 1); } [Test] public void TestHideMaxValue() { AddStep("create counter", () => Child = counterDisplay = new TestJudgementCounterDisplay()); AddStep("Hide max judgement", () => counterDisplay.ShowMaxJudgement.Value = false); AddWaitStep("wait some", 2); AddAssert("Check max hidden", () => counterDisplay.CounterFlow.ChildrenOfType().First().Alpha == 0); AddStep("Show max judgement", () => counterDisplay.ShowMaxJudgement.Value = true); } [Test] public void TestMaxValueStartsHidden() { AddStep("create counter", () => Child = counterDisplay = new TestJudgementCounterDisplay { ShowMaxJudgement = { Value = false } }); AddAssert("Check max hidden", () => counterDisplay.CounterFlow.ChildrenOfType().First().Alpha == 0); } [Test] public void TestMaxValueHiddenOnModeChange() { AddStep("create counter", () => Child = counterDisplay = new TestJudgementCounterDisplay()); AddStep("Set max judgement to hide itself", () => counterDisplay.ShowMaxJudgement.Value = false); AddStep("Show all judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.All); AddWaitStep("wait some", 2); AddAssert("Assert max judgement hidden", () => counterDisplay.CounterFlow.ChildrenOfType().First().Alpha == 0); } [Test] public void TestNoDuplicates() { AddStep("create counter", () => Child = counterDisplay = new TestJudgementCounterDisplay()); AddStep("Show all judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.All); AddAssert("Check no duplicates", () => counterDisplay.CounterFlow.ChildrenOfType().Count(), () => Is.EqualTo(counterDisplay.CounterFlow.ChildrenOfType().Select(c => c.ResultName.Text).Distinct().Count())); } [Test] public void TestCycleDisplayModes() { AddStep("create counter", () => Child = counterDisplay = new TestJudgementCounterDisplay()); AddStep("Show basic judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.Simple); AddWaitStep("wait some", 2); AddAssert("Check only basic", () => counterDisplay.CounterFlow.ChildrenOfType().Last().Alpha == 0); AddStep("Show normal judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.Normal); AddStep("Show all judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.All); AddWaitStep("wait some", 2); AddAssert("Check all visible", () => counterDisplay.CounterFlow.ChildrenOfType().Last().Alpha == 1); } private int hiddenCount() { var num = counterDisplay.CounterFlow.Children.First(child => child.Result.Types.Contains(HitResult.LargeTickHit)); return num.Result.ResultCount.Value; } private partial class TestJudgementCounterDisplay : JudgementCounterDisplay { public new FillFlowContainer CounterFlow => base.CounterFlow; public TestJudgementCounterDisplay() { Margin = new MarginPadding { Top = 100 }; Anchor = Anchor.TopCentre; Origin = Anchor.TopCentre; } } } }