Merge remote-tracking branch 'upstream/master' into tournament-tools

This commit is contained in:
Dean Herbert
2019-03-02 13:11:34 +09:00
614 changed files with 7332 additions and 3325 deletions

View File

@ -27,7 +27,7 @@ namespace osu.Game.Tests.Visual
protected override void AddCheckSteps(Func<Player> player)
{
base.AddCheckSteps(player);
AddUntilStep(() => ((ScoreAccessiblePlayer)player()).ScoreProcessor.TotalScore > 0, "score above zero");
AddUntilStep(() => ((ScoreAccessiblePlayer)player()).ScoreProcessor.TotalScore.Value > 0, "score above zero");
AddUntilStep(() => ((ScoreAccessiblePlayer)player()).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 0), "key counter counted keys");
}

View File

@ -0,0 +1,414 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Framework.Input.States;
using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Database;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Scoring;
using osu.Game.Screens;
using osu.Game.Screens.Backgrounds;
using osu.Game.Screens.Play;
using osu.Game.Screens.Play.PlayerSettings;
using osu.Game.Screens.Select;
using osu.Game.Tests.Resources;
using osu.Game.Users;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Tests.Visual
{
[TestFixture]
public class TestCaseBackgroundScreenBeatmap : ManualInputManagerTestCase
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(ScreenWithBeatmapBackground),
typeof(PlayerLoader),
typeof(Player),
typeof(UserDimContainer),
typeof(OsuScreen)
};
private DummySongSelect songSelect;
private DimAccessiblePlayerLoader playerLoader;
private DimAccessiblePlayer player;
private DatabaseContextFactory factory;
private BeatmapManager manager;
private RulesetStore rulesets;
private ScreenStackCacheContainer screenStackContainer;
[BackgroundDependencyLoader]
private void load(GameHost host)
{
factory = new DatabaseContextFactory(LocalStorage);
factory.ResetDatabase();
using (var usage = factory.Get())
usage.Migrate();
factory.ResetDatabase();
using (var usage = factory.Get())
usage.Migrate();
Dependencies.Cache(rulesets = new RulesetStore(factory));
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, factory, rulesets, null, null, host, Beatmap.Default));
Dependencies.Cache(new OsuConfigManager(LocalStorage));
Beatmap.SetDefault();
}
[SetUp]
public virtual void SetUp()
{
Schedule(() =>
{
manager.Delete(manager.GetAllUsableBeatmapSets());
var temp = TestResources.GetTestBeatmapForImport();
manager.Import(temp);
Child = screenStackContainer = new ScreenStackCacheContainer { RelativeSizeAxes = Axes.Both };
screenStackContainer.ScreenStack.Push(songSelect = new DummySongSelect());
});
}
/// <summary>
/// Check if <see cref="PlayerLoader"/> properly triggers background dim previews when a user hovers over the visual settings panel.
/// </summary>
[Test]
public void PlayerLoaderSettingsHoverTest()
{
setupUserSettings();
AddStep("Start player loader", () => songSelect.Push(playerLoader = new DimAccessiblePlayerLoader(player = new DimAccessiblePlayer())));
AddUntilStep(() => playerLoader?.IsLoaded ?? false, "Wait for Player Loader to load");
AddAssert("Background retained from song select", () => songSelect.IsBackgroundCurrent());
AddStep("Trigger background preview", () =>
{
InputManager.MoveMouseTo(playerLoader.ScreenPos);
InputManager.MoveMouseTo(playerLoader.VisualSettingsPos);
});
waitForDim();
AddAssert("Screen is dimmed", () => songSelect.IsBackgroundDimmed());
AddStep("Stop background preview", () => InputManager.MoveMouseTo(playerLoader.ScreenPos));
waitForDim();
AddAssert("Screen is undimmed", () => songSelect.IsBackgroundUndimmed());
}
/// <summary>
/// In the case of a user triggering the dim preview the instant player gets loaded, then moving the cursor off of the visual settings:
/// The OnHover of PlayerLoader will trigger, which could potentially trigger an undim unless checked for in PlayerLoader.
/// We need to check that in this scenario, the dim is still properly applied after entering player.
/// </summary>
[Test]
public void PlayerLoaderTransitionTest()
{
performFullSetup();
AddStep("Trigger hover event", () => playerLoader.TriggerOnHover());
AddAssert("Background retained from song select", () => songSelect.IsBackgroundCurrent());
waitForDim();
AddAssert("Screen is dimmed and unblurred", () => songSelect.IsBackgroundDimmed() && songSelect.IsBackgroundUnblurred());
}
/// <summary>
/// Make sure the background is fully invisible (Alpha == 0) when the background should be disabled by the storyboard.
/// </summary>
[Test]
public void StoryboardBackgroundVisibilityTest()
{
performFullSetup();
createFakeStoryboard();
AddStep("Storyboard Enabled", () =>
{
player.ReplacesBackground.Value = true;
player.StoryboardEnabled.Value = true;
});
waitForDim();
AddAssert("Background is invisible, storyboard is visible", () => songSelect.IsBackgroundInvisible() && player.IsStoryboardVisible());
AddStep("Storyboard Disabled", () =>
{
player.ReplacesBackground.Value = false;
player.StoryboardEnabled.Value = false;
});
waitForDim();
AddAssert("Background is visible, storyboard is invisible", () => songSelect.IsBackgroundVisible() && player.IsStoryboardInvisible());
}
/// <summary>
/// When exiting player, the screen that it suspends/exits to needs to have a fully visible (Alpha == 1) background.
/// </summary>
[Test]
public void StoryboardTransitionTest()
{
performFullSetup();
createFakeStoryboard();
AddStep("Exit to song select", () => player.Exit());
waitForDim();
AddAssert("Background is visible", () => songSelect.IsBackgroundVisible());
}
/// <summary>
/// Check if the <see cref="UserDimContainer"/> is properly accepting user dim changes at all.
/// </summary>
[Test]
public void DisableUserDimTest()
{
performFullSetup();
waitForDim();
AddAssert("Screen is dimmed", () => songSelect.IsBackgroundDimmed());
AddStep("EnableUserDim disabled", () => songSelect.DimEnabled.Value = false);
waitForDim();
AddAssert("Screen is undimmed", () => songSelect.IsBackgroundUndimmed());
AddStep("EnableUserDim enabled", () => songSelect.DimEnabled.Value = true);
waitForDim();
AddAssert("Screen is dimmed", () => songSelect.IsBackgroundDimmed());
}
/// <summary>
/// Check if the fade container retains dim when pausing
/// </summary>
[Test]
public void PauseTest()
{
performFullSetup(true);
AddStep("Pause", () => player.CurrentPauseContainer.Pause());
waitForDim();
AddAssert("Screen is dimmed", () => songSelect.IsBackgroundDimmed());
AddStep("Unpause", () => player.CurrentPauseContainer.Resume());
waitForDim();
AddAssert("Screen is dimmed", () => songSelect.IsBackgroundDimmed());
}
/// <summary>
/// Check if the fade container removes user dim when suspending <see cref="Player"/> for <see cref="SoloResults"/>
/// </summary>
[Test]
public void TransitionTest()
{
performFullSetup();
AddStep("Transition to Results", () => player.Push(new FadeAccessibleResults(new ScoreInfo { User = new User { Username = "osu!" } })));
waitForDim();
AddAssert("Screen is undimmed and is original background", () => songSelect.IsBackgroundUndimmed() && songSelect.IsBackgroundCurrent());
}
/// <summary>
/// Check if background gets undimmed when leaving <see cref="Player"/> for <see cref="PlaySongSelect"/>
/// </summary>
[Test]
public void TransitionOutTest()
{
performFullSetup();
AddStep("Exit to song select", () => player.Exit());
waitForDim();
AddAssert("Screen is undimmed", () => songSelect.IsBackgroundUndimmed());
}
private void waitForDim() => AddWaitStep(5, "Wait for dim");
private void createFakeStoryboard() => AddStep("Create storyboard", () =>
{
player.StoryboardEnabled.Value = false;
player.ReplacesBackground.Value = false;
player.CurrentStoryboardContainer.Add(new SpriteText
{
Size = new Vector2(250, 50),
Alpha = 1,
Colour = Color4.Tomato,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Text = "THIS IS A STORYBOARD",
});
});
private void performFullSetup(bool allowPause = false)
{
setupUserSettings();
AddStep("Start player loader", () =>
{
songSelect.Push(playerLoader = new DimAccessiblePlayerLoader(player = new DimAccessiblePlayer
{
AllowPause = allowPause,
Ready = true,
}));
});
AddUntilStep(() => playerLoader.IsLoaded, "Wait for Player Loader to load");
AddStep("Move mouse to center of screen", () => InputManager.MoveMouseTo(playerLoader.ScreenPos));
AddUntilStep(() => player.IsLoaded, "Wait for player to load");
}
private void setupUserSettings()
{
AddUntilStep(() => songSelect.Carousel.SelectedBeatmap != null, "Song select has selection");
AddStep("Set default user settings", () =>
{
Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { new OsuModNoFail() });
songSelect.DimLevel.Value = 0.7f;
songSelect.BlurLevel.Value = 0.0f;
});
}
private class DummySongSelect : PlaySongSelect
{
protected override BackgroundScreen CreateBackground()
{
FadeAccessibleBackground background = new FadeAccessibleBackground(Beatmap.Value);
DimEnabled.BindTo(background.EnableUserDim);
return background;
}
public readonly Bindable<bool> DimEnabled = new Bindable<bool>();
public readonly Bindable<double> DimLevel = new Bindable<double>();
public readonly Bindable<double> BlurLevel = new Bindable<double>();
public new BeatmapCarousel Carousel => base.Carousel;
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
config.BindWith(OsuSetting.DimLevel, DimLevel);
config.BindWith(OsuSetting.BlurLevel, BlurLevel);
}
public bool IsBackgroundDimmed() => ((FadeAccessibleBackground)Background).CurrentColour == OsuColour.Gray(1 - (float)DimLevel.Value);
public bool IsBackgroundUnblurred() => ((FadeAccessibleBackground)Background).CurrentBlur == new Vector2(0);
public bool IsBackgroundUndimmed() => ((FadeAccessibleBackground)Background).CurrentColour == Color4.White;
public bool IsBackgroundInvisible() => ((FadeAccessibleBackground)Background).CurrentAlpha == 0;
public bool IsBackgroundVisible() => ((FadeAccessibleBackground)Background).CurrentAlpha == 1;
/// <summary>
/// Make sure every time a screen gets pushed, the background doesn't get replaced
/// </summary>
/// <returns>Whether or not the original background (The one created in DummySongSelect) is still the current background</returns>
public bool IsBackgroundCurrent() => ((FadeAccessibleBackground)Background).IsCurrentScreen();
}
private class FadeAccessibleResults : SoloResults
{
public FadeAccessibleResults(ScoreInfo score)
: base(score)
{
}
protected override BackgroundScreen CreateBackground() => new FadeAccessibleBackground(Beatmap.Value);
}
private class DimAccessiblePlayer : Player
{
protected override BackgroundScreen CreateBackground() => new FadeAccessibleBackground(Beatmap.Value);
protected override UserDimContainer CreateStoryboardContainer()
{
return new TestUserDimContainer(true)
{
RelativeSizeAxes = Axes.Both,
Alpha = 1,
EnableUserDim = { Value = true }
};
}
public PauseContainer CurrentPauseContainer => PauseContainer;
public UserDimContainer CurrentStoryboardContainer => StoryboardContainer;
// Whether or not the player should be allowed to load.
public bool Ready;
public Bindable<bool> StoryboardEnabled;
public readonly Bindable<bool> ReplacesBackground = new Bindable<bool>();
public readonly Bindable<bool> IsPaused = new Bindable<bool>();
public bool IsStoryboardVisible() => ((TestUserDimContainer)CurrentStoryboardContainer).CurrentAlpha == 1;
public bool IsStoryboardInvisible() => ((TestUserDimContainer)CurrentStoryboardContainer).CurrentAlpha <= 1;
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
while (!Ready)
Thread.Sleep(1);
StoryboardEnabled = config.GetBindable<bool>(OsuSetting.ShowStoryboard);
ReplacesBackground.BindTo(Background.StoryboardReplacesBackground);
RulesetContainer.IsPaused.BindTo(IsPaused);
}
}
private class ScreenStackCacheContainer : Container
{
[Cached]
private BackgroundScreenStack backgroundScreenStack;
public readonly ScreenStack ScreenStack;
public ScreenStackCacheContainer()
{
Add(backgroundScreenStack = new BackgroundScreenStack { RelativeSizeAxes = Axes.Both });
Add(ScreenStack = new ScreenStack { RelativeSizeAxes = Axes.Both });
}
}
private class DimAccessiblePlayerLoader : PlayerLoader
{
public VisualSettings VisualSettingsPos => VisualSettings;
public BackgroundScreen ScreenPos => Background;
public DimAccessiblePlayerLoader(Player player)
: base(() => player)
{
}
public void TriggerOnHover() => OnHover(new HoverEvent(new InputState()));
protected override BackgroundScreen CreateBackground() => new FadeAccessibleBackground(Beatmap.Value);
}
private class FadeAccessibleBackground : BackgroundScreenBeatmap
{
protected override UserDimContainer CreateFadeContainer() => fadeContainer = new TestUserDimContainer { RelativeSizeAxes = Axes.Both };
public Color4 CurrentColour => fadeContainer.CurrentColour;
public float CurrentAlpha => fadeContainer.CurrentAlpha;
public Vector2 CurrentBlur => Background.BlurSigma;
private TestUserDimContainer fadeContainer;
public FadeAccessibleBackground(WorkingBeatmap beatmap)
: base(beatmap)
{
}
}
private class TestUserDimContainer : UserDimContainer
{
public Color4 CurrentColour => DimContainer.Colour;
public float CurrentAlpha => DimContainer.Alpha;
public TestUserDimContainer(bool isStoryboard = false)
: base(isStoryboard)
{
}
}
}
}

