Merge remote-tracking branch 'refs/remotes/ppy/master' into toolbar-rulesets-refactor

This commit is contained in:
Andrei Zavatski
2019-06-24 01:06:54 +03:00
173 changed files with 8914 additions and 1348 deletions

View File

@ -25,6 +25,7 @@ namespace osu.Game.Tests.Visual.Components
{
box1 = new IdleTrackingBox(1000)
{
Name = "TopLeft",
RelativeSizeAxes = Axes.Both,
Colour = Color4.Red,
Anchor = Anchor.TopLeft,
@ -32,6 +33,7 @@ namespace osu.Game.Tests.Visual.Components
},
box2 = new IdleTrackingBox(2000)
{
Name = "TopRight",
RelativeSizeAxes = Axes.Both,
Colour = Color4.Green,
Anchor = Anchor.TopRight,
@ -39,6 +41,7 @@ namespace osu.Game.Tests.Visual.Components
},
box3 = new IdleTrackingBox(3000)
{
Name = "BottomLeft",
RelativeSizeAxes = Axes.Both,
Colour = Color4.Blue,
Anchor = Anchor.BottomLeft,
@ -46,6 +49,7 @@ namespace osu.Game.Tests.Visual.Components
},
box4 = new IdleTrackingBox(4000)
{
Name = "BottomRight",
RelativeSizeAxes = Axes.Both,
Colour = Color4.Orange,
Anchor = Anchor.BottomRight,
@ -57,51 +61,80 @@ namespace osu.Game.Tests.Visual.Components
[Test]
public void TestNudge()
{
AddStep("move mouse to top left", () => InputManager.MoveMouseTo(box1.ScreenSpaceDrawQuad.Centre));
AddStep("move to top left", () => InputManager.MoveMouseTo(box1));
AddUntilStep("Wait for all idle", () => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle);
waitForAllIdle();
AddStep("nudge mouse", () => InputManager.MoveMouseTo(box1.ScreenSpaceDrawQuad.Centre + new Vector2(1)));
AddAssert("check not idle", () => !box1.IsIdle);
AddAssert("check idle", () => box2.IsIdle);
AddAssert("check idle", () => box3.IsIdle);
AddAssert("check idle", () => box4.IsIdle);
checkIdleStatus(box1, false);
checkIdleStatus(box2, true);
checkIdleStatus(box3, true);
checkIdleStatus(box4, true);
}
[Test]
public void TestMovement()
{
AddStep("move mouse", () => InputManager.MoveMouseTo(box2.ScreenSpaceDrawQuad.Centre));
AddStep("move to top right", () => InputManager.MoveMouseTo(box2));
AddAssert("check not idle", () => box1.IsIdle);
AddAssert("check not idle", () => !box2.IsIdle);
AddAssert("check idle", () => box3.IsIdle);
AddAssert("check idle", () => box4.IsIdle);
checkIdleStatus(box1, true);
checkIdleStatus(box2, false);
checkIdleStatus(box3, true);
checkIdleStatus(box4, true);
AddStep("move mouse", () => InputManager.MoveMouseTo(box3.ScreenSpaceDrawQuad.Centre));
AddStep("move mouse", () => InputManager.MoveMouseTo(box4.ScreenSpaceDrawQuad.Centre));
AddStep("move to bottom left", () => InputManager.MoveMouseTo(box3));
AddStep("move to bottom right", () => InputManager.MoveMouseTo(box4));
AddAssert("check not idle", () => box1.IsIdle);
AddAssert("check not idle", () => !box2.IsIdle);
AddAssert("check idle", () => !box3.IsIdle);
AddAssert("check idle", () => !box4.IsIdle);
checkIdleStatus(box1, true);
checkIdleStatus(box2, false);
checkIdleStatus(box3, false);
checkIdleStatus(box4, false);
AddUntilStep("Wait for all idle", () => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle);
waitForAllIdle();
}
[Test]
public void TestTimings()
{
AddStep("move mouse", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.Centre));
AddStep("move to centre", () => InputManager.MoveMouseTo(Content));
checkIdleStatus(box1, false);
checkIdleStatus(box2, false);
checkIdleStatus(box3, false);
checkIdleStatus(box4, false);
AddAssert("check not idle", () => !box1.IsIdle && !box2.IsIdle && !box3.IsIdle && !box4.IsIdle);
AddUntilStep("Wait for idle", () => box1.IsIdle);
AddAssert("check not idle", () => !box2.IsIdle && !box3.IsIdle && !box4.IsIdle);
checkIdleStatus(box1, true);
checkIdleStatus(box2, false);
checkIdleStatus(box3, false);
checkIdleStatus(box4, false);
AddUntilStep("Wait for idle", () => box2.IsIdle);
AddAssert("check not idle", () => !box3.IsIdle && !box4.IsIdle);
checkIdleStatus(box1, true);
checkIdleStatus(box2, true);
checkIdleStatus(box3, false);
checkIdleStatus(box4, false);
AddUntilStep("Wait for idle", () => box3.IsIdle);
checkIdleStatus(box1, true);
checkIdleStatus(box2, true);
checkIdleStatus(box3, true);
checkIdleStatus(box4, false);
waitForAllIdle();
}
private void checkIdleStatus(IdleTrackingBox box, bool expectedIdle)
{
AddAssert($"{box.Name} is {(expectedIdle ? "idle" : "active")}", () => box.IsIdle == expectedIdle);
}
private void waitForAllIdle()
{
AddUntilStep("Wait for all idle", () => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle);
}

View File

@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual.Gameplay
protected override void LoadComplete()
{
base.LoadComplete();
ScoreProcessor.FailConditions += _ => true;
ScoreProcessor.FailConditions += (_, __) => true;
}
}
}

