Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor step buttons + improve assertion messages #6418

Merged
merged 5 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 38 additions & 8 deletions osu.Framework.Tests/Visual/Testing/TestSceneStepButton.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

#nullable disable

using System.Diagnostics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing.Drawables.Steps;
Expand All @@ -22,12 +21,43 @@ public TestSceneStepButton()
Spacing = new Vector2(5),
Children = new Drawable[]
{
new LabelStep { Text = nameof(LabelStep) },
new AssertButton { Text = nameof(AssertButton), Assertion = () => true },
new SingleStepButton { Text = nameof(SingleStepButton) },
new RepeatStepButton(null) { Text = nameof(RepeatStepButton) },
new ToggleStepButton(null) { Text = nameof(ToggleStepButton) },
new UntilStepButton(() => true) { Text = nameof(UntilStepButton) },
new LabelStep
{
Text = nameof(LabelStep),
IsSetupStep = false,
Action = _ => { },
},
new AssertButton
{
Text = nameof(AssertButton),
IsSetupStep = false,
Assertion = () => true,
CallStack = new StackTrace()
},
new SingleStepButton
{
Text = nameof(SingleStepButton),
IsSetupStep = false,
Action = () => { }
},
new RepeatStepButton
{
Text = nameof(RepeatStepButton),
IsSetupStep = false
},
new ToggleStepButton
{
Text = nameof(ToggleStepButton),
IsSetupStep = false,
Action = _ => { }
},
new UntilStepButton
{
Text = nameof(UntilStepButton),
IsSetupStep = false,
Assertion = () => true,
CallStack = new StackTrace()
},
new StepSlider<int>(nameof(StepSlider<int>), 0, 10, 5),
}
};
Expand Down
5 changes: 3 additions & 2 deletions osu.Framework.Tests/Visual/Testing/TestSceneTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ public virtual void SetUpSteps()
if (DebugUtils.IsNUnitRunning && TestContext.CurrentContext.Test.MethodName == nameof(TestConstructor))
return;

AddStep(new SingleStepButton(true)
AddStep(new SingleStepButton
{
Name = "set up dummy",
Text = "set up dummy",
IsSetupStep = true,
Action = () => setupStepsDummyRun++
});

Expand Down
35 changes: 10 additions & 25 deletions osu.Framework/Testing/Drawables/Steps/AssertButton.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

#nullable disable

using System;
using System.Diagnostics;
using System.Runtime.ExceptionServices;
using System.Text;
using NUnit.Framework;
using osuTK.Graphics;
Expand All @@ -13,15 +12,14 @@ namespace osu.Framework.Testing.Drawables.Steps
{
public partial class AssertButton : StepButton
{
public Func<bool> Assertion;
public string ExtendedDescription;
public StackTrace CallStack;
private readonly Func<string> getFailureMessage;
public required StackTrace CallStack { get; init; }
public required Func<bool> Assertion { get; init; }
public Func<string>? GetFailureMessage { get; init; }

public string? ExtendedDescription { get; init; }

public AssertButton(bool isSetupStep = false, Func<string> getFailureMessage = null)
: base(isSetupStep)
public AssertButton()
{
this.getFailureMessage = getFailureMessage;
Action += checkAssert;
LightColour = Color4.OrangeRed;
}
Expand All @@ -39,26 +37,13 @@ private void checkAssert()
if (!string.IsNullOrEmpty(ExtendedDescription))
builder.Append($" {ExtendedDescription}");

if (getFailureMessage != null)
builder.Append($": {getFailureMessage()}");
if (GetFailureMessage != null)
builder.Append($": {GetFailureMessage()}");

throw new TracedException(builder.ToString(), CallStack);
throw ExceptionDispatchInfo.SetRemoteStackTrace(new AssertionException(builder.ToString()), CallStack.ToString());
}
}

public override string ToString() => "Assert: " + base.ToString();

private class TracedException : AssertionException
{
private readonly StackTrace trace;

public TracedException(string description, StackTrace trace)
: base(description)
{
this.trace = trace;
}

public override string StackTrace => trace.ToString();
}
}
}
6 changes: 6 additions & 0 deletions osu.Framework/Testing/Drawables/Steps/LabelStep.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using osuTK.Graphics;

namespace osu.Framework.Testing.Drawables.Steps
{
public partial class LabelStep : StepButton
{
public new required Action<LabelStep> Action { get; init; }

protected override Color4 IdleColour => new Color4(77, 77, 77, 255);

protected override Color4 RunningColour => new Color4(128, 128, 128, 255);
Expand All @@ -15,6 +18,9 @@ public LabelStep()
{
Light.Hide();
Height = 30;
base.Action = clickAction;
}

private void clickAction() => Action(this);
}
}
30 changes: 12 additions & 18 deletions osu.Framework/Testing/Drawables/Steps/RepeatStepButton.cs
Original file line number Diff line number Diff line change
@@ -1,45 +1,39 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

#nullable disable

using System;