View File

@ -15,6 +15,7 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Overlays;
using osuTK.Graphics;
using osu.Framework.Lists;
using osu.Game.Graphics;
namespace osu.Game.Tests.Visual
{
@ -140,6 +141,7 @@ namespace osu.Game.Tests.Visual
}
private SortedList<TimingControlPoint> timingPoints => Beatmap.Value.Beatmap.ControlPointInfo.TimingPoints;
private TimingControlPoint getNextTimingPoint(TimingControlPoint current)
{
if (timingPoints[timingPoints.Count - 1] == current)
@ -189,15 +191,15 @@ namespace osu.Game.Tests.Visual
public double Value
{
set { valueText.Text = $"{value:G}"; }
set => valueText.Text = $"{value:G}";
}
public InfoString(string header)
{
AutoSizeAxes = Axes.Both;
Direction = FillDirection.Horizontal;
Add(new OsuSpriteText { Text = header + @": ", TextSize = text_size });
Add(valueText = new OsuSpriteText { TextSize = text_size });
Add(new OsuSpriteText { Text = header + @": ", Font = OsuFont.GetFont(size: text_size) });
Add(valueText = new OsuSpriteText { Font = OsuFont.GetFont(size: text_size) });
Margin = new MarginPadding(margin);
}
}

View File