View File

@ -15,11 +15,10 @@ using osu.Game.Overlays.Chat.Tabs;
namespace osu.Game.Tests.Visual.Online
{
[Description("Testing chat api and overlay")]
public class TestSceneChatDisplay : OsuTestScene
public class TestSceneChatOverlay : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(ChatOverlay),
typeof(ChatLine),
typeof(DrawableChannel),
typeof(ChannelSelectorTabItem),

View File

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -39,8 +40,7 @@ namespace osu.Game.Tests.Visual.Online
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
RelativeSizeAxes = Axes.Both,
Width = 0.8f,
Children = new Drawable[]
{
@ -173,7 +173,9 @@ namespace osu.Game.Tests.Visual.Online
s.Statistics.Add(HitResult.Miss, RNG.Next(2000));
}
scoresContainer.Scores = scores;
AddStep("Load all scores", () => scoresContainer.Scores = scores);
AddStep("Load null scores", () => scoresContainer.Scores = null);
AddStep("Load only one score", () => scoresContainer.Scores = new[] { scores.First() });
}
[BackgroundDependencyLoader]

View File

@ -39,13 +39,27 @@ namespace osu.Game.Tests.Visual.Online
header = new ProfileHeader();
Add(header);
AddStep("Show offline dummy", () => header.User.Value = TestSceneUserProfileOverlay.TEST_USER);
AddStep("Show test dummy", () => header.User.Value = TestSceneUserProfileOverlay.TEST_USER);
AddStep("Show null dummy", () => header.User.Value = new User
{
Username = "Null"
});
AddStep("Show online dummy", () => header.User.Value = new User
{
Username = "IAmOnline",
LastVisit = DateTimeOffset.Now,
IsOnline = true,
});
AddStep("Show offline dummy", () => header.User.Value = new User
{
Username = "IAmOffline",
LastVisit = DateTimeOffset.Now,
IsOnline = false,
});
addOnlineStep("Show ppy", new User
{
Username = @"peppy",

View File

@ -1,17 +1,30 @@
// 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 NUnit.Framework;
using osu.Game.Overlays;
using osu.Game.Overlays.KeyBinding;
namespace osu.Game.Tests.Visual.Settings
{
[TestFixture]
public class TestSceneKeyConfiguration : OsuTestScene
public class TestSceneKeyBindingPanel : OsuTestScene
{
private readonly KeyBindingPanel panel;
public TestSceneKeyConfiguration()
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(KeyBindingRow),
typeof(GlobalKeyBindingsSection),
typeof(KeyBindingRow),
typeof(KeyBindingsSubsection),
typeof(RulesetBindingsSection),
typeof(VariantBindingsSubsection),
};
public TestSceneKeyBindingPanel()
{
Child = panel = new KeyBindingPanel();
}

View File

@ -214,37 +214,6 @@ namespace osu.Game.Tests.Visual.SongSelect
AddAssert("start not requested", () => !startRequested);
}
[Test]
public void TestAddNewBeatmapWhileSelectingRandom()
{
const int test_count = 10;
int beatmapChangedCount = 0;
int debounceCount = 0;
createSongSelect();
AddStep("Setup counters", () =>
{
beatmapChangedCount = 0;
debounceCount = 0;
songSelect.Carousel.SelectionChanged += _ => beatmapChangedCount++;
});
AddRepeatStep($"Create beatmaps {test_count} times", () =>
{
importForRuleset(0);
Scheduler.AddDelayed(() =>
{
// Wait for debounce
songSelect.Carousel.SelectNextRandom();
++debounceCount;
}, 400);
}, test_count);
AddUntilStep("Debounce limit reached", () => debounceCount == test_count);
// The selected beatmap should have changed an additional 2 times since both initially loading songselect and the first import also triggers selectionChanged
AddAssert($"Beatmap changed {test_count + 2} times", () => beatmapChangedCount == test_count + 2);
}
[Test]
public void TestHideSetSelectsCorrectBeatmap()
{

View File

@ -1,85 +0,0 @@
// 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.Collections.Generic;
using System.ComponentModel;
using osu.Framework.Allocation;
using osu.Game.Screens.Tournament;
using osu.Game.Screens.Tournament.Teams;
namespace osu.Game.Tests.Visual.Tournament
{
[Description("for tournament use")]
public class TestSceneDrawings : ScreenTestScene
{
[BackgroundDependencyLoader]
private void load()
{
LoadScreen(new Drawings
{
TeamList = new TestTeamList(),
});
}
private class TestTeamList : ITeamList
{
public IEnumerable<DrawingsTeam> Teams { get; } = new[]
{
new DrawingsTeam
{
FlagName = "GB",
FullName = "United Kingdom",
Acronym = "UK"
},
new DrawingsTeam
{
FlagName = "FR",
FullName = "France",
Acronym = "FRA"
},
new DrawingsTeam
{
FlagName = "CN",
FullName = "China",
Acronym = "CHN"
},
new DrawingsTeam
{
FlagName = "AU",
FullName = "Australia",
Acronym = "AUS"
},
new DrawingsTeam
{
FlagName = "JP",
FullName = "Japan",
Acronym = "JPN"
},
new DrawingsTeam
{
FlagName = "RO",
FullName = "Romania",
Acronym = "ROM"
},
new DrawingsTeam
{
FlagName = "IT",
FullName = "Italy",
Acronym = "PIZZA"
},
new DrawingsTeam
{
FlagName = "VE",
FullName = "Venezuela",
Acronym = "VNZ"
},
new DrawingsTeam
{
FlagName = "US",
FullName = "United States of America",
Acronym = "USA"
},
};
}
}
}

View File

@ -24,11 +24,10 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.UserInterface
{
[Description("mod select and icon display")]
public class TestSceneMods : OsuTestScene
public class TestSceneModSelectOverlay : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(ModSelectOverlay),
typeof(ModDisplay),
typeof(ModSection),
typeof(ModIcon),
@ -77,7 +76,7 @@ namespace osu.Game.Tests.Visual.UserInterface
public void TestOsuMods()
{
var ruleset = rulesets.AvailableRulesets.First(r => r.ID == 0);
AddStep("change ruleset", () => { Ruleset.Value = ruleset; });
changeRuleset(ruleset);
var instance = ruleset.CreateInstance();
@ -109,7 +108,7 @@ namespace osu.Game.Tests.Visual.UserInterface
public void TestManiaMods()
{
var ruleset = rulesets.AvailableRulesets.First(r => r.ID == 3);
AddStep("change ruleset", () => { Ruleset.Value = ruleset; });
changeRuleset(ruleset);
testRankedText(ruleset.CreateInstance().GetModsFor(ModType.Conversion).First(m => m is ManiaModRandom));
}
@ -120,7 +119,7 @@ namespace osu.Game.Tests.Visual.UserInterface
var rulesetOsu = rulesets.AvailableRulesets.First(r => r.ID == 0);
var rulesetMania = rulesets.AvailableRulesets.First(r => r.ID == 3);
AddStep("change ruleset to null", () => { Ruleset.Value = null; });
changeRuleset(null);
var instance = rulesetOsu.CreateInstance();
var easierMods = instance.GetModsFor(ModType.DifficultyReduction);
@ -128,15 +127,15 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("set mods externally", () => { modDisplay.Current.Value = new[] { noFailMod }; });
AddStep("change ruleset to osu", () => { Ruleset.Value = rulesetOsu; });
changeRuleset(rulesetOsu);
AddAssert("ensure mods still selected", () => modDisplay.Current.Value.Single(m => m is OsuModNoFail) != null);
AddStep("change ruleset to mania", () => { Ruleset.Value = rulesetMania; });
changeRuleset(rulesetMania);
AddAssert("ensure mods not selected", () => !modDisplay.Current.Value.Any(m => m is OsuModNoFail));
AddStep("change ruleset to osu", () => { Ruleset.Value = rulesetOsu; });
changeRuleset(rulesetOsu);
AddAssert("ensure mods not selected", () => !modDisplay.Current.Value.Any());
}
@ -217,14 +216,11 @@ namespace osu.Game.Tests.Visual.UserInterface
private void testRankedText(Mod mod)
{
AddWaitStep("wait for fade", 1);
AddAssert("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0);
AddUntilStep("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0);
selectNext(mod);
AddWaitStep("wait for fade", 1);
AddAssert("check for unranked", () => modSelect.UnrankedLabel.Alpha != 0);
AddUntilStep("check for unranked", () => modSelect.UnrankedLabel.Alpha != 0);
selectPrevious(mod);
AddWaitStep("wait for fade", 1);
AddAssert("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0);
AddUntilStep("check for ranked", () => modSelect.UnrankedLabel.Alpha == 0);
}
private void selectNext(Mod mod) => AddStep($"left click {mod.Name}", () => modSelect.GetModButton(mod)?.SelectNext(1));
@ -240,6 +236,15 @@ namespace osu.Game.Tests.Visual.UserInterface
});
}
private void changeRuleset(RulesetInfo ruleset)
{
AddStep($"change ruleset to {ruleset}", () => { Ruleset.Value = ruleset; });
waitForLoad();
}
private void waitForLoad() =>
AddUntilStep("wait for icons to load", () => modSelect.AllLoaded);
private void checkNotSelected(Mod mod)
{
AddAssert($"check {mod.Name} is not selected", () =>
@ -255,6 +260,8 @@ namespace osu.Game.Tests.Visual.UserInterface
{
public new Bindable<IReadOnlyList<Mod>> SelectedMods => base.SelectedMods;
public bool AllLoaded => ModSectionsContainer.Children.All(c => c.ModIconsLoaded);
public ModButton GetModButton(Mod mod)
{
var section = ModSectionsContainer.Children.Single(s => s.ModType == mod.Type);

View File

@ -18,9 +18,6 @@ namespace osu.Game.Tests.Visual.UserInterface
[TestFixture]
public class TestSceneNotificationOverlay : OsuTestScene
{
private readonly NotificationOverlay manager;
private readonly List<ProgressNotification> progressingNotifications = new List<ProgressNotification>();
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(NotificationSection),
@ -31,25 +28,33 @@ namespace osu.Game.Tests.Visual.UserInterface
typeof(Notification)
};
public TestSceneNotificationOverlay()
private NotificationOverlay notificationOverlay;
private readonly List<ProgressNotification> progressingNotifications = new List<ProgressNotification>();
private SpriteText displayedCount;
[SetUp]
public void SetUp() => Schedule(() =>
{
progressingNotifications.Clear();
Content.Add(manager = new NotificationOverlay
Content.Children = new Drawable[]
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight
});
notificationOverlay = new NotificationOverlay
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight
},
displayedCount = new OsuSpriteText()
};
SpriteText displayedCount = new OsuSpriteText();
Content.Add(displayedCount);
void setState(Visibility state) => AddStep(state.ToString(), () => manager.State.Value = state);
void checkProgressingCount(int expected) => AddAssert($"progressing count is {expected}", () => progressingNotifications.Count == expected);
manager.UnreadCount.ValueChanged += count => { displayedCount.Text = $"displayed count: {count.NewValue}"; };
notificationOverlay.UnreadCount.ValueChanged += count => { displayedCount.Text = $"displayed count: {count.NewValue}"; };
});
[Test]
public void TestBasicFlow()
{
setState(Visibility.Visible);
AddStep(@"simple #1", sendHelloNotification);
AddStep(@"simple #2", sendAmazingNotification);
@ -61,6 +66,7 @@ namespace osu.Game.Tests.Visual.UserInterface
setState(Visibility.Hidden);
AddRepeatStep(@"add many simple", sendManyNotifications, 3);
AddWaitStep("wait some", 5);
checkProgressingCount(0);
@ -69,18 +75,122 @@ namespace osu.Game.Tests.Visual.UserInterface
checkProgressingCount(1);
AddAssert("Displayed count is 33", () => manager.UnreadCount.Value == 33);
checkDisplayedCount(33);
AddWaitStep("wait some", 10);
checkProgressingCount(0);
setState(Visibility.Visible);
//AddStep(@"barrage", () => sendBarrage());
}
private void sendBarrage(int remaining = 10)
[Test]
public void TestImportantWhileClosed()
{
AddStep(@"simple #1", sendHelloNotification);
AddAssert("Is visible", () => notificationOverlay.State.Value == Visibility.Visible);
checkDisplayedCount(1);
AddStep(@"progress #1", sendUploadProgress);
AddStep(@"progress #2", sendDownloadProgress);
checkProgressingCount(2);
checkDisplayedCount(3);
}
[Test]
public void TestUnimportantWhileClosed()
{
AddStep(@"background #1", sendBackgroundNotification);
AddAssert("Is not visible", () => notificationOverlay.State.Value == Visibility.Hidden);
checkDisplayedCount(1);
AddStep(@"background progress #1", sendBackgroundUploadProgress);
AddWaitStep("wait some", 5);
checkProgressingCount(0);
checkDisplayedCount(2);
AddStep(@"simple #1", sendHelloNotification);
checkDisplayedCount(3);
}
[Test]
public void TestSpam()
{
setState(Visibility.Visible);
AddRepeatStep("send barrage", sendBarrage, 10);
}
protected override void Update()
{
base.Update();
progressingNotifications.RemoveAll(n => n.State == ProgressNotificationState.Completed);
if (progressingNotifications.Count(n => n.State == ProgressNotificationState.Active) < 3)
{
var p = progressingNotifications.Find(n => n.State == ProgressNotificationState.Queued);
if (p != null)
p.State = ProgressNotificationState.Active;
}
foreach (var n in progressingNotifications.FindAll(n => n.State == ProgressNotificationState.Active))
{
if (n.Progress < 1)
n.Progress += (float)(Time.Elapsed / 400) * RNG.NextSingle();
else
n.State = ProgressNotificationState.Completed;
}
}
private void checkDisplayedCount(int expected) =>
AddAssert($"Displayed count is {expected}", () => notificationOverlay.UnreadCount.Value == expected);
private void sendDownloadProgress()
{
var n = new ProgressNotification
{
Text = @"Downloading Haitai...",
CompletionText = "Downloaded Haitai!",
};
notificationOverlay.Post(n);
progressingNotifications.Add(n);
}
private void sendUploadProgress()
{
var n = new ProgressNotification
{
Text = @"Uploading to BSS...",
CompletionText = "Uploaded to BSS!",
};
notificationOverlay.Post(n);
progressingNotifications.Add(n);
}
private void sendBackgroundUploadProgress()
{
var n = new BackgroundProgressNotification
{
Text = @"Uploading to BSS...",
CompletionText = "Uploaded to BSS!",
};
notificationOverlay.Post(n);
progressingNotifications.Add(n);
}
private void setState(Visibility state) => AddStep(state.ToString(), () => notificationOverlay.State.Value = state);
private void checkProgressingCount(int expected) => AddAssert($"progressing count is {expected}", () => progressingNotifications.Count == expected);
private void sendBarrage()
{
switch (RNG.Next(0, 4))
{
@ -100,69 +210,37 @@ namespace osu.Game.Tests.Visual.UserInterface
sendDownloadProgress();
break;
}
if (remaining > 0)
Scheduler.AddDelayed(() => sendBarrage(remaining - 1), 80);
}
protected override void Update()
{
base.Update();
progressingNotifications.RemoveAll(n => n.State == ProgressNotificationState.Completed);
if (progressingNotifications.Count(n => n.State == ProgressNotificationState.Active) < 3)
{
var p = progressingNotifications.Find(n => n.State == ProgressNotificationState.Queued);
if (p != null)
p.State = ProgressNotificationState.Active;
}
foreach (var n in progressingNotifications.FindAll(n => n.State == ProgressNotificationState.Active))
{
if (n.Progress < 1)
n.Progress += (float)(Time.Elapsed / 400) * RNG.NextSingle();
else
n.State = ProgressNotificationState.Completed;
}
}
private void sendDownloadProgress()
{
var n = new ProgressNotification
{
Text = @"Downloading Haitai...",
CompletionText = "Downloaded Haitai!",
};
manager.Post(n);
progressingNotifications.Add(n);
}
private void sendUploadProgress()
{
var n = new ProgressNotification
{
Text = @"Uploading to BSS...",
CompletionText = "Uploaded to BSS!",
};
manager.Post(n);
progressingNotifications.Add(n);
}
private void sendAmazingNotification()
{
manager.Post(new SimpleNotification { Text = @"You are amazing" });
notificationOverlay.Post(new SimpleNotification { Text = @"You are amazing" });
}
private void sendHelloNotification()
{
manager.Post(new SimpleNotification { Text = @"Welcome to osu!. Enjoy your stay!" });
notificationOverlay.Post(new SimpleNotification { Text = @"Welcome to osu!. Enjoy your stay!" });
}
private void sendBackgroundNotification()
{
notificationOverlay.Post(new BackgroundNotification { Text = @"Welcome to osu!. Enjoy your stay!" });
}
private void sendManyNotifications()
{
for (int i = 0; i < 10; i++)
manager.Post(new SimpleNotification { Text = @"Spam incoming!!" });
notificationOverlay.Post(new SimpleNotification { Text = @"Spam incoming!!" });
}
private class BackgroundNotification : SimpleNotification
{
public override bool IsImportant => false;
}
private class BackgroundProgressNotification : ProgressNotification
{
public override bool IsImportant => false;
}
}
}