namespace osu.Framework.Testing.Drawables.Steps
{
public partial class RepeatStepButton : StepButton
{
private readonly int count;
private int invocations;
public int Count { get; init; } = 1;

public override int RequiredRepetitions => count;
public override int RequiredRepetitions => Count;

private string text;
private readonly string text = string.Empty;
private int invocations;

public new string Text
public RepeatStepButton()
{
get => text;
set => base.Text = text = value;
updateText();
}

public RepeatStepButton(Action action, int count = 1, bool isSetupStep = false)
: base(isSetupStep)
public new string Text
{
this.count = count;
Action = action;

updateText();
get => text;
init => base.Text = text = value;
}

public override void PerformStep(bool userTriggered = false)
{
if (invocations == count && !userTriggered) throw new InvalidOperationException("Repeat step was invoked too many times");
if (invocations == Count && !userTriggered) throw new InvalidOperationException("Repeat step was invoked too many times");

invocations++;

base.PerformStep(userTriggered);

if (invocations >= count) // Allows for manual execution beyond the invocation limit.
if (invocations >= Count) // Allows for manual execution beyond the invocation limit.
Success();

updateText();
Expand All @@ -53,7 +47,7 @@ public override void Reset()
updateText();
}

private void updateText() => base.Text = $@"{Text} {invocations}/{count}";
private void updateText() => base.Text = $@"{Text} {invocations}/{Count}";

public override string ToString() => "Repeat: " + base.ToString();
}
Expand Down
19 changes: 9 additions & 10 deletions osu.Framework/Testing/Drawables/Steps/SingleStepButton.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

#nullable disable

using System;

namespace osu.Framework.Testing.Drawables.Steps
{
public partial class SingleStepButton : StepButton
{
public new Action Action;
public new required Action Action { get; init; }

public SingleStepButton()
{
base.Action = clickAction;
}

public SingleStepButton(bool isSetupStep = false)
: base(isSetupStep)
private void clickAction()
{
base.Action = () =>
{
Action?.Invoke();
Success();
};
Action();
Success();
}
}
}
58 changes: 26 additions & 32 deletions osu.Framework/Testing/Drawables/Steps/StepButton.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

#nullable disable

using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
Expand All @@ -16,42 +14,20 @@ namespace osu.Framework.Testing.Drawables.Steps
{
public abstract partial class StepButton : CompositeDrawable
{
public virtual int RequiredRepetitions => 1;

protected Box Light;
protected Box Background;
protected SpriteText SpriteText;

public Action Action { get; set; }

public LocalisableString Text
{
get => SpriteText.Text;
set => SpriteText.Text = value;
}

private Color4 lightColour = Color4.BlueViolet;

public Color4 LightColour
{
get => lightColour;
set
{
lightColour = value;
if (IsLoaded) Reset();
}
}
public required bool IsSetupStep { get; init; }
public Action? Action { get; set; }

public readonly bool IsSetupStep;
public virtual int RequiredRepetitions => 1;

protected virtual Color4 IdleColour => new Color4(0.15f, 0.15f, 0.15f, 1);

protected virtual Color4 RunningColour => new Color4(0.5f, 0.5f, 0.5f, 1);

protected StepButton(bool isSetupStep = false)
{
IsSetupStep = isSetupStep;
protected readonly Box Light;
protected readonly Box Background;
protected readonly SpriteText SpriteText;

protected StepButton()
{
InternalChildren = new Drawable[]
{
Background = new Box
Expand Down Expand Up @@ -85,6 +61,24 @@ protected StepButton(bool isSetupStep = false)
Masking = true;
}

public LocalisableString Text
{
get => SpriteText.Text;
set => SpriteText.Text = value;
}

private Color4 lightColour = Color4.BlueViolet;

public Color4 LightColour
{
get => lightColour;
set
{
lightColour = value;
if (IsLoaded) Reset();
}
}

protected override void LoadComplete()
{
base.LoadComplete();
Expand Down
20 changes: 10 additions & 10 deletions osu.Framework/Testing/Drawables/Steps/ToggleStepButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,31 @@ namespace osu.Framework.Testing.Drawables.Steps
{
public partial class ToggleStepButton : StepButton
{
private readonly Action<bool>? reloadCallback;
private static readonly Color4 off_colour = Color4.Red;
private static readonly Color4 on_colour = Color4.YellowGreen;

public bool State;
public new required Action<bool> Action { get; init; }

public override int RequiredRepetitions => 2;

public ToggleStepButton(Action<bool>? reloadCallback)
private bool state;

public ToggleStepButton()
{
this.reloadCallback = reloadCallback;
Action = clickAction;
base.Action = clickAction;
LightColour = off_colour;
}

private void clickAction()
{
State = !State;
Light.FadeColour(State ? on_colour : off_colour);
reloadCallback?.Invoke(State);
state = !state;
Light.FadeColour(state ? on_colour : off_colour);
Action(state);

if (!State)
if (!state)
Success();
}

public override string ToString() => $"Toggle: {base.ToString()} ({(State ? "on" : "off")})";
public override string ToString() => $"Toggle: {base.ToString()} ({(state ? "on" : "off")})";
}
}
Loading
Loading