@ -147,9 +147,10 @@ namespace osu.Game.Tests.Visual
private bool selectedBeatmapVisible()
{
var currentlySelected = carousel.Items.Find(s => s.Item is CarouselBeatmap && s.Item.State == CarouselItemState.Selected);
var currentlySelected = carousel.Items.Find(s => s.Item is CarouselBeatmap && s.Item.State.Value == CarouselItemState.Selected);
if (currentlySelected == null)
return true;
return currentlySelected.Item.Visible;
}
@ -166,8 +167,7 @@ namespace osu.Game.Tests.Visual
carousel.Filter(new FilterCriteria { SearchText = "Dingo" }, false);
carousel.Filter(new FilterCriteria(), false);
eagerSelectedIDs.Add(carousel.SelectedBeatmapSet.ID);
}
);
});
}
/// <summary>
@ -522,6 +522,7 @@ namespace osu.Game.Tests.Visual
}
});
}
return toReturn;
}

View File

@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual
Padding = new MarginPadding(150),
});
AddStep("beatmap all metrics", () => details.Beatmap = new BeatmapInfo
AddStep("all metrics", () => details.Beatmap = new BeatmapInfo
{
Version = "All Metrics",
Metadata = new BeatmapMetadata
@ -45,7 +45,30 @@ namespace osu.Game.Tests.Visual
},
});
AddStep("beatmap ratings", () => details.Beatmap = new BeatmapInfo
AddStep("all except source", () => details.Beatmap = new BeatmapInfo
{
Version = "All Metrics",
Metadata = new BeatmapMetadata
{
Tags = "this beatmap has all the metrics",
},
BaseDifficulty = new BeatmapDifficulty
{
CircleSize = 7,
DrainRate = 1,
OverallDifficulty = 5.7f,
ApproachRate = 3.5f,
},
StarDifficulty = 5.3f,
Metrics = new BeatmapMetrics
{
Ratings = Enumerable.Range(0, 11),
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
},
});
AddStep("ratings", () => details.Beatmap = new BeatmapInfo
{
Version = "Only Ratings",
Metadata = new BeatmapMetadata
@ -67,7 +90,7 @@ namespace osu.Game.Tests.Visual
},
});
AddStep("beatmap fails retries", () => details.Beatmap = new BeatmapInfo
AddStep("fails retries", () => details.Beatmap = new BeatmapInfo
{
Version = "Only Retries and Fails",
Metadata = new BeatmapMetadata
@ -90,7 +113,7 @@ namespace osu.Game.Tests.Visual
},
});
AddStep("beatmap no metrics", () => details.Beatmap = new BeatmapInfo
AddStep("no metrics", () => details.Beatmap = new BeatmapInfo
{
Version = "No Metrics",
Metadata = new BeatmapMetadata

View File

@ -50,7 +50,7 @@ namespace osu.Game.Tests.Visual
AddStep("show", () =>
{
infoWedge.State = Visibility.Visible;
infoWedge.Beatmap = Beatmap;
infoWedge.Beatmap = Beatmap.Value;
});
// select part is redundant, but wait for load isn't

View File

@ -160,7 +160,8 @@ namespace osu.Game.Tests.Visual
Accuracy = 0.6543,
},
};
foreach(var s in scores)
foreach (var s in scores)
{
s.Statistics.Add(HitResult.Great, RNG.Next(2000));
s.Statistics.Add(HitResult.Good, RNG.Next(2000));

View File

@ -69,7 +69,7 @@ namespace osu.Game.Tests.Visual
});
channelTabControl.OnRequestLeave += channel => channelTabControl.RemoveChannel(channel);
channelTabControl.Current.ValueChanged += channel => currentText.Text = "Currently selected channel: " + channel.ToString();
channelTabControl.Current.ValueChanged += channel => currentText.Text = "Currently selected channel: " + channel.NewValue.ToString();
AddStep("Add random private channel", addRandomPrivateChannel);
AddAssert("There is only one channels", () => channelTabControl.Items.Count() == 2);

View File

@ -13,10 +13,10 @@ using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Bindables;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Overlays;
using osu.Framework.Configuration;
namespace osu.Game.Tests.Visual
{
@ -56,7 +56,7 @@ namespace osu.Game.Tests.Visual
var chatManager = new ChannelManager();
BindableList<Channel> availableChannels = (BindableList<Channel>)chatManager.AvailableChannels;
availableChannels.Add(new Channel { Name = "#english"});
availableChannels.Add(new Channel { Name = "#english" });
availableChannels.Add(new Channel { Name = "#japanese" });
Dependencies.Cache(chatManager);
@ -96,7 +96,7 @@ namespace osu.Game.Tests.Visual
return true;
}
bool isItalic() => newLine.ContentFlow.Where(d => d is OsuSpriteText).Cast<OsuSpriteText>().All(sprite => sprite.Font == "Exo2.0-MediumItalic");
bool isItalic() => newLine.ContentFlow.Where(d => d is OsuSpriteText).Cast<OsuSpriteText>().All(sprite => sprite.Font.Italics);
bool isShowingLinks()
{

View File

@ -61,10 +61,10 @@ namespace osu.Game.Tests.Visual
// Move box along a square trajectory
container.Loop(c => c
.MoveTo(new Vector2(0, 100), duration).Then()
.MoveTo(new Vector2(100, 100), duration).Then()
.MoveTo(new Vector2(100, 0), duration).Then()
.MoveTo(Vector2.Zero, duration)
.MoveTo(new Vector2(0, 100), duration).Then()
.MoveTo(new Vector2(100, 100), duration).Then()
.MoveTo(new Vector2(100, 0), duration).Then()
.MoveTo(Vector2.Zero, duration)
);
}

View File

@ -60,7 +60,7 @@ namespace osu.Game.Tests.Visual
}
};
drawableDate.Current.ValueChanged += v => flash.FadeOutFromOne(500);
drawableDate.Current.ValueChanged += _ => flash.FadeOutFromOne(500);
}
}
}

View File

@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual
[BackgroundDependencyLoader]
private void load()
{
Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo);
Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo, Clock);
Child = new ComposeScreen();
}
}

View File

@ -5,7 +5,7 @@ using System;
using System.Collections.Generic;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Bindables;
using osuTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;

View File

@ -33,7 +33,7 @@ namespace osu.Game.Tests.Visual
{
TimingPoints =
{
new TimingControlPoint { Time = 0, BeatLength = 200},
new TimingControlPoint { Time = 0, BeatLength = 200 },
new TimingControlPoint { Time = 100, BeatLength = 400 },
new TimingControlPoint { Time = 175, BeatLength = 800 },
new TimingControlPoint { Time = 350, BeatLength = 200 },
@ -48,7 +48,7 @@ namespace osu.Game.Tests.Visual
}
};
Beatmap.Value = new TestWorkingBeatmap(testBeatmap);
Beatmap.Value = new TestWorkingBeatmap(testBeatmap, Clock);
Child = new TimingPointVisualiser(testBeatmap, 5000) { Clock = Clock };
}

View File

@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual
[BackgroundDependencyLoader]
private void load()
{
Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo);
Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo, null);
Add(new SummaryTimeline
{

View File

@ -76,7 +76,7 @@ namespace osu.Game.Tests.Visual
AddStep("Hover first button", () => InputManager.MoveMouseTo(failOverlay.Buttons.First()));
AddStep("Hide overlay", () => failOverlay.Hide());
AddAssert("Overlay state is reset", () => !failOverlay.Buttons.Any(b => b.Selected));
AddAssert("Overlay state is reset", () => !failOverlay.Buttons.Any(b => b.Selected.Value));
}
private void press(Key key)
@ -106,7 +106,7 @@ namespace osu.Game.Tests.Visual
AddStep("Show overlay", () => pauseOverlay.Show());
AddStep("Up arrow", () => press(Key.Up));
AddAssert("Last button selected", () => pauseOverlay.Buttons.Last().Selected);
AddAssert("Last button selected", () => pauseOverlay.Buttons.Last().Selected.Value);
AddStep("Hide overlay", () => pauseOverlay.Hide());
}
@ -119,7 +119,7 @@ namespace osu.Game.Tests.Visual
AddStep("Show overlay", () => pauseOverlay.Show());
AddStep("Down arrow", () => press(Key.Down));
AddAssert("First button selected", () => pauseOverlay.Buttons.First().Selected);
AddAssert("First button selected", () => pauseOverlay.Buttons.First().Selected.Value);
AddStep("Hide overlay", () => pauseOverlay.Hide());
}
@ -132,11 +132,11 @@ namespace osu.Game.Tests.Visual
AddStep("Show overlay", () => failOverlay.Show());
AddStep("Up arrow", () => press(Key.Up));
AddAssert("Last button selected", () => failOverlay.Buttons.Last().Selected);
AddAssert("Last button selected", () => failOverlay.Buttons.Last().Selected.Value);
AddStep("Up arrow", () => press(Key.Up));
AddAssert("First button selected", () => failOverlay.Buttons.First().Selected);
AddAssert("First button selected", () => failOverlay.Buttons.First().Selected.Value);
AddStep("Up arrow", () => press(Key.Up));
AddAssert("Last button selected", () => failOverlay.Buttons.Last().Selected);
AddAssert("Last button selected", () => failOverlay.Buttons.Last().Selected.Value);
AddStep("Hide overlay", () => failOverlay.Hide());
}
@ -149,11 +149,11 @@ namespace osu.Game.Tests.Visual
AddStep("Show overlay", () => failOverlay.Show());
AddStep("Down arrow", () => press(Key.Down));
AddAssert("First button selected", () => failOverlay.Buttons.First().Selected);
AddAssert("First button selected", () => failOverlay.Buttons.First().Selected.Value);
AddStep("Down arrow", () => press(Key.Down));
AddAssert("Last button selected", () => failOverlay.Buttons.Last().Selected);
AddAssert("Last button selected", () => failOverlay.Buttons.Last().Selected.Value);
AddStep("Down arrow", () => press(Key.Down));
AddAssert("First button selected", () => failOverlay.Buttons.First().Selected);
AddAssert("First button selected", () => failOverlay.Buttons.First().Selected.Value);
AddStep("Hide overlay", () => failOverlay.Hide());
}
@ -169,8 +169,8 @@ namespace osu.Game.Tests.Visual
AddStep("Down arrow", () => press(Key.Down));
AddStep("Hover second button", () => InputManager.MoveMouseTo(secondButton));
AddAssert("First button not selected", () => !pauseOverlay.Buttons.First().Selected);
AddAssert("Second button selected", () => secondButton.Selected);
AddAssert("First button not selected", () => !pauseOverlay.Buttons.First().Selected.Value);
AddAssert("Second button selected", () => secondButton.Selected.Value);
AddStep("Hide overlay", () => pauseOverlay.Hide());
}
@ -190,8 +190,8 @@ namespace osu.Game.Tests.Visual
AddStep("Hover second button", () => InputManager.MoveMouseTo(secondButton));
AddStep("Up arrow", () => press(Key.Up));
AddAssert("Second button not selected", () => !secondButton.Selected);
AddAssert("First button selected", () => pauseOverlay.Buttons.First().Selected);
AddAssert("Second button not selected", () => !secondButton.Selected.Value);
AddAssert("First button selected", () => pauseOverlay.Buttons.First().Selected.Value);
AddStep("Hide overlay", () => pauseOverlay.Hide());
}
@ -208,7 +208,7 @@ namespace osu.Game.Tests.Visual
AddStep("Hover second button", () => InputManager.MoveMouseTo(secondButton));
AddStep("Unhover second button", () => InputManager.MoveMouseTo(Vector2.Zero));
AddStep("Down arrow", () => press(Key.Down));
AddAssert("First button selected", () => pauseOverlay.Buttons.First().Selected); // Initial state condition
AddAssert("First button selected", () => pauseOverlay.Buttons.First().Selected.Value); // Initial state condition
AddStep("Hide overlay", () => pauseOverlay.Hide());
}
@ -265,6 +265,7 @@ namespace osu.Game.Tests.Visual
pauseOverlay.OnRetry = lastAction;
lastAction = null;
}
return triggered;
});
AddAssert("Overlay is closed", () => pauseOverlay.State == Visibility.Hidden);

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Screens.Menu;
@ -22,7 +23,7 @@ namespace osu.Game.Tests.Visual
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Text = "Fired!",
TextSize = 50,
Font = OsuFont.GetFont(size: 50),
Alpha = 0,
};

View File

@ -128,7 +128,7 @@ namespace osu.Game.Tests.Visual
},
};
idleTracker.IsIdle.BindValueChanged(idle => box.Colour = idle ? Color4.White : Color4.Black, true);
idleTracker.IsIdle.BindValueChanged(idle => box.Colour = idle.NewValue ? Color4.White : Color4.Black, true);
}
}
}

View File

@ -20,7 +20,8 @@ namespace osu.Game.Tests.Visual
[Description("PlaySongSelect leaderboard")]
public class TestCaseLeaderboard : OsuTestCase
{
public override IReadOnlyList<Type> RequiredTypes => new[] {
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(Placeholder),
typeof(MessagePlaceholder),
typeof(RetrievalFailurePlaceholder),

View File

@ -5,7 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Graphics;
using osu.Game.Online.Multiplayer;

View File

@ -3,7 +3,7 @@
using System;
using System.Collections.Generic;
using osu.Framework.Configuration;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Screens.Multi.Match.Components;
using osu.Game.Users;

View File

@ -5,7 +5,7 @@ using System;
using System.Collections.Generic;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
@ -52,16 +52,16 @@ namespace osu.Game.Tests.Visual
Room.Playlist.Clear();
});
AddAssert("button disabled", () => !settings.ApplyButton.Enabled);
AddAssert("button disabled", () => !settings.ApplyButton.Enabled.Value);
AddStep("set name", () => Room.Name.Value = "Room name");
AddAssert("button disabled", () => !settings.ApplyButton.Enabled);
AddAssert("button disabled", () => !settings.ApplyButton.Enabled.Value);
AddStep("set beatmap", () => Room.Playlist.Add(new PlaylistItem { Beatmap = new DummyWorkingBeatmap().BeatmapInfo }));
AddAssert("button enabled", () => settings.ApplyButton.Enabled);
AddAssert("button enabled", () => settings.ApplyButton.Enabled.Value);
AddStep("clear name", () => Room.Name.Value = "");
AddAssert("button disabled", () => !settings.ApplyButton.Enabled);
AddAssert("button disabled", () => !settings.ApplyButton.Enabled.Value);
}
[Test]

View File

@ -13,7 +13,7 @@ using osu.Game.Rulesets.Osu.Mods;
using System.Linq;
using System.Collections.Generic;
using NUnit.Framework;
using osu.Framework.Configuration;
using osu.Framework.Bindables;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.Sprites;
using osu.Game.Overlays.Mods.Sections;

View File

@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
using osu.Framework.Screens;
using osu.Game.Screens.Multi;
using osu.Game.Screens.Multi.Lounge;
using osu.Game.Screens.Multi.Lounge.Components;
@ -26,8 +25,6 @@ namespace osu.Game.Tests.Visual
Multiplayer multi = new Multiplayer();
AddStep(@"show", () => LoadScreen(multi));
AddWaitStep(5);
AddStep(@"exit", multi.Exit);
}
}
}

View File

@ -47,7 +47,7 @@ namespace osu.Game.Tests.Visual
void setState(Visibility state) => AddStep(state.ToString(), () => manager.State = state);
void checkProgressingCount(int expected) => AddAssert($"progressing count is {expected}", () => progressingNotifications.Count == expected);
manager.UnreadCount.ValueChanged += count => { displayedCount.Text = $"displayed count: {count}"; };
manager.UnreadCount.ValueChanged += count => { displayedCount.Text = $"displayed count: {count.NewValue}"; };
setState(Visibility.Visible);
AddStep(@"simple #1", sendHelloNotification);

View File

@ -4,10 +4,10 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Screens;
using osu.Game.Screens;
using osu.Framework.Platform;
using osu.Game.Screens.Menu;
using osuTK.Graphics;
@ -21,8 +21,12 @@ namespace osu.Game.Tests.Visual
typeof(OsuLogo),
};
public TestCaseOsuGame()
[BackgroundDependencyLoader]
private void load(GameHost host)
{
OsuGame game = new OsuGame();
game.SetHost(host);
Children = new Drawable[]
{
new Box
@ -30,10 +34,7 @@ namespace osu.Game.Tests.Visual
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
},
new ScreenStack(new Loader())
{
RelativeSizeAxes = Axes.Both,
}
game
};
}
}

View File

@ -8,7 +8,7 @@ using System.Linq;
using System.Text;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.MathUtils;
using osu.Framework.Platform;
@ -187,8 +187,8 @@ namespace osu.Game.Tests.Visual
AddAssert("mods changed before ruleset", () => modChangeIndex < rulesetChangeIndex);
AddAssert("empty mods", () => !selectedMods.Value.Any());
void onModChange(IEnumerable<Mod> mods) => modChangeIndex = actionIndex++;
void onRulesetChange(RulesetInfo ruleset) => rulesetChangeIndex = actionIndex--;
void onModChange(ValueChangedEvent<IEnumerable<Mod>> e) => modChangeIndex = actionIndex++;
void onRulesetChange(ValueChangedEvent<RulesetInfo> e) => rulesetChangeIndex = actionIndex--;
}
[Test]

View File

@ -26,10 +26,10 @@ namespace osu.Game.Tests.Visual
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(200,100)
Size = new Vector2(200, 100)
};
Beatmap.Value = new TestWorkingBeatmap(new Beatmap());
Beatmap.Value = new TestWorkingBeatmap(new Beatmap(), Clock);
Child = playback;
}

View File

@ -6,6 +6,7 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Screens;
using osu.Game.Beatmaps;
using osu.Game.Screens;
using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual
@ -13,15 +14,22 @@ namespace osu.Game.Tests.Visual
public class TestCasePlayerLoader : ManualInputManagerTestCase
{
private PlayerLoader loader;
private ScreenStack stack;
private readonly ScreenStack stack;
[Cached]
private BackgroundScreenStack backgroundStack;
public TestCasePlayerLoader()
{
InputManager.Add(backgroundStack = new BackgroundScreenStack { RelativeSizeAxes = Axes.Both });
InputManager.Add(stack = new ScreenStack { RelativeSizeAxes = Axes.Both });
}
[BackgroundDependencyLoader]
private void load(OsuGameBase game)
{
Beatmap.Value = new DummyWorkingBeatmap(game);
InputManager.Add(stack = new ScreenStack { RelativeSizeAxes = Axes.Both });
AddStep("load dummy beatmap", () => stack.Push(loader = new PlayerLoader(() => new Player
{
AllowPause = false,

View File

@ -56,6 +56,7 @@ namespace osu.Game.Tests.Visual
});
[Test]
[Ignore("polling is threaded, and it's very hard to hook into it correctly")]
public void TestInstantPolling()
{
createPoller(true);
@ -106,8 +107,11 @@ namespace osu.Game.Tests.Visual
private void checkCount(int checkValue)
{
Logger.Log($"value is {count}");
AddAssert($"count is {checkValue}", () => count == checkValue);
AddAssert($"count is {checkValue}", () =>
{
Logger.Log($"value is {count}");
return count == checkValue;
});
}
private void createPoller(bool instant) => AddStep("create poller", () =>

View File

@ -74,7 +74,7 @@ namespace osu.Game.Tests.Visual
AddStep(@"Hit! :D", delegate
{
score.Current.Value += 300 + (ulong)(300.0 * (comboCounter.Current > 0 ? comboCounter.Current - 1 : 0) / 25.0);
score.Current.Value += 300 + (ulong)(300.0 * (comboCounter.Current.Value > 0 ? comboCounter.Current.Value - 1 : 0) / 25.0);
comboCounter.Increment();
numerator++;
denominator++;

View File

@ -48,7 +48,7 @@ namespace osu.Game.Tests.Visual
},
};
breadcrumbs.Current.ValueChanged += s => titleText.Text = $"Changed to {s.ToString()}";
breadcrumbs.Current.ValueChanged += screen => titleText.Text = $"Changed to {screen.NewValue.ToString()}";
breadcrumbs.Current.TriggerChange();
waitForCurrent();
@ -84,7 +84,7 @@ namespace osu.Game.Tests.Visual
public TestScreen PushNext()
{
TestScreen screen = CreateNextScreen();
this.Push(screen);
this.Push(screen);
return screen;
}

View File

@ -0,0 +1,153 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using NUnit.Framework;
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Graphics;
using osu.Game.Skinning;
using osuTK.Graphics;
namespace osu.Game.Tests.Visual
{
public class TestCaseSkinReloadable : OsuTestCase
{
[Test]
public void TestInitialLoad()
{
var secondarySource = new SecondarySource();
SkinConsumer consumer = null;
AddStep("setup layout", () =>
{
Child = new SkinSourceContainer
{
RelativeSizeAxes = Axes.Both,
Child = new LocalSkinOverrideContainer(secondarySource)
{
RelativeSizeAxes = Axes.Both,
Child = consumer = new SkinConsumer("test", name => new NamedBox("Default Implementation"), source => true)
}
};
});
AddAssert("consumer using override source", () => consumer.Drawable is SecondarySourceBox);
AddAssert("skinchanged only called once", () => consumer.SkinChangedCount == 1);
}
[Test]
public void TestOverride()
{
var secondarySource = new SecondarySource();
SkinConsumer consumer = null;
Container target = null;
AddStep("setup layout", () =>
{
Child = new SkinSourceContainer
{
RelativeSizeAxes = Axes.Both,
Child = target = new LocalSkinOverrideContainer(secondarySource)
{
RelativeSizeAxes = Axes.Both,
}
};
});
AddStep("add permissive", () => target.Add(consumer = new SkinConsumer("test", name => new NamedBox("Default Implementation"), source => true)));
AddAssert("consumer using override source", () => consumer.Drawable is SecondarySourceBox);
AddAssert("skinchanged only called once", () => consumer.SkinChangedCount == 1);
}
private class NamedBox : Container
{
public NamedBox(string name)
{
Children = new Drawable[]
{
new Box
{
Colour = Color4.Black,
RelativeSizeAxes = Axes.Both,
},
new SpriteText
{
Font = OsuFont.Default.With(size: 40),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Text = name
}
};
}
}
private class SkinConsumer : SkinnableDrawable
{
public new Drawable Drawable => base.Drawable;
public int SkinChangedCount { get; private set; }
public SkinConsumer(string name, Func<string, Drawable> defaultImplementation, Func<ISkinSource, bool> allowFallback = null, bool restrictSize = true)
: base(name, defaultImplementation, allowFallback, restrictSize)
{
}
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
{
base.SkinChanged(skin, allowFallback);
SkinChangedCount++;
}
}
private class BaseSourceBox : NamedBox
{
public BaseSourceBox()
: base("Base Source")
{
}
}
private class SecondarySourceBox : NamedBox
{
public SecondarySourceBox()
: base("Secondary Source")
{
}
}
private class SecondarySource : ISkinSource
{
public event Action SourceChanged;
public void TriggerSourceChanged() => SourceChanged?.Invoke();
public Drawable GetDrawableComponent(string componentName) => new SecondarySourceBox();
public Texture GetTexture(string componentName) => throw new NotImplementedException();
public SampleChannel GetSample(string sampleName) => throw new NotImplementedException();
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration => throw new NotImplementedException();
}
private class SkinSourceContainer : Container, ISkinSource
{
public event Action SourceChanged;
public void TriggerSourceChanged() => SourceChanged?.Invoke();
public Drawable GetDrawableComponent(string componentName) => new BaseSourceBox();
public Texture GetTexture(string componentName) => throw new NotImplementedException();
public SampleChannel GetSample(string sampleName) => throw new NotImplementedException();
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration => throw new NotImplementedException();
}
}
}

View File

@ -15,7 +15,7 @@ namespace osu.Game.Tests.Visual
public class TestCaseSongProgress : OsuTestCase
{
private readonly SongProgress progress;
private readonly SongProgressGraph graph;
private readonly TestSongProgressGraph graph;
private readonly StopwatchClock clock;
@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual
Origin = Anchor.BottomLeft,
});
Add(graph = new SongProgressGraph
Add(graph = new TestSongProgressGraph
{
RelativeSizeAxes = Axes.X,
Height = 200,
@ -39,13 +39,24 @@ namespace osu.Game.Tests.Visual
Origin = Anchor.TopLeft,
});
AddWaitStep(5);
AddAssert("ensure not created", () => graph.CreationCount == 0);
AddStep("display values", displayNewValues);
AddWaitStep(5);
AddUntilStep(() => graph.CreationCount == 1, "wait for creation count");
AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking);
AddWaitStep(5);
AddUntilStep(() => graph.CreationCount == 1, "wait for creation count");
AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking);
AddWaitStep(2);
AddWaitStep(5);
AddUntilStep(() => graph.CreationCount == 1, "wait for creation count");
AddRepeatStep("New Values", displayNewValues, 5);
displayNewValues();
AddWaitStep(5);
AddAssert("ensure debounced", () => graph.CreationCount == 2);
}
private void displayNewValues()
@ -60,5 +71,16 @@ namespace osu.Game.Tests.Visual
progress.AudioClock = clock;
progress.OnSeek = pos => clock.Seek(pos);
}
private class TestSongProgressGraph : SongProgressGraph
{
public int CreationCount { get; private set; }
protected override void RecreateGraph()
{
base.RecreateGraph();
CreationCount++;
}
}
}
}

View File

@ -3,6 +3,7 @@
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -49,7 +50,10 @@ namespace osu.Game.Tests.Visual
});
AddStep("Restart", restart);
AddToggleStep("Passing", passing => { if (storyboard != null) storyboard.Passing = passing; });
AddToggleStep("Passing", passing =>
{
if (storyboard != null) storyboard.Passing = passing;
});
}
[BackgroundDependencyLoader]
@ -58,15 +62,15 @@ namespace osu.Game.Tests.Visual
Beatmap.ValueChanged += beatmapChanged;
}
private void beatmapChanged(WorkingBeatmap working)
=> loadStoryboard(working);
private void beatmapChanged(ValueChangedEvent<WorkingBeatmap> e)
=> loadStoryboard(e.NewValue);
private void restart()
{
var track = Beatmap.Value.Track;
track.Reset();
loadStoryboard(Beatmap);
loadStoryboard(Beatmap.Value);
track.Start();
}
@ -78,7 +82,7 @@ namespace osu.Game.Tests.Visual
var decoupledClock = new DecoupleableInterpolatingFramedClock { IsCoupled = true };
storyboardContainer.Clock = decoupledClock;
storyboard = working.Storyboard.CreateDrawable(Beatmap);
storyboard = working.Storyboard.CreateDrawable(Beatmap.Value);
storyboard.Passing = false;
storyboardContainer.Add(storyboard);

View File

@ -33,9 +33,9 @@ namespace osu.Game.Tests.Visual
filter.PinItem(GroupMode.All);
filter.PinItem(GroupMode.RecentlyPlayed);
filter.Current.ValueChanged += newFilter =>
filter.Current.ValueChanged += grouping =>
{
text.Text = "Currently Selected: " + newFilter.ToString();
text.Text = "Currently Selected: " + grouping.NewValue.ToString();
};
}
}

View File

@ -3,7 +3,7 @@
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;

View File

@ -41,7 +41,7 @@ namespace osu.Game.Tests.Visual
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
TextSize = 20,
Font = OsuFont.GetFont(size: 20),
Text = @"Wave Container",
},
},