1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-05 10:23:20 +08:00

Merge branch 'ppy:master' into taiko-mod-simplified-rhythm

This commit is contained in:
Hivie 2024-11-22 10:09:58 +01:00 committed by GitHub
commit dea5d8329d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
219 changed files with 3508 additions and 2409 deletions

View File

@ -114,7 +114,7 @@ jobs:
dotnet-version: "8.0.x"
- name: Install .NET workloads
run: dotnet workload install maui-android
run: dotnet workload install android
- name: Compile
run: dotnet build -c Debug osu.Android.slnf

View File

@ -10,7 +10,7 @@
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Framework.Android" Version="2024.1115.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2024.1118.0" />
</ItemGroup>
<PropertyGroup>
<!-- Fody does not handle Android build well, and warns when unchanged.

View File

@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Mods
},
Autoplay = true,
PassCondition = () => Player.ScoreProcessor.Combo.Value == 2,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -59,7 +59,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Mods
},
Autoplay = true,
PassCondition = () => true,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Mods
},
Autoplay = true,
PassCondition = () => true,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{

View File

@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Mods
Mod = new CatchModRelax(),
Autoplay = false,
PassCondition = passCondition,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{

View File

@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Catch.Tests
{
CreateModTest(new ModTestData
{
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{

View File

@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Catch.Edit
{
public partial class CatchDistanceSnapProvider : ComposerDistanceSnapProvider
{
protected override double ReadCurrentDistanceSnap(HitObject before, HitObject after)
public override double ReadCurrentDistanceSnap(HitObject before, HitObject after)
{
// osu!catch's distance snap implementation is limited, in that a custom spacing cannot be specified.
// Therefore this functionality is not currently used.

View File

@ -70,6 +70,8 @@ namespace osu.Game.Rulesets.Catch.Edit
}));
}
protected override Drawable CreateHitObjectInspector() => new CatchHitObjectInspector(DistanceSnapProvider);
protected override IEnumerable<TernaryButton> CreateTernaryButtons()
=> base.CreateTernaryButtons()
.Concat(DistanceSnapProvider.CreateTernaryButtons());

View File

@ -0,0 +1,41 @@
// 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.Linq;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Objects;
using osu.Game.Screens.Edit.Compose.Components;
namespace osu.Game.Rulesets.Catch.Edit
{
public partial class CatchHitObjectInspector(CatchDistanceSnapProvider snapProvider) : HitObjectInspector
{
protected override void AddInspectorValues(HitObject[] objects)
{
base.AddInspectorValues(objects);
if (objects.Length > 0)
{
HitObject firstSelectedHitObject = objects.MinBy(ho => ho.StartTime)!;
HitObject lastSelectedHitObject = objects.MaxBy(ho => ho.GetEndTime())!;
HitObject? precedingObject = EditorBeatmap.HitObjects.LastOrDefault(ho => ho.GetEndTime() < firstSelectedHitObject.StartTime);
HitObject? nextObject = EditorBeatmap.HitObjects.FirstOrDefault(ho => ho.StartTime > lastSelectedHitObject.GetEndTime());
if (precedingObject != null && precedingObject is not BananaShower)
{
double previousSnap = snapProvider.ReadCurrentDistanceSnap(precedingObject, firstSelectedHitObject);
AddHeader("To previous");
AddValue($"{previousSnap:#,0.##}x");
}
if (nextObject != null && nextObject is not BananaShower)
{
double nextSnap = snapProvider.ReadCurrentDistanceSnap(lastSelectedHitObject, nextObject);
AddHeader("To next");
AddValue($"{nextSnap:#,0.##}x");
}
}
}
}
}

View File

@ -0,0 +1,39 @@
// 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 NUnit.Framework;
using osu.Game.Rulesets.Mania.Scoring;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
public class ManiaScoreProcessorTest
{
[TestCase(ScoreRank.X, 1, HitResult.Perfect)]
[TestCase(ScoreRank.X, 0.99, HitResult.Great)]
[TestCase(ScoreRank.D, 0.1, HitResult.Great)]
[TestCase(ScoreRank.X, 0.99, HitResult.Perfect, HitResult.Great)]
[TestCase(ScoreRank.X, 0.99, HitResult.Great, HitResult.Great)]
[TestCase(ScoreRank.S, 0.99, HitResult.Perfect, HitResult.Good)]
[TestCase(ScoreRank.S, 0.99, HitResult.Perfect, HitResult.Ok)]
[TestCase(ScoreRank.S, 0.99, HitResult.Perfect, HitResult.Meh)]
[TestCase(ScoreRank.S, 0.99, HitResult.Perfect, HitResult.Miss)]
[TestCase(ScoreRank.S, 0.99, HitResult.Great, HitResult.Good)]
[TestCase(ScoreRank.S, 0.99, HitResult.Great, HitResult.Ok)]
[TestCase(ScoreRank.S, 0.99, HitResult.Great, HitResult.Meh)]
[TestCase(ScoreRank.S, 0.99, HitResult.Great, HitResult.Miss)]
public void TestRanks(ScoreRank expected, double accuracy, params HitResult[] results)
{
var scoreProcessor = new ManiaScoreProcessor();
Dictionary<HitResult, int> resultsDict = new Dictionary<HitResult, int>();
foreach (var result in results)
resultsDict[result] = resultsDict.GetValueOrDefault(result) + 1;
Assert.That(scoreProcessor.RankFromScore(accuracy, resultsDict), Is.EqualTo(expected));
}
}
}

View File

@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
CreateModTest(new ModTestData
{
Autoplay = true,
Beatmap = new ManiaBeatmap(new StageDefinition(1))
CreateBeatmap = () => new ManiaBeatmap(new StageDefinition(1))
{
HitObjects = new List<ManiaHitObject>
{

View File

@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
&& Precision.AlmostEquals(Player.ScoreProcessor.Accuracy.Value, 0.9836, 0.01)
&& Player.ScoreProcessor.TotalScore.Value == 946_049,
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
BeatmapInfo = { Ruleset = new ManiaRuleset().RulesetInfo },
Difficulty = { OverallDifficulty = 10 },
@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
&& Player.ScoreProcessor.Accuracy.Value == 1
&& Player.ScoreProcessor.TotalScore.Value == (long)(1_000_000 * doubleTime.ScoreMultiplier),
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
BeatmapInfo = { Ruleset = new ManiaRuleset().RulesetInfo },
Difficulty = { OverallDifficulty = 10 },

View File

@ -74,7 +74,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
CreateModTest(new ModTestData
{
Mod = new ManiaModHidden(),
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = Enumerable.Range(1, 100).Select(i => (HitObject)new Note { StartTime = 1000 + 200 * i }).ToList(),
Breaks = { new BreakPeriod(2000, 28000) }

View File

@ -74,7 +74,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
CreateModTest(new ModTestData
{
Mod = new ManiaModHidden(),
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = Enumerable.Range(1, 100).Select(i => (HitObject)new Note { StartTime = 1000 + 200 * i }).ToList(),
Breaks = { new BreakPeriod(2000, 28000) }

View File

@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
Mod = new ManiaModPerfect(),
PassCondition = () => ((ModFailConditionTestPlayer)Player).CheckFailed(false),
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -59,7 +59,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
Mod = new ManiaModPerfect(),
PassCondition = () => ((ModFailConditionTestPlayer)Player).CheckFailed(true) && Player.Results.Count == 2,
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{

View File

@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
Mod = new ManiaModSuddenDeath(),
PassCondition = () => ((ModFailConditionTestPlayer)Player).CheckFailed(false),
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods
Mod = new ManiaModSuddenDeath(),
PassCondition = () => ((ModFailConditionTestPlayer)Player).CheckFailed(true) && Player.Results.Count == 2,
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{

View File

@ -0,0 +1,45 @@
// 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 osu.Framework.Graphics;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Mania.Edit
{
public partial class EditorColumn : Column
{
public EditorColumn(int index, bool isSpecial)
: base(index, isSpecial)
{
}
protected override void OnNewDrawableHitObject(DrawableHitObject drawableHitObject)
{
base.OnNewDrawableHitObject(drawableHitObject);
drawableHitObject.ApplyCustomUpdateState += (dho, state) =>
{
switch (dho)
{
// hold note heads are exempt from what follows due to the "freezing" mechanic
// which already ensures they'll never fade away on their own.
case DrawableHoldNoteHead:
break;
// mania features instantaneous hitobject fade-outs.
// this means that without manual intervention stopping the clock at the precise time of hitting the object
// means the object will fade out.
// this is anti-user in editor contexts, as the user is expecting to continue the see the note on the receptor line.
// therefore, apply a crude workaround to prevent it from going away.
default:
{
if (state == ArmedState.Hit)
dho.FadeTo(1).Delay(1).FadeOut().Expire();
break;
}
}
};
}
}
}

View File

@ -0,0 +1,18 @@
// 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 osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.UI;
namespace osu.Game.Rulesets.Mania.Edit
{
public partial class EditorStage : Stage
{
public EditorStage(int firstColumnIndex, StageDefinition definition, ref ManiaAction columnStartAction)
: base(firstColumnIndex, definition, ref columnStartAction)
{
}
protected override Column CreateColumn(int index, bool isSpecial) => new EditorColumn(index, isSpecial);
}
}

View File

@ -13,5 +13,8 @@ namespace osu.Game.Rulesets.Mania.Edit
: base(stages)
{
}
protected override Stage CreateStage(int firstColumnIndex, StageDefinition stageDefinition, ref ManiaAction columnAction)
=> new EditorStage(firstColumnIndex, stageDefinition, ref columnAction);
}
}

View File

@ -9,6 +9,7 @@ using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
namespace osu.Game.Rulesets.Mania.Scoring
{
@ -58,6 +59,24 @@ namespace osu.Game.Rulesets.Mania.Scoring
return GetBaseScoreForResult(result);
}
public override ScoreRank RankFromScore(double accuracy, IReadOnlyDictionary<HitResult, int> results)
{
ScoreRank rank = base.RankFromScore(accuracy, results);
if (rank != ScoreRank.S)
return rank;
// SS is expected as long as all hitobjects have been hit with either a GREAT or PERFECT result.
bool anyImperfect =
results.GetValueOrDefault(HitResult.Good) > 0
|| results.GetValueOrDefault(HitResult.Ok) > 0
|| results.GetValueOrDefault(HitResult.Meh) > 0
|| results.GetValueOrDefault(HitResult.Miss) > 0;
return anyImperfect ? rank : ScoreRank.X;
}
private class JudgementOrderComparer : IComparer<HitObject>
{
public static readonly JudgementOrderComparer DEFAULT = new JudgementOrderComparer();

View File

@ -7,6 +7,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Primitives;
using osu.Game.Rulesets.Mania.Beatmaps;
@ -71,7 +72,7 @@ namespace osu.Game.Rulesets.Mania.UI
for (int i = 0; i < stageDefinitions.Count; i++)
{
var newStage = new Stage(firstColumnIndex, stageDefinitions[i], ref columnAction);
var newStage = CreateStage(firstColumnIndex, stageDefinitions[i], ref columnAction);
playfieldGrid.Content[0][i] = newStage;
@ -82,6 +83,9 @@ namespace osu.Game.Rulesets.Mania.UI
}
}
[Pure]
protected virtual Stage CreateStage(int firstColumnIndex, StageDefinition stageDefinition, ref ManiaAction columnAction) => new Stage(firstColumnIndex, stageDefinition, ref columnAction);
public override void Add(HitObject hitObject) => getStageByColumn(((ManiaHitObject)hitObject).Column).Add(hitObject);
public override bool Remove(HitObject hitObject) => getStageByColumn(((ManiaHitObject)hitObject).Column).Remove(hitObject);

View File

@ -3,6 +3,7 @@
using System;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
@ -134,12 +135,14 @@ namespace osu.Game.Rulesets.Mania.UI
{
bool isSpecial = definition.IsSpecialColumn(i);
var column = new Column(firstColumnIndex + i, isSpecial)
var action = columnStartAction;
columnStartAction++;
var column = CreateColumn(firstColumnIndex + i, isSpecial).With(c =>
{
RelativeSizeAxes = Axes.Both,
Width = 1,
Action = { Value = columnStartAction++ }
};
c.RelativeSizeAxes = Axes.Both;
c.Width = 1;
c.Action.Value = action;
});
topLevelContainer.Add(column.TopLevelContainer.CreateProxy());
columnBackgrounds.Add(column.BackgroundContainer.CreateProxy());
@ -154,6 +157,9 @@ namespace osu.Game.Rulesets.Mania.UI
RegisterPool<BarLine, DrawableBarLine>(50, 200);
}
[Pure]
protected virtual Column CreateColumn(int index, bool isSpecial) => new Column(index, isSpecial);
[BackgroundDependencyLoader]
private void load(ISkinSource skin)
{

View File

@ -17,4 +17,8 @@
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
</ItemGroup>
<ItemGroup Label="Package References">
<PackageReference Include="DeepEqual" Version="2.0.0" />
<PackageReference Include="Moq" Version="4.17.2" />
</ItemGroup>
</Project>

View File

@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
Mod = new OsuModAlternate(),
PassCondition = () => Player.ScoreProcessor.Combo.Value == 4,
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
Mod = new OsuModAlternate(),
PassCondition = () => Player.ScoreProcessor.Combo.Value == 0 && Player.ScoreProcessor.HighestCombo.Value == 1,
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -101,7 +101,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
Mod = new OsuModAlternate(),
PassCondition = () => Player.ScoreProcessor.Combo.Value == 1,
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -131,7 +131,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
Mod = new OsuModAlternate(),
PassCondition = () => Player.ScoreProcessor.Combo.Value == 0 && Player.ScoreProcessor.HighestCombo.Value == 2,
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
Breaks =
{

View File

@ -60,7 +60,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
CreateModTest(new ModTestData
{
Autoplay = true,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
{
Autoplay = true,
Mod = mod,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects =
{

View File

@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
public void TestNoAdjustment() => CreateModTest(new ModTestData
{
Mod = new OsuModDifficultyAdjust(),
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
BeatmapInfo = new BeatmapInfo
{

View File

@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
Player.GameplayClockContainer.CurrentTime < 1000 && Player.ChildrenOfType<ModFlashlight<OsuHitObject>.Flashlight>().Single().FlashlightDim > 0;
return Player.GameplayState.HasPassed && !sliderDimmedBeforeStartTime;
},
Beatmap = new OsuBeatmap
CreateBeatmap = () => new OsuBeatmap
{
HitObjects = new List<OsuHitObject>
{
@ -114,7 +114,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
Player.GameplayClockContainer.CurrentTime >= 1000 && Player.ChildrenOfType<ModFlashlight<OsuHitObject>.Flashlight>().Single().FlashlightDim > 0;
return Player.GameplayState.HasPassed && sliderDimmed;
},
Beatmap = new OsuBeatmap
CreateBeatmap = () => new OsuBeatmap
{
HitObjects = new List<OsuHitObject>
{
@ -153,7 +153,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
Player.GameplayClockContainer.CurrentTime >= 1000 && Player.ChildrenOfType<ModFlashlight<OsuHitObject>.Flashlight>().Single().FlashlightDim > 0;
return Player.GameplayState.HasPassed && sliderDimmed;
},
Beatmap = new OsuBeatmap
CreateBeatmap = () => new OsuBeatmap
{
HitObjects = new List<OsuHitObject>
{

View File

@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
{
Mod = new TestOsuModHidden(),
Autoplay = true,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -63,7 +63,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
{
Mod = new TestOsuModHidden(),
Autoplay = true,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -98,7 +98,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
{
Mod = new TestOsuModHidden(),
Autoplay = true,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -122,7 +122,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
{
Mod = new OsuModHidden { OnlyFadeApproachCircles = { Value = true } },
Autoplay = true,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{

View File

@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
public void TestCorrectReflections([Values] OsuModMirror.MirrorType type, [Values] bool withStrictTracking) => CreateModTest(new ModTestData
{
Autoplay = true,
Beatmap = new OsuBeatmap
CreateBeatmap = () => new OsuBeatmap
{
HitObjects =
{

View File

@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
},
Autoplay = true,
PassCondition = () => true,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
},
Autoplay = true,
PassCondition = () => true,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -113,7 +113,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
},
Autoplay = true,
PassCondition = () => true,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{

View File

@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
Mod = new OsuModPerfect(),
PassCondition = () => ((ModFailConditionTestPlayer)Player).CheckFailed(true),
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{

View File

@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
{
AngleSharpness = { Value = angleSharpness }
},
Beatmap = jumpBeatmap,
CreateBeatmap = jumpBeatmap,
Autoplay = true,
PassCondition = () => true
});
@ -50,15 +50,15 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
{
AngleSharpness = { Value = angleSharpness }
},
Beatmap = streamBeatmap,
CreateBeatmap = streamBeatmap,
Autoplay = true,
PassCondition = () => true
});
private OsuBeatmap jumpBeatmap =>
private OsuBeatmap jumpBeatmap() =>
createHitCircleBeatmap(new[] { 100, 200, 300, 400 }, 8, 300, 2 * 300);
private OsuBeatmap streamBeatmap =>
private OsuBeatmap streamBeatmap() =>
createHitCircleBeatmap(new[] { 10, 20, 30, 40, 50, 60, 70, 80 }, 16, 150, 4 * 150);
private OsuBeatmap createHitCircleBeatmap(IEnumerable<int> spacings, int objectsPerSpacing, int interval, int beatLength)

View File

@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
Mod = new OsuModSingleTap(),
PassCondition = () => Player.ScoreProcessor.Combo.Value == 2,
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -62,7 +62,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
Mod = new OsuModSingleTap(),
PassCondition = () => Player.ScoreProcessor.Combo.Value == 0 && Player.ScoreProcessor.HighestCombo.Value == 1,
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -100,7 +100,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
Mod = new OsuModSingleTap(),
PassCondition = () => Player.ScoreProcessor.Combo.Value == 1,
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -130,7 +130,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
Mod = new OsuModSingleTap(),
PassCondition = () => Player.ScoreProcessor.Combo.Value == 0 && Player.ScoreProcessor.HighestCombo.Value == 2,
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
Breaks =
{

View File

@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
{
Mod = new OsuModSpunOut(),
Autoplay = false,
Beatmap = singleSpinnerBeatmap,
CreateBeatmap = singleSpinnerBeatmap,
PassCondition = () =>
{
// Bind to the first spinner's results for further tracking.
@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
{
Mods = mods,
Autoplay = false,
Beatmap = singleSpinnerBeatmap,
CreateBeatmap = singleSpinnerBeatmap,
PassCondition = () =>
{
var counter = Player.ChildrenOfType<SpinnerSpmCalculator>().SingleOrDefault();
@ -101,7 +101,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
{
Mod = new OsuModSpunOut(),
Autoplay = false,
Beatmap = singleSpinnerBeatmap,
CreateBeatmap = singleSpinnerBeatmap,
PassCondition = () =>
{
// Bind to the first spinner's results for further tracking.
@ -130,7 +130,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
});
}
private Beatmap singleSpinnerBeatmap => new Beatmap
private Beatmap singleSpinnerBeatmap() => new Beatmap
{
HitObjects = new List<HitObject>
{

View File

@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
{
Mod = new OsuModStrictTracking(),
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{

View File

@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
Mod = new OsuModSuddenDeath(),
PassCondition = () => ((ModFailConditionTestPlayer)Player).CheckFailed(false),
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
Mod = new OsuModSuddenDeath(),
PassCondition = () => ((ModFailConditionTestPlayer)Player).CheckFailed(true),
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{

View File

@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.Tests
{
Autoplay = false,
Mod = new TestAutoMod(),
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = { new HitCircle { Position = new Vector2(256, 192) } }
},
@ -47,18 +47,16 @@ namespace osu.Game.Rulesets.Osu.Tests
[Test]
public void TestMissViaNotHitting()
{
var beatmap = new Beatmap
{
HitObjects = { new HitCircle { Position = new Vector2(256, 192) } }
};
var hitWindows = new OsuHitWindows();
hitWindows.SetDifficulty(beatmap.Difficulty.OverallDifficulty);
hitWindows.SetDifficulty(IBeatmapDifficultyInfo.DEFAULT_DIFFICULTY);
CreateModTest(new ModTestData
{
Autoplay = false,
Beatmap = beatmap,
CreateBeatmap = () => new Beatmap
{
HitObjects = { new HitCircle { Position = new Vector2(256, 192) } }
},
PassCondition = () => Player.Results.Count > 0 && Player.Results[0].TimeOffset >= hitWindows.WindowFor(HitResult.Meh) && !Player.Results[0].IsHit
});
}

View File

@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Edit
{
public partial class OsuDistanceSnapProvider : ComposerDistanceSnapProvider
{
protected override double ReadCurrentDistanceSnap(HitObject before, HitObject after)
public override double ReadCurrentDistanceSnap(HitObject before, HitObject after)
{
float expectedDistance = DurationToDistance(before, after.StartTime - before.GetEndTime());
float actualDistance = Vector2.Distance(((OsuHitObject)before).EndPosition, ((OsuHitObject)after).Position);

View File

@ -13,7 +13,8 @@
</Compile>
</ItemGroup>
<ItemGroup Label="Project References">
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
<ProjectReference Include="..\osu.Game.Tests\osu.Game.Tests.csproj" />
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
</ItemGroup>
</Project>

View File

@ -31,40 +31,42 @@ namespace osu.Game.Rulesets.Taiko.Tests.Mods
{
const double hit_time = 1;
var beatmap = new Beatmap<TaikoHitObject>
{
HitObjects = new List<TaikoHitObject>
{
new Hit
{
Type = HitType.Rim,
StartTime = hit_time,
},
new Hit
{
Type = HitType.Centre,
StartTime = hit_time * 2,
},
},
BeatmapInfo =
{
Difficulty = new BeatmapDifficulty
{
SliderTickRate = 4,
OverallDifficulty = 0,
},
Ruleset = new TaikoRuleset().RulesetInfo
},
};
beatmap.ControlPointInfo.Add(0, new EffectControlPoint { ScrollSpeed = 0.1f });
CreateModTest(new ModTestData
{
Mod = new TaikoModHidden(),
Autoplay = true,
PassCondition = checkAllMaxResultJudgements(2),
Beatmap = beatmap,
CreateBeatmap = () =>
{
var beatmap = new Beatmap<TaikoHitObject>
{
HitObjects = new List<TaikoHitObject>
{
new Hit
{
Type = HitType.Rim,
StartTime = hit_time,
},
new Hit
{
Type = HitType.Centre,
StartTime = hit_time * 2,
},
},
BeatmapInfo =
{
Difficulty = new BeatmapDifficulty
{
SliderTickRate = 4,
OverallDifficulty = 0,
},
Ruleset = new TaikoRuleset().RulesetInfo
},
};
beatmap.ControlPointInfo.Add(0, new EffectControlPoint { ScrollSpeed = 0.1f });
return beatmap;
},
});
}
}

View File

@ -15,7 +15,26 @@ namespace osu.Game.Rulesets.Taiko.Tests.Mods
[Test]
public void TestRelax()
{
var beatmap = new TaikoBeatmap
var beatmapForReplay = createBeatmap();
foreach (var ho in beatmapForReplay.HitObjects)
ho.ApplyDefaults(beatmapForReplay.ControlPointInfo, beatmapForReplay.Difficulty);
var replay = new TaikoAutoGenerator(beatmapForReplay).Generate();
foreach (var frame in replay.Frames.OfType<TaikoReplayFrame>().Where(r => r.Actions.Any()))
frame.Actions = [TaikoAction.LeftCentre];
CreateModTest(new ModTestData
{
Mod = new TaikoModRelax(),
CreateBeatmap = createBeatmap,
ReplayFrames = replay.Frames,
Autoplay = false,
PassCondition = () => Player.ScoreProcessor.HasCompleted.Value && Player.ScoreProcessor.Accuracy.Value == 1,
});
TaikoBeatmap createBeatmap() => new TaikoBeatmap
{
HitObjects =
{
@ -25,22 +44,6 @@ namespace osu.Game.Rulesets.Taiko.Tests.Mods
new Swell { StartTime = 1250, Duration = 500 },
}
};
foreach (var ho in beatmap.HitObjects)
ho.ApplyDefaults(beatmap.ControlPointInfo, beatmap.Difficulty);
var replay = new TaikoAutoGenerator(beatmap).Generate();
foreach (var frame in replay.Frames.OfType<TaikoReplayFrame>().Where(r => r.Actions.Any()))
frame.Actions = [TaikoAction.LeftCentre];
CreateModTest(new ModTestData
{
Mod = new TaikoModRelax(),
Beatmap = beatmap,
ReplayFrames = replay.Frames,
Autoplay = false,
PassCondition = () => Player.ScoreProcessor.HasCompleted.Value && Player.ScoreProcessor.Accuracy.Value == 1,
});
}
}
}

View File

@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Mods
{
Mod = new TaikoModSingleTap(),
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Mods
{
Mod = new TaikoModSingleTap(),
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -110,7 +110,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Mods
{
Mod = new TaikoModSingleTap(),
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -136,7 +136,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Mods
{
Mod = new TaikoModSingleTap(),
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = new List<HitObject>
{
@ -175,7 +175,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Mods
{
Mod = new TaikoModSingleTap(),
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
Breaks =
{

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.IO;
using System.Text;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
@ -9,6 +10,7 @@ using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.IO.Archives;
using osu.Game.Tests.Resources;
using osu.Game.Tests.Visual;
using MemoryStream = System.IO.MemoryStream;
@ -48,6 +50,47 @@ namespace osu.Game.Tests.Beatmaps.IO
AddAssert("hit object is snapped", () => beatmap.Beatmap.HitObjects[0].StartTime, () => Is.EqualTo(28519).Within(0.001));
}
[Test]
public void TestExportStability()
{
IWorkingBeatmap beatmap = null!;
MemoryStream firstExport = null!;
MemoryStream secondExport = null!;
// Ensure importer encoding is correct
AddStep("import beatmap", () => beatmap = importBeatmapFromArchives(@"legacy-export-stability-test.olz"));
AddStep("export once", () =>
{
firstExport = new MemoryStream();
new LegacyBeatmapExporter(LocalStorage)
.ExportToStream((BeatmapSetInfo)beatmap.BeatmapInfo.BeatmapSet!, firstExport, null);
});
AddStep("import beatmap again", () => beatmap = importBeatmapFromStream(firstExport));
AddStep("export again", () =>
{
secondExport = new MemoryStream();
new LegacyBeatmapExporter(LocalStorage)
.ExportToStream((BeatmapSetInfo)beatmap.BeatmapInfo.BeatmapSet!, secondExport, null);
});
const string osu_filename = @"legacy export - stability test (spaceman_atlas) [].osu";
AddAssert("exports are identical",
() => getStringContentsOf(osu_filename, firstExport.GetBuffer()),
() => Is.EqualTo(getStringContentsOf(osu_filename, secondExport.GetBuffer())));
string getStringContentsOf(string filename, byte[] archiveBytes)
{
using var memoryStream = new MemoryStream(archiveBytes);
using var archiveReader = new ZipArchiveReader(memoryStream);
byte[] fileContent = archiveReader.GetStream(filename).ReadAllBytesToArray();
return Encoding.UTF8.GetString(fileContent);
}
}
private IWorkingBeatmap importBeatmapFromStream(Stream stream)
{
var imported = beatmaps.Import(new ImportTask(stream, "filename.osz")).GetResultSafely();

View File

@ -148,6 +148,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
[TestCase("tags too", false)]
[TestCase("version", false)]
[TestCase("an auteur", true)]
[TestCase("unit", false)]
public void TestCriteriaMatchingTerms(string terms, bool filtered)
{
var exampleBeatmapInfo = getExampleBeatmap();
@ -175,6 +176,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
[TestCase("\"Artist\"!", true)]
[TestCase("\"The Artist\"!", false)]
[TestCase("\"the artist\"!", false)]
[TestCase("\"unit tests\"!", false)]
[TestCase("\"\\\"", true)] // nasty case, covers properly escaping user input in underlying regex.
public void TestCriteriaMatchingExactTerms(string terms, bool filtered)
{

View File

@ -501,6 +501,18 @@ namespace osu.Game.Tests.NonVisual.Filtering
Assert.That(visibleBeatmaps, Is.EqualTo(expectedBeatmapIndexes));
}
[Test]
public void TestApplySourceQueries()
{
const string query = "find me songs with source=\"unit tests\" please";
var filterCriteria = new FilterCriteria();
FilterQueryParser.ApplyQueries(filterCriteria, query);
Assert.AreEqual("find me songs with please", filterCriteria.SearchText.Trim());
Assert.AreEqual(5, filterCriteria.SearchTerms.Length);
Assert.AreEqual("unit tests", filterCriteria.Source.SearchTerm);
Assert.That(filterCriteria.Source.MatchMode, Is.EqualTo(FilterCriteria.MatchMode.IsolatedPhrase));
}
private class CustomFilterCriteria : IRulesetFilterCriteria
{
public string? CustomValue { get; set; }

View File

@ -73,9 +73,9 @@ namespace osu.Game.Tests.NonVisual.Multiplayer
AddStep("create room initially in gameplay", () =>
{
var newRoom = new Room();
newRoom.CopyFrom(SelectedRoom.Value);
newRoom.CopyFrom(SelectedRoom.Value!);
newRoom.RoomID.Value = null;
newRoom.RoomID = null;
MultiplayerClient.RoomSetupAction = room =>
{
room.State = MultiplayerRoomState.Playing;

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System;
using System.Collections.Generic;
using NUnit.Framework;
@ -21,12 +19,12 @@ namespace osu.Game.Tests.OnlinePlay
[HeadlessTest]
public partial class TestSceneCatchUpSyncManager : OsuTestScene
{
private GameplayClockContainer master;
private SpectatorSyncManager syncManager;
private GameplayClockContainer master = null!;
private SpectatorSyncManager syncManager = null!;
private Dictionary<SpectatorPlayerClock, int> clocksById;
private SpectatorPlayerClock player1;
private SpectatorPlayerClock player2;
private Dictionary<SpectatorPlayerClock, int> clocksById = null!;
private SpectatorPlayerClock player1 = null!;
private SpectatorPlayerClock player2 = null!;
[SetUp]
public void Setup()

View File

@ -12,6 +12,7 @@ using osu.Framework.Platform;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Collections;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
using osu.Game.Overlays.Dialog;
using osu.Game.Rulesets;
@ -265,7 +266,6 @@ namespace osu.Game.Tests.Visual.Collections
}
[Test]
[Solo]
public void TestCollectionRenamedExternal()
{
BeatmapCollection first = null!;
@ -338,10 +338,44 @@ namespace osu.Game.Tests.Visual.Collections
AddUntilStep("collection has new name", () => first.Name == "First");
}
[Test]
public void TestSearch()
{
BeatmapCollection first = null!;
AddStep("add two collections", () =>
{
Realm.Write(r =>
{
r.Add(new[]
{
first = new BeatmapCollection(name: "1"),
new BeatmapCollection(name: "2"),
});
});
});
assertCollectionName(0, "1");
assertCollectionName(1, "2");
AddStep("search for 1", () => dialog.ChildrenOfType<SearchTextBox>().Single().Current.Value = "1");
assertCollectionCount(1);
AddStep("change first collection name", () => Realm.Write(_ => first.Name = "First"));
assertCollectionCount(0);
AddStep("search for first", () => dialog.ChildrenOfType<SearchTextBox>().Single().Current.Value = "firs");
assertCollectionCount(1);
}
private void assertCollectionCount(int count)
=> AddUntilStep($"{count} collections shown", () => dialog.ChildrenOfType<DrawableCollectionListItem>().Count() == count + 1); // +1 for placeholder
=> AddUntilStep($"{count} collections shown", () => dialog.ChildrenOfType<DrawableCollectionListItem>().Count(i => i.IsPresent) == count + 1); // +1 for placeholder
private void assertCollectionName(int index, string name)
=> AddUntilStep($"item {index + 1} has correct name", () => dialog.ChildrenOfType<DrawableCollectionList>().Single().OrderedItems.ElementAt(index).ChildrenOfType<TextBox>().First().Text == name);
=> AddUntilStep($"item {index + 1} has correct name",
() => dialog.ChildrenOfType<DrawableCollectionList>().Single().OrderedItems.ElementAt(index).ChildrenOfType<TextBox>().First().Text == name);
}
}

View File

@ -39,18 +39,18 @@ namespace osu.Game.Tests.Visual.DailyChallenge
{
var room = new Room
{
RoomID = { Value = 1234 },
Name = { Value = "Daily Challenge: June 4, 2024" },
RoomID = 1234,
Name = "Daily Challenge: June 4, 2024",
Playlist =
{
[
new PlaylistItem(TestResources.CreateTestBeatmapSetInfo().Beatmaps.First())
{
RequiredMods = [new APIMod(new OsuModTraceable())],
AllowedMods = [new APIMod(new OsuModDoubleTime())]
}
},
EndDate = { Value = DateTimeOffset.Now.AddHours(12) },
Category = { Value = RoomCategory.DailyChallenge }
],
EndDate = DateTimeOffset.Now.AddHours(12),
Category = RoomCategory.DailyChallenge
};
AddStep("add room", () => API.Perform(new CreateRoomRequest(room)));
@ -62,18 +62,18 @@ namespace osu.Game.Tests.Visual.DailyChallenge
{
var room = new Room
{
RoomID = { Value = 1234 },
Name = { Value = "Daily Challenge: June 4, 2024" },
RoomID = 1234,
Name = "Daily Challenge: June 4, 2024",
Playlist =
{
[
new PlaylistItem(TestResources.CreateTestBeatmapSetInfo().Beatmaps.First())
{
RequiredMods = [new APIMod(new OsuModTraceable())],
AllowedMods = [new APIMod(new OsuModDoubleTime())]
}
},
EndDate = { Value = DateTimeOffset.Now.AddHours(12) },
Category = { Value = RoomCategory.DailyChallenge }
],
EndDate = DateTimeOffset.Now.AddHours(12),
Category = RoomCategory.DailyChallenge
};
AddStep("add room", () => API.Perform(new CreateRoomRequest(room)));
@ -91,18 +91,18 @@ namespace osu.Game.Tests.Visual.DailyChallenge
{
var room = new Room
{
RoomID = { Value = 1234 },
Name = { Value = "Daily Challenge: June 4, 2024" },
RoomID = 1234,
Name = "Daily Challenge: June 4, 2024",
Playlist =
{
[
new PlaylistItem(TestResources.CreateTestBeatmapSetInfo().Beatmaps.First())
{
RequiredMods = [new APIMod(new OsuModTraceable())],
AllowedMods = [new APIMod(new OsuModDoubleTime())]
}
},
EndDate = { Value = DateTimeOffset.Now.AddHours(12) },
Category = { Value = RoomCategory.DailyChallenge }
],
EndDate = DateTimeOffset.Now.AddHours(12),
Category = RoomCategory.DailyChallenge
};
AddStep("add room", () => API.Perform(new CreateRoomRequest(room)));

View File

@ -26,11 +26,6 @@ namespace osu.Game.Tests.Visual.DailyChallenge
private readonly Bindable<Room> room = new Bindable<Room>(new Room());
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) => new CachedModelDependencyContainer<Room>(base.CreateChildDependencies(parent))
{
Model = { BindTarget = room }
};
[Test]
public void TestBasicAppearance()
{
@ -98,7 +93,7 @@ namespace osu.Game.Tests.Visual.DailyChallenge
Origin = Anchor.Centre,
Children = new Drawable[]
{
new DailyChallengeTimeRemainingRing(),
new DailyChallengeTimeRemainingRing(room.Value),
breakdown = new DailyChallengeScoreBreakdown(),
}
}
@ -125,8 +120,8 @@ namespace osu.Game.Tests.Visual.DailyChallenge
AddSliderStep("update time remaining", 0f, 1f, 0f, progress =>
{
var startedTimeAgo = TimeSpan.FromHours(24) * progress;
room.Value.StartDate.Value = DateTimeOffset.Now - startedTimeAgo;
room.Value.EndDate.Value = room.Value.StartDate.Value.Value.AddDays(1);
room.Value.StartDate = DateTimeOffset.Now - startedTimeAgo;
room.Value.EndDate = room.Value.StartDate.Value.AddDays(1);
});
AddStep("add normal score", () =>
{

View File

@ -68,19 +68,19 @@ namespace osu.Game.Tests.Visual.DailyChallenge
{
API.Perform(new CreateRoomRequest(room = new Room
{
RoomID = { Value = roomId },
Name = { Value = "Daily Challenge: June 4, 2024" },
RoomID = roomId,
Name = "Daily Challenge: June 4, 2024",
Playlist =
{
[
new PlaylistItem(CreateAPIBeatmap(new OsuRuleset().RulesetInfo))
{
RequiredMods = [new APIMod(new OsuModTraceable())],
AllowedMods = [new APIMod(new OsuModDoubleTime())]
}
},
StartDate = { Value = DateTimeOffset.Now },
EndDate = { Value = DateTimeOffset.Now.AddHours(24) },
Category = { Value = RoomCategory.DailyChallenge }
],
StartDate = DateTimeOffset.Now,
EndDate = DateTimeOffset.Now.AddHours(24),
Category = RoomCategory.DailyChallenge
}));
});
AddStep("signal client", () => metadataClient.DailyChallengeUpdated(new DailyChallengeInfo { RoomID = roomId }));

View File

@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual.DailyChallenge
return false;
};
});
AddStep("create leaderboard", () => Child = leaderboard = new DailyChallengeLeaderboard(new Room { RoomID = { Value = 1 } }, new PlaylistItem(Beatmap.Value.BeatmapInfo))
AddStep("create leaderboard", () => Child = leaderboard = new DailyChallengeLeaderboard(new Room { RoomID = 1 }, new PlaylistItem(Beatmap.Value.BeatmapInfo))
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
@ -86,7 +86,7 @@ namespace osu.Game.Tests.Visual.DailyChallenge
return false;
};
});
AddStep("create leaderboard", () => Child = leaderboard = new DailyChallengeLeaderboard(new Room { RoomID = { Value = 1 } }, new PlaylistItem(Beatmap.Value.BeatmapInfo))
AddStep("create leaderboard", () => Child = leaderboard = new DailyChallengeLeaderboard(new Room { RoomID = 1 }, new PlaylistItem(Beatmap.Value.BeatmapInfo))
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,

View File

@ -18,11 +18,6 @@ namespace osu.Game.Tests.Visual.DailyChallenge
{
private readonly Bindable<Room> room = new Bindable<Room>(new Room());
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) => new CachedModelDependencyContainer<Room>(base.CreateChildDependencies(parent))
{
Model = { BindTarget = room }
};
[Cached]
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Plum);
@ -38,7 +33,7 @@ namespace osu.Game.Tests.Visual.DailyChallenge
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background4,
},
ring = new DailyChallengeTimeRemainingRing
ring = new DailyChallengeTimeRemainingRing(room.Value)
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
@ -59,29 +54,29 @@ namespace osu.Game.Tests.Visual.DailyChallenge
AddStep("just started", () =>
{
room.Value.StartDate.Value = DateTimeOffset.Now.AddMinutes(-1);
room.Value.EndDate.Value = room.Value.StartDate.Value.Value.AddDays(1);
room.Value.StartDate = DateTimeOffset.Now.AddMinutes(-1);
room.Value.EndDate = room.Value.StartDate.Value.AddDays(1);
});
AddStep("midway through", () =>
{
room.Value.StartDate.Value = DateTimeOffset.Now.AddHours(-12);
room.Value.EndDate.Value = room.Value.StartDate.Value.Value.AddDays(1);
room.Value.StartDate = DateTimeOffset.Now.AddHours(-12);
room.Value.EndDate = room.Value.StartDate.Value.AddDays(1);
});
AddStep("nearing end", () =>
{
room.Value.StartDate.Value = DateTimeOffset.Now.AddDays(-1).AddMinutes(8);
room.Value.EndDate.Value = room.Value.StartDate.Value.Value.AddDays(1);
room.Value.StartDate = DateTimeOffset.Now.AddDays(-1).AddMinutes(8);
room.Value.EndDate = room.Value.StartDate.Value.AddDays(1);
});
AddStep("already ended", () =>
{
room.Value.StartDate.Value = DateTimeOffset.Now.AddDays(-2);
room.Value.EndDate.Value = room.Value.StartDate.Value.Value.AddDays(1);
room.Value.StartDate = DateTimeOffset.Now.AddDays(-2);
room.Value.EndDate = room.Value.StartDate.Value.AddDays(1);
});
AddSliderStep("manual progress", 0f, 1f, 0f, progress =>
{
var startedTimeAgo = TimeSpan.FromHours(24) * progress;
room.Value.StartDate.Value = DateTimeOffset.Now - startedTimeAgo;
room.Value.EndDate.Value = room.Value.StartDate.Value.Value.AddDays(1);
room.Value.StartDate = DateTimeOffset.Now - startedTimeAgo;
room.Value.EndDate = room.Value.StartDate.Value.AddDays(1);
});
}
}

View File

@ -18,6 +18,7 @@ using osu.Framework.Testing;
using osu.Framework.Utils;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets.Mods;
@ -207,7 +208,25 @@ namespace osu.Game.Tests.Visual.Gameplay
}
[Test]
public void TestBlockLoadViaFocus()
public void TestLoadNotBlockedViaArbitraryFocus()
{
AddStep("load dummy beatmap", () => resetPlayer(false));
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
AddUntilStep("click settings slider", () =>
{
InputManager.MoveMouseTo(loader.ChildrenOfType<OsuSliderBar<float>>().First());
InputManager.Click(MouseButton.Left);
return InputManager.FocusedDrawable is OsuSliderBar<float>;
});
AddUntilStep("wait for load ready", () => player?.LoadState == LoadState.Ready);
AddUntilStep("loads", () => !loader.IsCurrentScreen());
}
[Test]
public void TestBlockLoadViaOverlayFocus()
{
AddStep("load dummy beatmap", () => resetPlayer(false));
AddUntilStep("wait for current", () => loader.IsCurrentScreen());

View File

@ -42,14 +42,14 @@ namespace osu.Game.Tests.Visual.Menus
beatmap.OnlineID = 1001;
getRoomRequest.TriggerSuccess(new Room
{
RoomID = { Value = 1234 },
Name = { Value = "Aug 8, 2024" },
RoomID = 1234,
Name = "Aug 8, 2024",
Playlist =
{
[
new PlaylistItem(beatmap)
},
StartDate = { Value = DateTimeOffset.Now.AddMinutes(-30) },
EndDate = { Value = DateTimeOffset.Now.AddSeconds(60) }
],
StartDate = DateTimeOffset.Now.AddMinutes(-30),
EndDate = DateTimeOffset.Now.AddSeconds(60)
});
return true;

View File

@ -35,7 +35,7 @@ namespace osu.Game.Tests.Visual.Mods
MinimumAccuracy = { Value = 0.6 }
},
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = Enumerable.Range(0, 5).Select(i => new HitCircle
{
@ -56,7 +56,7 @@ namespace osu.Game.Tests.Visual.Mods
AccuracyJudgeMode = { Value = ModAccuracyChallenge.AccuracyMode.Standard }
},
Autoplay = false,
Beatmap = new Beatmap
CreateBeatmap = () => new Beatmap
{
HitObjects = Enumerable.Range(0, 5).Select(i => new HitCircle
{

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
@ -31,7 +29,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
protected readonly BindableList<MultiplayerRoomUser> MultiplayerUsers = new BindableList<MultiplayerRoomUser>();
protected MultiplayerGameplayLeaderboard Leaderboard { get; private set; }
protected MultiplayerGameplayLeaderboard? Leaderboard { get; private set; }
protected virtual MultiplayerRoomUser CreateUser(int userId) => new MultiplayerRoomUser(userId);
@ -40,7 +38,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
private readonly BindableList<int> multiplayerUserIds = new BindableList<int>();
private readonly BindableDictionary<int, SpectatorState> watchedUserStates = new BindableDictionary<int, SpectatorState>();
private OsuConfigManager config;
private OsuConfigManager config = null!;
private readonly Mock<SpectatorClient> spectatorClient = new Mock<SpectatorClient>();
private readonly Mock<MultiplayerClient> multiplayerClient = new Mock<MultiplayerClient>();
@ -133,7 +131,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
LoadComponentAsync(Leaderboard = CreateLeaderboard(), Add);
});
AddUntilStep("wait for load", () => Leaderboard.IsLoaded);
AddUntilStep("wait for load", () => Leaderboard!.IsLoaded);
AddStep("check watch requests were sent", () =>
{
@ -146,7 +144,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
public void TestScoreUpdates()
{
AddRepeatStep("update state", UpdateUserStatesRandomly, 100);
AddToggleStep("switch compact mode", expanded => Leaderboard.Expanded.Value = expanded);
AddToggleStep("switch compact mode", expanded => Leaderboard!.Expanded.Value = expanded);
}
[Test]

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
@ -30,16 +28,16 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
protected abstract QueueMode Mode { get; }
protected BeatmapInfo InitialBeatmap { get; private set; }
protected BeatmapInfo OtherBeatmap { get; private set; }
protected BeatmapInfo InitialBeatmap { get; private set; } = null!;
protected BeatmapInfo OtherBeatmap { get; private set; } = null!;
protected IScreen CurrentScreen => multiplayerComponents.CurrentScreen;
protected IScreen CurrentSubScreen => multiplayerComponents.MultiplayerScreen.CurrentSubScreen;
private BeatmapManager beatmaps;
private BeatmapSetInfo importedSet;
private BeatmapManager beatmaps = null!;
private BeatmapSetInfo importedSet = null!;
private TestMultiplayerComponents multiplayerComponents;
private TestMultiplayerComponents multiplayerComponents = null!;
protected TestMultiplayerClient MultiplayerClient => multiplayerComponents.MultiplayerClient;
@ -75,15 +73,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("wait for lounge", () => multiplayerComponents.ChildrenOfType<LoungeSubScreen>().SingleOrDefault()?.IsLoaded == true);
AddStep("open room", () => multiplayerComponents.ChildrenOfType<LoungeSubScreen>().Single().Open(new Room
{
Name = { Value = "Test Room" },
QueueMode = { Value = Mode },
Name = "Test Room",
QueueMode = Mode,
Playlist =
{
[
new PlaylistItem(InitialBeatmap)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
}
]
}));
AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true);
@ -98,7 +96,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestCreatedWithCorrectMode()
{
AddUntilStep("room created with correct mode", () => MultiplayerClient.ClientAPIRoom?.QueueMode.Value == Mode);
AddUntilStep("room created with correct mode", () => MultiplayerClient.ClientAPIRoom?.QueueMode == Mode);
}
protected void RunGameplay()

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System;
using NUnit.Framework;
using osu.Framework.Graphics;
@ -12,7 +10,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneCreateMultiplayerMatchButton : MultiplayerTestScene
{
private CreateMultiplayerMatchButton button;
private CreateMultiplayerMatchButton button = null!;
public override void SetUpSteps()
{
@ -29,7 +27,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestButtonEnableStateChanges()
{
IDisposable joiningRoomOperation = null;
IDisposable joiningRoomOperation = null!;
assertButtonEnableState(true);

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System;
using System.Linq;
using System.Threading;
@ -10,6 +8,7 @@ using System.Threading.Tasks;
using Moq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Testing;
@ -25,14 +24,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
private readonly Room room = new Room
{
HasPassword = { Value = true }
Password = "*"
};
[Cached]
protected readonly OverlayColourProvider ColourProvider = new OverlayColourProvider(OverlayColourScheme.Pink);
private DrawableLoungeRoom drawableRoom;
private SearchTextBox searchTextBox;
private DrawableLoungeRoom drawableRoom = null!;
private SearchTextBox searchTextBox = null!;
private readonly ManualResetEventSlim allowResponseCallback = new ManualResetEventSlim();
@ -78,6 +77,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
SelectedRoom = new Bindable<Room?>()
}
}
};
@ -87,7 +87,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestFocusViaKeyboardCommit()
{
DrawableLoungeRoom.PasswordEntryPopover popover = null;
DrawableLoungeRoom.PasswordEntryPopover? popover = null;
AddAssert("search textbox has focus", () => checkFocus(searchTextBox));
AddStep("click room twice", () =>
@ -103,11 +103,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("enter password", () => popover.ChildrenOfType<OsuPasswordTextBox>().Single().Text = "password");
AddStep("commit via enter", () => InputManager.Key(Key.Enter));
AddAssert("popover has focus", () => checkFocus(popover));
AddAssert("popover has focus", () => checkFocus(popover!));
AddStep("attempt another enter", () => InputManager.Key(Key.Enter));
AddAssert("popover still has focus", () => checkFocus(popover));
AddAssert("popover still has focus", () => checkFocus(popover!));
AddStep("unblock response", () => allowResponseCallback.Set());
@ -122,7 +122,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestFocusViaMouseCommit()
{
DrawableLoungeRoom.PasswordEntryPopover popover = null;
DrawableLoungeRoom.PasswordEntryPopover? popover = null;
AddAssert("search textbox has focus", () => checkFocus(searchTextBox));
AddStep("click room twice", () =>
@ -144,11 +144,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
InputManager.Click(MouseButton.Left);
});
AddAssert("popover has focus", () => checkFocus(popover));
AddAssert("popover has focus", () => checkFocus(popover!));
AddStep("attempt another click", () => InputManager.Click(MouseButton.Left));
AddAssert("popover still has focus", () => checkFocus(popover));
AddAssert("popover still has focus", () => checkFocus(popover!));
AddStep("unblock response", () => allowResponseCallback.Set());

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System;
using System.Linq;
using NUnit.Framework;
@ -32,15 +30,40 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Cached]
protected readonly OverlayColourProvider ColourProvider = new OverlayColourProvider(OverlayColourScheme.Plum);
private readonly Bindable<Room> selectedRoom = new Bindable<Room>();
private readonly Bindable<Room?> selectedRoom = new Bindable<Room?>();
[Test]
public void TestMultipleStatuses()
{
FillFlowContainer rooms = null;
FillFlowContainer rooms = null!;
AddStep("create rooms", () =>
{
PlaylistItem item1 = new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo)
{
BeatmapInfo = { StarRating = 2.5 }
}.BeatmapInfo);
PlaylistItem item2 = new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo)
{
BeatmapInfo = { StarRating = 4.5 }
}.BeatmapInfo);
PlaylistItem item3 = new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo)
{
BeatmapInfo =
{
StarRating = 2.5,
Metadata =
{
Artist = "very very very very very very very very very long artist",
ArtistUnicode = "very very very very very very very very very long artist",
Title = "very very very very very very very very very very very long title",
TitleUnicode = "very very very very very very very very very very very long title",
}
}
}.BeatmapInfo);
Child = rooms = new FillFlowContainer
{
Anchor = Anchor.Centre,
@ -52,86 +75,48 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createLoungeRoom(new Room
{
Name = { Value = "Multiplayer room" },
Status = { Value = new RoomStatusOpen() },
EndDate = { Value = DateTimeOffset.Now.AddDays(1) },
Type = { Value = MatchType.HeadToHead },
Playlist =
{
new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo)
{
BeatmapInfo =
{
StarRating = 2.5
}
}.BeatmapInfo)
}
Name = "Multiplayer room",
Status = new RoomStatusOpen(),
EndDate = DateTimeOffset.Now.AddDays(1),
Type = MatchType.HeadToHead,
Playlist = [item1],
CurrentPlaylistItem = item1
}),
createLoungeRoom(new Room
{
Name = { Value = "Private room" },
Status = { Value = new RoomStatusOpenPrivate() },
HasPassword = { Value = true },
EndDate = { Value = DateTimeOffset.Now.AddDays(1) },
Type = { Value = MatchType.HeadToHead },
Playlist =
{
new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo)
{
BeatmapInfo =
{
StarRating = 2.5,
Metadata =
{
Artist = "very very very very very very very very very long artist",
ArtistUnicode = "very very very very very very very very very long artist",
Title = "very very very very very very very very very very very long title",
TitleUnicode = "very very very very very very very very very very very long title",
}
}
}.BeatmapInfo)
}
Name = "Private room",
Status = new RoomStatusOpenPrivate(),
Password = "*",
EndDate = DateTimeOffset.Now.AddDays(1),
Type = MatchType.HeadToHead,
Playlist = [item3],
CurrentPlaylistItem = item3
}),
createLoungeRoom(new Room
{
Name = { Value = "Playlist room with multiple beatmaps" },
Status = { Value = new RoomStatusPlaying() },
EndDate = { Value = DateTimeOffset.Now.AddDays(1) },
Playlist =
{
new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo)
{
BeatmapInfo =
{
StarRating = 2.5
}
}.BeatmapInfo),
new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo)
{
BeatmapInfo =
{
StarRating = 4.5
}
}.BeatmapInfo)
}
Name = "Playlist room with multiple beatmaps",
Status = new RoomStatusPlaying(),
EndDate = DateTimeOffset.Now.AddDays(1),
Playlist = [item1, item2],
CurrentPlaylistItem = item1
}),
createLoungeRoom(new Room
{
Name = { Value = "Finished room" },
Status = { Value = new RoomStatusEnded() },
EndDate = { Value = DateTimeOffset.Now },
Name = "Finished room",
Status = new RoomStatusEnded(),
EndDate = DateTimeOffset.Now,
}),
createLoungeRoom(new Room
{
Name = { Value = "Spotlight room" },
Status = { Value = new RoomStatusOpen() },
Category = { Value = RoomCategory.Spotlight },
Name = "Spotlight room",
Status = new RoomStatusOpen(),
Category = RoomCategory.Spotlight,
}),
createLoungeRoom(new Room
{
Name = { Value = "Featured artist room" },
Status = { Value = new RoomStatusOpen() },
Category = { Value = RoomCategory.FeaturedArtist },
Name = "Featured artist room",
Status = new RoomStatusOpen(),
Category = RoomCategory.FeaturedArtist,
}),
}
};
@ -145,24 +130,24 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestEnableAndDisablePassword()
{
DrawableRoom drawableRoom = null;
Room room = null;
DrawableRoom drawableRoom = null!;
Room room = null!;
AddStep("create room", () => Child = drawableRoom = createLoungeRoom(room = new Room
{
Name = { Value = "Room with password" },
Status = { Value = new RoomStatusOpen() },
Type = { Value = MatchType.HeadToHead },
Name = "Room with password",
Status = new RoomStatusOpen(),
Type = MatchType.HeadToHead,
}));
AddUntilStep("wait for panel load", () => drawableRoom.ChildrenOfType<DrawableRoomParticipantsList>().Any());
AddAssert("password icon hidden", () => Precision.AlmostEquals(0, drawableRoom.ChildrenOfType<DrawableRoom.PasswordProtectedIcon>().Single().Alpha));
AddStep("set password", () => room.Password.Value = "password");
AddStep("set password", () => room.Password = "password");
AddAssert("password icon visible", () => Precision.AlmostEquals(1, drawableRoom.ChildrenOfType<DrawableRoom.PasswordProtectedIcon>().Single().Alpha));
AddStep("unset password", () => room.Password.Value = string.Empty);
AddStep("unset password", () => room.Password = string.Empty);
AddAssert("password icon hidden", () => Precision.AlmostEquals(0, drawableRoom.ChildrenOfType<DrawableRoom.PasswordProtectedIcon>().Single().Alpha));
}
@ -179,43 +164,52 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
new DrawableMatchRoom(new Room
{
Name = { Value = "A host-only room" },
QueueMode = { Value = QueueMode.HostOnly },
Type = { Value = MatchType.HeadToHead }
}),
Name = "A host-only room",
QueueMode = QueueMode.HostOnly,
Type = MatchType.HeadToHead,
})
{
SelectedItem = new Bindable<PlaylistItem?>()
},
new DrawableMatchRoom(new Room
{
Name = { Value = "An all-players, team-versus room" },
QueueMode = { Value = QueueMode.AllPlayers },
Type = { Value = MatchType.TeamVersus }
}),
Name = "An all-players, team-versus room",
QueueMode = QueueMode.AllPlayers,
Type = MatchType.TeamVersus
})
{
SelectedItem = new Bindable<PlaylistItem?>()
},
new DrawableMatchRoom(new Room
{
Name = { Value = "A round-robin room" },
QueueMode = { Value = QueueMode.AllPlayersRoundRobin },
Type = { Value = MatchType.HeadToHead }
}),
Name = "A round-robin room",
QueueMode = QueueMode.AllPlayersRoundRobin,
Type = MatchType.HeadToHead
})
{
SelectedItem = new Bindable<PlaylistItem?>()
},
}
});
}
private DrawableRoom createLoungeRoom(Room room)
{
room.Host.Value ??= new APIUser { Username = "peppy", Id = 2 };
room.Host ??= new APIUser { Username = "peppy", Id = 2 };
if (room.RecentParticipants.Count == 0)
{
room.RecentParticipants.AddRange(Enumerable.Range(0, 20).Select(i => new APIUser
room.RecentParticipants = Enumerable.Range(0, 20).Select(i => new APIUser
{
Id = i,
Username = $"User {i}"
}));
}).ToArray();
}
return new DrawableLoungeRoom(room)
{
MatchingFilter = true,
SelectedRoom = { BindTarget = selectedRoom }
SelectedRoom = selectedRoom
};
}
}

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics;
@ -17,7 +15,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneDrawableRoomParticipantsList : OnlinePlayTestScene
{
private DrawableRoomParticipantsList list;
private DrawableRoomParticipantsList list = null!;
public override void SetUpSteps()
{
@ -27,18 +25,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
SelectedRoom.Value = new Room
{
Name = { Value = "test room" },
Host =
Name = "test room",
Host = new APIUser
{
Value = new APIUser
{
Id = 2,
Username = "peppy",
}
Id = 2,
Username = "peppy",
}
};
Child = list = new DrawableRoomParticipantsList
Child = list = new DrawableRoomParticipantsList(SelectedRoom.Value)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@ -124,7 +119,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddAssert("4 circles displayed", () => list.ChildrenOfType<UpdateableAvatar>().Count() == 4);
AddAssert("46 hidden users", () => list.ChildrenOfType<DrawableRoomParticipantsList.HiddenUserCount>().Single().Count == 46);
AddStep("remove from end", () => removeUserAt(SelectedRoom.Value.RecentParticipants.Count - 1));
AddStep("remove from end", () => removeUserAt(SelectedRoom.Value!.RecentParticipants.Count - 1));
AddAssert("4 circles displayed", () => list.ChildrenOfType<UpdateableAvatar>().Count() == 4);
AddAssert("45 hidden users", () => list.ChildrenOfType<DrawableRoomParticipantsList.HiddenUserCount>().Single().Count == 45);
@ -143,18 +138,18 @@ namespace osu.Game.Tests.Visual.Multiplayer
private void addUser(int id)
{
SelectedRoom.Value.RecentParticipants.Add(new APIUser
SelectedRoom.Value!.RecentParticipants = SelectedRoom.Value!.RecentParticipants.Append(new APIUser
{
Id = id,
Username = $"User {id}"
});
SelectedRoom.Value.ParticipantCount.Value++;
}).ToArray();
SelectedRoom.Value!.ParticipantCount++;
}
private void removeUserAt(int index)
{
SelectedRoom.Value.RecentParticipants.RemoveAt(index);
SelectedRoom.Value.ParticipantCount.Value--;
SelectedRoom.Value!.RecentParticipants = SelectedRoom.Value!.RecentParticipants.Where(u => !u.Equals(SelectedRoom.Value!.RecentParticipants[index])).ToArray();
SelectedRoom.Value!.ParticipantCount--;
}
}
}

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System;
using System.Collections.Generic;
using System.Diagnostics;
@ -39,9 +37,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneDrawableRoomPlaylist : MultiplayerTestScene
{
private TestPlaylist playlist;
private BeatmapManager manager;
private TestPlaylist playlist = null!;
private BeatmapManager manager = null!;
[BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio)
@ -199,14 +196,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestDownloadButtonHiddenWhenBeatmapExists()
{
Live<BeatmapSetInfo> imported = null;
Live<BeatmapSetInfo> imported = null!;
AddStep("import beatmap", () =>
{
var beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo;
Debug.Assert(beatmap.BeatmapSet != null);
imported = manager.Import(beatmap.BeatmapSet);
imported = manager.Import(beatmap.BeatmapSet)!;
});
createPlaylistWithBeatmaps(() => imported.PerformRead(s => s.Beatmaps.Detach()));
@ -378,7 +375,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
}
});
private void createPlaylist(Action<TestPlaylist> setupPlaylist = null)
private void createPlaylist(Action<TestPlaylist>? setupPlaylist = null)
{
AddStep("create playlist", () =>
{

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
@ -26,9 +24,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneFreeModSelectOverlay : MultiplayerTestScene
{
private FreeModSelectOverlay freeModSelectOverlay;
private FooterButtonFreeMods footerButtonFreeMods;
private ScreenFooter footer;
private FreeModSelectOverlay freeModSelectOverlay = null!;
private FooterButtonFreeMods footerButtonFreeMods = null!;
private ScreenFooter footer = null!;
private readonly Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> availableMods = new Bindable<Dictionary<ModType, IReadOnlyList<Mod>>>();
[BackgroundDependencyLoader]
@ -49,8 +47,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddToggleStep("toggle visibility", visible =>
{
if (freeModSelectOverlay != null)
freeModSelectOverlay.State.Value = visible ? Visibility.Visible : Visibility.Hidden;
freeModSelectOverlay.State.Value = visible ? Visibility.Visible : Visibility.Hidden;
});
}

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System.Linq;
using Moq;
using NUnit.Framework;
@ -20,7 +18,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneGameplayChatDisplay : OsuManualInputManagerTestScene
{
private GameplayChatDisplay chatDisplay;
private GameplayChatDisplay chatDisplay = null!;
[Cached(typeof(ILocalUserPlayInfo))]
private ILocalUserPlayInfo localUserInfo;

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System;
using System.Linq;
using NUnit.Framework;
@ -46,7 +44,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
QueueMode = QueueMode.AllPlayers
}).WaitSafely());
AddUntilStep("api room updated", () => MultiplayerClient.ClientAPIRoom?.QueueMode.Value == QueueMode.AllPlayers);
AddUntilStep("api room updated", () => MultiplayerClient.ClientAPIRoom?.QueueMode == QueueMode.AllPlayers);
}
[Test]
@ -70,13 +68,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
RunGameplay();
IBeatmapInfo firstBeatmap = null;
AddStep("get first playlist item beatmap", () => firstBeatmap = MultiplayerClient.ServerAPIRoom?.Playlist[0].Beatmap);
IBeatmapInfo firstBeatmap = null!;
AddStep("get first playlist item beatmap", () => firstBeatmap = MultiplayerClient.ServerAPIRoom!.Playlist[0].Beatmap);
selectNewItem(() => OtherBeatmap);
AddUntilStep("first playlist item hasn't changed", () => MultiplayerClient.ServerAPIRoom?.Playlist[0].Beatmap == firstBeatmap);
AddUntilStep("second playlist item changed", () => MultiplayerClient.ClientAPIRoom?.Playlist[1].Beatmap != firstBeatmap);
AddUntilStep("first playlist item hasn't changed", () => MultiplayerClient.ServerAPIRoom!.Playlist[0].Beatmap == firstBeatmap);
AddUntilStep("second playlist item changed", () => MultiplayerClient.ClientAPIRoom!.Playlist[1].Beatmap != firstBeatmap);
}
[Test]
@ -103,7 +101,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("wait for song select", () => CurrentSubScreen is Screens.Select.SongSelect select && select.BeatmapSetsLoaded);
BeatmapInfo otherBeatmap = null;
BeatmapInfo otherBeatmap = null!;
AddStep("select other beatmap", () => ((Screens.Select.SongSelect)CurrentSubScreen).FinaliseSelection(otherBeatmap = beatmap()));
AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen);

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics;
@ -23,7 +21,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
protected new TestRoomManager RoomManager => (TestRoomManager)base.RoomManager;
private RoomsContainer container;
private RoomsContainer container = null!;
public override void SetUpSteps()
{
@ -55,20 +53,20 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddAssert("has 5 rooms", () => container.Rooms.Count == 5);
AddAssert("all spotlights at top", () => container.Rooms
.SkipWhile(r => r.Room.Category.Value == RoomCategory.Spotlight)
.All(r => r.Room.Category.Value == RoomCategory.Normal));
.SkipWhile(r => r.Room.Category == RoomCategory.Spotlight)
.All(r => r.Room.Category == RoomCategory.Normal));
AddStep("remove first room", () => RoomManager.RemoveRoom(RoomManager.Rooms.First(r => r.RoomID.Value == 0)));
AddStep("remove first room", () => RoomManager.RemoveRoom(RoomManager.Rooms.First(r => r.RoomID == 0)));
AddAssert("has 4 rooms", () => container.Rooms.Count == 4);
AddAssert("first room removed", () => container.Rooms.All(r => r.Room.RoomID.Value != 0));
AddAssert("first room removed", () => container.Rooms.All(r => r.Room.RoomID != 0));
AddStep("select first room", () => container.Rooms.First().TriggerClick());
AddAssert("first spotlight selected", () => checkRoomSelected(RoomManager.Rooms.First(r => r.Category.Value == RoomCategory.Spotlight)));
AddAssert("first spotlight selected", () => checkRoomSelected(RoomManager.Rooms.First(r => r.Category == RoomCategory.Spotlight)));
AddStep("remove last room", () => RoomManager.RemoveRoom(RoomManager.Rooms.MinBy(r => r.RoomID?.Value)));
AddAssert("first spotlight still selected", () => checkRoomSelected(RoomManager.Rooms.First(r => r.Category.Value == RoomCategory.Spotlight)));
AddStep("remove last room", () => RoomManager.RemoveRoom(RoomManager.Rooms.MinBy(r => r.RoomID)!));
AddAssert("first spotlight still selected", () => checkRoomSelected(RoomManager.Rooms.First(r => r.Category == RoomCategory.Spotlight)));
AddStep("remove spotlight room", () => RoomManager.RemoveRoom(RoomManager.Rooms.Single(r => r.Category.Value == RoomCategory.Spotlight)));
AddStep("remove spotlight room", () => RoomManager.RemoveRoom(RoomManager.Rooms.Single(r => r.Category == RoomCategory.Spotlight)));
AddAssert("selection vacated", () => checkRoomSelected(null));
}
@ -157,7 +155,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("add rooms", () => RoomManager.AddRooms(3, new CatchRuleset().RulesetInfo));
// Todo: What even is this case...?
AddStep("set empty filter criteria", () => container.Filter.Value = null);
AddStep("set empty filter criteria", () => container.Filter.Value = new FilterCriteria());
AddUntilStep("5 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 5);
AddStep("filter osu! rooms", () => container.Filter.Value = new FilterCriteria { Ruleset = new OsuRuleset().RulesetInfo });
@ -182,11 +180,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("filter public rooms", () => container.Filter.Value = new FilterCriteria { Permissions = RoomPermissionsFilter.Public });
AddUntilStep("private room hidden", () => container.Rooms.All(r => !r.Room.HasPassword.Value));
AddUntilStep("private room hidden", () => container.Rooms.All(r => !r.Room.HasPassword));
AddStep("filter private rooms", () => container.Filter.Value = new FilterCriteria { Permissions = RoomPermissionsFilter.Private });
AddUntilStep("public room hidden", () => container.Rooms.All(r => r.Room.HasPassword.Value));
AddUntilStep("public room hidden", () => container.Rooms.All(r => r.Room.HasPassword));
}
[Test]
@ -195,9 +193,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("add rooms", () => RoomManager.AddRooms(3, withPassword: true));
}
private bool checkRoomSelected(Room room) => SelectedRoom.Value == room;
private bool checkRoomSelected(Room? room) => SelectedRoom.Value == room;
private Room getRoomInFlow(int index) =>
private Room? getRoomInFlow(int index) =>
(container.ChildrenOfType<FillFlowContainer<DrawableLoungeRoom>>().First().FlowingChildren.ElementAt(index) as DrawableRoom)?.Room;
}
}

View File

@ -1,6 +1,7 @@
// 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.Linq;
using osu.Framework.Graphics;
using osu.Game.Online.API;
using osu.Game.Online.Rooms;
@ -23,7 +24,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
SelectedRoom.Value = new Room();
Child = new MatchBeatmapDetailArea
Child = new MatchBeatmapDetailArea(SelectedRoom.Value)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@ -35,7 +36,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
private void createNewItem()
{
SelectedRoom.Value.Playlist.Add(new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo)
SelectedRoom.Value!.Playlist = SelectedRoom.Value.Playlist.Append(new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo)
{
ID = SelectedRoom.Value.Playlist.Count,
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
@ -45,7 +46,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
new APIMod(new OsuModDoubleTime()),
new APIMod(new OsuModAutoplay())
}
});
}).ToArray();
}
}
}

View File

@ -61,9 +61,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("create leaderboard", () =>
{
SelectedRoom.Value = new Room { RoomID = { Value = 3 } };
SelectedRoom.Value = new Room { RoomID = 3 };
Child = new MatchLeaderboard
Child = new MatchLeaderboard(SelectedRoom.Value)
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,

View File

@ -43,12 +43,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
private OsuButton readyButton => control.ChildrenOfType<OsuButton>().Single();
[Cached(typeof(IBindable<PlaylistItem>))]
private readonly Bindable<PlaylistItem> currentItem = new Bindable<PlaylistItem>();
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) =>
new CachedModelDependencyContainer<Room>(base.CreateChildDependencies(parent)) { Model = { BindTarget = room } };
[BackgroundDependencyLoader]
private void load()
{
@ -107,31 +101,33 @@ namespace osu.Game.Tests.Visual.Multiplayer
[SetUpSteps]
public void SetUpSteps()
{
PlaylistItem item = null!;
AddStep("reset state", () =>
{
multiplayerClient.Invocations.Clear();
beatmapAvailability.Value = BeatmapAvailability.LocallyAvailable();
currentItem.Value = new PlaylistItem(Beatmap.Value.BeatmapInfo)
item = new PlaylistItem(Beatmap.Value.BeatmapInfo)
{
RulesetID = Beatmap.Value.BeatmapInfo.Ruleset.OnlineID
};
room.Value = new Room
{
Playlist = { currentItem.Value },
CurrentPlaylistItem = { BindTarget = currentItem }
Playlist = [item],
CurrentPlaylistItem = item
};
localUser = new MultiplayerRoomUser(API.LocalUser.Value.Id) { User = API.LocalUser.Value };
localUser = new MultiplayerRoomUser(API.LocalUser.Value.Id)
{
User = API.LocalUser.Value
};
multiplayerRoom = new MultiplayerRoom(0)
{
Playlist =
{
TestMultiplayerClient.CreateMultiplayerPlaylistItem(currentItem.Value),
},
Playlist = { TestMultiplayerClient.CreateMultiplayerPlaylistItem(item) },
Users = { localUser },
Host = localUser,
};
@ -144,6 +140,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(250, 50),
SelectedItem = new Bindable<PlaylistItem?>(item)
};
});
}

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
@ -18,8 +16,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneMultiSpectatorLeaderboard : MultiplayerTestScene
{
private Dictionary<int, ManualClock> clocks;
private MultiSpectatorLeaderboard leaderboard;
private Dictionary<int, ManualClock> clocks = null!;
private MultiSpectatorLeaderboard? leaderboard;
[SetUpSteps]
public override void SetUpSteps()
@ -55,13 +53,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
}, Add);
});
AddUntilStep("wait for load", () => leaderboard.IsLoaded);
AddUntilStep("wait for load", () => leaderboard!.IsLoaded);
AddUntilStep("wait for user population", () => leaderboard.ChildrenOfType<GameplayLeaderboardScore>().Count() == 2);
AddStep("add clock sources", () =>
{
foreach ((int userId, var clock) in clocks)
leaderboard.AddClock(userId, clock);
leaderboard!.AddClock(userId, clock);
});
}

View File

@ -455,7 +455,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
applyToBeatmap?.Invoke(Beatmap.Value);
LoadScreen(spectatorScreen = new MultiSpectatorScreen(SelectedRoom.Value, playingUsers.ToArray()));
LoadScreen(spectatorScreen = new MultiSpectatorScreen(SelectedRoom.Value!, playingUsers.ToArray()));
});
AddUntilStep("wait for screen load", () => spectatorScreen.LoadState == LoadState.Loaded && (!waitForPlayerLoad || spectatorScreen.AllPlayersLoaded));

View File

@ -103,14 +103,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Name = "Test Room",
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
}
]
});
AddRepeatStep("random stuff happens", performRandomAction, 30);
@ -238,17 +238,17 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Name = "Test Room",
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
}
]
});
AddUntilStep("Check participant count correct", () => multiplayerClient.ClientAPIRoom?.ParticipantCount.Value == 1);
AddUntilStep("Check participant count correct", () => multiplayerClient.ClientAPIRoom?.ParticipantCount == 1);
AddUntilStep("Check participant list contains user", () => multiplayerClient.ClientAPIRoom?.RecentParticipants.Count(u => u.Id == API.LocalUser.Value.Id) == 1);
}
@ -259,14 +259,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
roomManager.AddServerSideRoom(new Room
{
Name = { Value = "Test Room" },
Name = "Test Room",
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
}
]
}, API.LocalUser.Value);
});
@ -288,14 +288,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
roomManager.AddServerSideRoom(new Room
{
Name = { Value = "Test Room" },
Name = "Test Room",
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
}
]
}, API.LocalUser.Value);
});
@ -308,7 +308,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("wait for room open", () => this.ChildrenOfType<MultiplayerMatchSubScreen>().FirstOrDefault()?.IsLoaded == true);
AddUntilStep("wait for join", () => multiplayerClient.RoomJoined);
AddUntilStep("Check participant count correct", () => multiplayerClient.ClientAPIRoom?.ParticipantCount.Value == 1);
AddUntilStep("Check participant count correct", () => multiplayerClient.ClientAPIRoom?.ParticipantCount == 1);
AddUntilStep("Check participant list contains user", () => multiplayerClient.ClientAPIRoom?.RecentParticipants.Count(u => u.Id == API.LocalUser.Value.Id) == 1);
}
@ -317,18 +317,18 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Password = { Value = "password" },
Name = "Test Room",
Password = "password",
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
}
]
});
AddUntilStep("room has password", () => multiplayerClient.ClientAPIRoom?.Password.Value == "password");
AddUntilStep("room has password", () => multiplayerClient.ClientAPIRoom?.Password == "password");
}
[Test]
@ -338,15 +338,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
roomManager.AddServerSideRoom(new Room
{
Name = { Value = "Test Room" },
Password = { Value = "password" },
Name = "Test Room",
Password = "password",
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
}
]
}, API.LocalUser.Value);
});
@ -370,19 +370,19 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Password = { Value = "password" },
Name = "Test Room",
Password = "password",
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
}
]
});
AddStep("change password", () => multiplayerClient.ChangeSettings(password: "password2"));
AddUntilStep("local password changed", () => multiplayerClient.ClientAPIRoom?.Password.Value == "password2");
AddUntilStep("local password changed", () => multiplayerClient.ClientAPIRoom?.Password == "password2");
}
[Test]
@ -401,14 +401,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Name = "Test Room",
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
}
]
});
pressReadyButton();
@ -430,8 +430,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
};
return new Room
{
Name = { Value = "Test Room" },
Playlist = { item }
Name = "Test Room",
Playlist = [item]
};
});
@ -471,8 +471,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
};
return new Room
{
Name = { Value = "Test Room" },
Playlist = { item }
Name = "Test Room",
Playlist = [item]
};
});
@ -512,8 +512,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
};
return new Room
{
Name = { Value = "Test Room" },
Playlist = { item }
Name = "Test Room",
Playlist = [item]
};
});
@ -548,14 +548,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Name = "Test Room",
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
}
]
});
AddStep("join other user (ready, host)", () =>
@ -581,14 +581,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Name = "Test Room",
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
}
]
});
AddStep("delete beatmap", () => beatmaps.Delete(importedSet));
@ -620,14 +620,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Name = "Test Room",
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
}
]
});
AddStep("disconnect", () => multiplayerClient.Disconnect());
@ -639,15 +639,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Name = "Test Room",
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
AllowedMods = new[] { new APIMod(new OsuModHidden()) }
}
}
]
});
AddStep("open mod overlay", () => this.ChildrenOfType<UserModSelectButton>().Single().TriggerClick());
@ -679,14 +679,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Name = "Test Room",
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
}
}
]
});
enterGameplay();
@ -724,14 +724,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Name = "Test Room",
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
}
}
]
});
enterGameplay();
@ -754,14 +754,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Name = "Test Room",
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
}
}
]
});
pressReadyButton();
@ -791,15 +791,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
roomManager.AddServerSideRoom(new Room
{
Name = { Value = "Test Room" },
QueueMode = { Value = QueueMode.AllPlayers },
Name = "Test Room",
QueueMode = QueueMode.AllPlayers,
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
}
}
]
}, API.LocalUser.Value);
});
@ -810,12 +810,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("disable polling", () => this.ChildrenOfType<ListingPollingComponent>().Single().TimeBetweenPolls.Value = 0);
AddStep("change server-side settings", () =>
{
roomManager.ServerSideRooms[0].Name.Value = "New name";
roomManager.ServerSideRooms[0].Playlist.Add(new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
ID = 2,
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
});
roomManager.ServerSideRooms[0].Name = "New name";
roomManager.ServerSideRooms[0].Playlist =
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
ID = 2,
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
}
];
});
AddStep("join room", () => InputManager.Key(Key.Enter));
@ -825,8 +828,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddAssert("local room has correct settings", () =>
{
var localRoom = this.ChildrenOfType<MultiplayerMatchSubScreen>().Single().Room;
return localRoom.Name.Value == roomManager.ServerSideRooms[0].Name.Value
&& localRoom.Playlist.SequenceEqual(roomManager.ServerSideRooms[0].Playlist);
return localRoom.Name == roomManager.ServerSideRooms[0].Name && localRoom.Playlist.Single().ID == 2;
});
}
@ -836,15 +838,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
QueueMode = { Value = QueueMode.AllPlayers },
Name = "Test Room",
QueueMode = QueueMode.AllPlayers,
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
}
}
]
});
AddStep("set spectating state", () => multiplayerClient.ChangeUserState(API.LocalUser.Value.OnlineID, MultiplayerUserState.Spectating));
@ -872,15 +874,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
QueueMode = { Value = QueueMode.AllPlayers },
Name = "Test Room",
QueueMode = QueueMode.AllPlayers,
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
}
}
]
});
AddStep("set spectating state", () => multiplayerClient.ChangeUserState(API.LocalUser.Value.OnlineID, MultiplayerUserState.Spectating));
@ -911,15 +913,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
QueueMode = { Value = QueueMode.AllPlayers },
Name = "Test Room",
QueueMode = QueueMode.AllPlayers,
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
}
}
]
});
enterGameplay();
@ -942,15 +944,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
QueueMode = { Value = QueueMode.AllPlayers },
Name = "Test Room",
QueueMode = QueueMode.AllPlayers,
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
}
}
]
});
enterGameplay();
@ -976,14 +978,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Name = "Test Room",
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
}
]
});
AddStep("join other user and make host", () =>
@ -1022,10 +1024,10 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
QueueMode = { Value = QueueMode.AllPlayers },
Name = "Test Room",
QueueMode = QueueMode.AllPlayers,
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
@ -1036,7 +1038,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
RulesetID = new TaikoRuleset().RulesetInfo.OnlineID,
AllowedMods = new[] { new APIMod { Acronym = "HD" } },
},
}
]
});
AddStep("select hidden", () => multiplayerClient.ChangeUserMods(new[] { new APIMod { Acronym = "HD" } }));

View File

@ -37,10 +37,10 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestPerUserMods()
{
AddStep("first user has no mods", () => Assert.That(((TestLeaderboard)Leaderboard).UserMods[0], Is.Empty));
AddStep("first user has no mods", () => Assert.That(((TestLeaderboard)Leaderboard!).UserMods[0], Is.Empty));
AddStep("last user has NF mod", () =>
{
Assert.That(((TestLeaderboard)Leaderboard).UserMods[TOTAL_USERS - 1], Has.One.Items);
Assert.That(((TestLeaderboard)Leaderboard!).UserMods[TOTAL_USERS - 1], Has.One.Items);
Assert.That(((TestLeaderboard)Leaderboard).UserMods[TOTAL_USERS - 1].Single(), Is.TypeOf<OsuModNoFail>());
});
}

View File

@ -39,7 +39,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
LoadComponentAsync(new MatchScoreDisplay
{
Team1Score = { BindTarget = Leaderboard.TeamScores[0] },
Team1Score = { BindTarget = Leaderboard!.TeamScores[0] },
Team2Score = { BindTarget = Leaderboard.TeamScores[1] }
}, Add);

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics.Containers;
@ -22,10 +20,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
protected new TestRoomManager RoomManager => (TestRoomManager)base.RoomManager;
private LoungeSubScreen loungeScreen;
private Room lastJoinedRoom;
private string lastJoinedPassword;
private LoungeSubScreen loungeScreen = null!;
private Room? lastJoinedRoom;
private string? lastJoinedPassword;
public override void SetUpSteps()
{
@ -87,7 +84,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestJoinRoomWithIncorrectPasswordViaButton()
{
DrawableLoungeRoom.PasswordEntryPopover passwordEntryPopover = null;
DrawableLoungeRoom.PasswordEntryPopover? passwordEntryPopover = null;
AddStep("add room", () => RoomManager.AddRooms(1, withPassword: true));
AddStep("select room", () => InputManager.Key(Key.Down));
@ -97,14 +94,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("press join room button", () => passwordEntryPopover.ChildrenOfType<OsuButton>().First().TriggerClick());
AddAssert("room not joined", () => loungeScreen.IsCurrentScreen());
AddUntilStep("password prompt still visible", () => passwordEntryPopover.State.Value == Visibility.Visible);
AddUntilStep("password prompt still visible", () => passwordEntryPopover!.State.Value == Visibility.Visible);
AddAssert("textbox still focused", () => InputManager.FocusedDrawable is OsuPasswordTextBox);
}
[Test]
public void TestJoinRoomWithIncorrectPasswordViaEnter()
{
DrawableLoungeRoom.PasswordEntryPopover passwordEntryPopover = null;
DrawableLoungeRoom.PasswordEntryPopover? passwordEntryPopover = null;
AddStep("add room", () => RoomManager.AddRooms(1, withPassword: true));
AddStep("select room", () => InputManager.Key(Key.Down));
@ -114,14 +111,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("press enter", () => InputManager.Key(Key.Enter));
AddAssert("room not joined", () => loungeScreen.IsCurrentScreen());
AddUntilStep("password prompt still visible", () => passwordEntryPopover.State.Value == Visibility.Visible);
AddUntilStep("password prompt still visible", () => passwordEntryPopover!.State.Value == Visibility.Visible);
AddAssert("textbox still focused", () => InputManager.FocusedDrawable is OsuPasswordTextBox);
}
[Test]
public void TestJoinRoomWithCorrectPassword()
{
DrawableLoungeRoom.PasswordEntryPopover passwordEntryPopover = null;
DrawableLoungeRoom.PasswordEntryPopover? passwordEntryPopover = null;
AddStep("add room", () => RoomManager.AddRooms(1, withPassword: true));
AddStep("select room", () => InputManager.Key(Key.Down));
@ -137,7 +134,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestJoinRoomWithPasswordViaKeyboardOnly()
{
DrawableLoungeRoom.PasswordEntryPopover passwordEntryPopover = null;
DrawableLoungeRoom.PasswordEntryPopover? passwordEntryPopover = null;
AddStep("add room", () => RoomManager.AddRooms(1, withPassword: true));
AddStep("select room", () => InputManager.Key(Key.Down));
@ -150,7 +147,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddAssert("room join password correct", () => lastJoinedPassword == "password");
}
private void onRoomJoined(Room room, string password)
private void onRoomJoined(Room room, string? password)
{
lastJoinedRoom = room;
lastJoinedPassword = password;

View File

@ -1,7 +1,6 @@
// 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 osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -13,9 +12,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneMultiplayerMatchFooter : MultiplayerTestScene
{
[Cached(typeof(IBindable<PlaylistItem>))]
private readonly Bindable<PlaylistItem> currentItem = new Bindable<PlaylistItem>();
public override void SetUpSteps()
{
base.SetUpSteps();
@ -33,7 +29,10 @@ namespace osu.Game.Tests.Visual.Multiplayer
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
Height = 50,
Child = new MultiplayerMatchFooter()
Child = new MultiplayerMatchFooter
{
SelectedItem = new Bindable<PlaylistItem?>()
}
}
};
});

View File

@ -1,12 +1,9 @@
// 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.
#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
@ -35,17 +32,16 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneMultiplayerMatchSongSelect : MultiplayerTestScene
{
private BeatmapManager manager;
private RulesetStore rulesets;
private BeatmapManager manager = null!;
private RulesetStore rulesets = null!;
private IList<BeatmapInfo> beatmaps => importedBeatmapSet?.PerformRead(s => s.Beatmaps) ?? new List<BeatmapInfo>();
private IList<BeatmapInfo> beatmaps => importedBeatmapSet.PerformRead(s => s.Beatmaps);
private TestMultiplayerMatchSongSelect songSelect;
private Live<BeatmapSetInfo> importedBeatmapSet;
private TestMultiplayerMatchSongSelect songSelect = null!;
private Live<BeatmapSetInfo> importedBeatmapSet = null!;
[Resolved]
private OsuConfigManager configManager { get; set; }
private OsuConfigManager configManager { get; set; } = null!;
[BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio)
@ -57,7 +53,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
Dependencies.Cache(detachedBeatmapStore = new DetachedBeatmapStore());
Dependencies.Cache(Realm);
importedBeatmapSet = manager.Import(TestResources.CreateTestBeatmapSetInfo(8, rulesets.AvailableRulesets.ToArray()));
importedBeatmapSet = manager.Import(TestResources.CreateTestBeatmapSetInfo(8, rulesets.AvailableRulesets.ToArray()))!;
Add(detachedBeatmapStore);
}
@ -71,7 +67,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
SelectedMods.SetDefault();
});
AddStep("create song select", () => LoadScreen(songSelect = new TestMultiplayerMatchSongSelect(SelectedRoom.Value)));
AddStep("create song select", () => LoadScreen(songSelect = new TestMultiplayerMatchSongSelect(SelectedRoom.Value!)));
AddUntilStep("wait for present", () => songSelect.IsCurrentScreen() && songSelect.BeatmapSetsLoaded);
}
@ -88,7 +84,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestBeatmapConfirmed()
{
BeatmapInfo selectedBeatmap = null;
BeatmapInfo selectedBeatmap = null!;
setUp();
@ -117,8 +113,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
setUp();
AddStep("change ruleset", () => Ruleset.Value = new OsuRuleset().RulesetInfo);
AddStep($"select {allowedMod.ReadableName()} as allowed", () => songSelect.FreeMods.Value = new[] { (Mod)Activator.CreateInstance(allowedMod) });
AddStep($"select {requiredMod.ReadableName()} as required", () => songSelect.Mods.Value = new[] { (Mod)Activator.CreateInstance(requiredMod) });
AddStep($"select {allowedMod.ReadableName()} as allowed", () => songSelect.FreeMods.Value = new[] { (Mod)Activator.CreateInstance(allowedMod)! });
AddStep($"select {requiredMod.ReadableName()} as required", () => songSelect.Mods.Value = new[] { (Mod)Activator.CreateInstance(requiredMod)! });
AddAssert("freemods empty", () => songSelect.FreeMods.Value.Count == 0);
@ -141,7 +137,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("create song select", () =>
{
SelectedRoom.Value.Playlist.Single().RulesetID = 2;
SelectedRoom.Value!.Playlist.Single().RulesetID = 2;
songSelect = new TestMultiplayerMatchSongSelect(SelectedRoom.Value, SelectedRoom.Value.Playlist.Single());
songSelect.OnLoadComplete += _ => Ruleset.Value = new TaikoRuleset().RulesetInfo;
LoadScreen(songSelect);
@ -171,7 +167,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
public new BeatmapCarousel Carousel => base.Carousel;
public TestMultiplayerMatchSongSelect(Room room, [CanBeNull] PlaylistItem itemToEdit = null)
public TestMultiplayerMatchSongSelect(Room room, PlaylistItem? itemToEdit = null)
: base(room, itemToEdit)
{
}

View File

@ -1,10 +1,7 @@
// 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.
#nullable disable
using System.Linq;
using JetBrains.Annotations;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
@ -42,10 +39,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneMultiplayerMatchSubScreen : MultiplayerTestScene
{
private MultiplayerMatchSubScreen screen;
private BeatmapManager beatmaps;
private BeatmapSetInfo importedSet;
private MultiplayerMatchSubScreen screen = null!;
private BeatmapManager beatmaps = null!;
private BeatmapSetInfo importedSet = null!;
public TestSceneMultiplayerMatchSubScreen()
: base(false)
@ -69,41 +65,25 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
AddStep("load match", () =>
{
SelectedRoom.Value = new Room { Name = { Value = "Test Room" } };
LoadScreen(screen = new TestMultiplayerMatchSubScreen(SelectedRoom.Value));
SelectedRoom.Value = new Room { Name = "Test Room" };
LoadScreen(screen = new TestMultiplayerMatchSubScreen(SelectedRoom.Value!));
});
AddUntilStep("wait for load", () => screen.IsCurrentScreen());
}
[Test]
[FlakyTest]
/*
* Fail rate around 1.5%
*
* TearDown : System.AggregateException : One or more errors occurred. (Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index'))
----> System.ArgumentOutOfRangeException : Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
* --TearDown
* at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
* at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
* at osu.Framework.Extensions.TaskExtensions.WaitSafely(Task task)
* at osu.Framework.Testing.TestScene.checkForErrors()
* at osu.Framework.Testing.TestScene.RunTestsFromNUnit()
*--ArgumentOutOfRangeException
* at osu.Framework.Bindables.BindableList`1.removeAt(Int32 index, BindableList`1 caller)
* at osu.Framework.Bindables.BindableList`1.removeAt(Int32 index, BindableList`1 caller)
* at osu.Framework.Bindables.BindableList`1.removeAt(Int32 index, BindableList`1 caller)
* at osu.Game.Online.Multiplayer.MultiplayerClient.<>c__DisplayClass106_0.<PlaylistItemChanged>b__0() in C:\BuildAgent\work\ecd860037212ac52\osu.Game\Online\Multiplayer\MultiplayerClient .cs:line 702
* at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal()
*/
public void TestCreatedRoom()
{
AddStep("add playlist item", () =>
{
SelectedRoom.Value.Playlist.Add(new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
});
SelectedRoom.Value!.Playlist =
[
new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
];
});
ClickButtonWhenEnabled<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>();
@ -112,16 +92,18 @@ namespace osu.Game.Tests.Visual.Multiplayer
}
[Test]
[FlakyTest] // See above
public void TestTaikoOnlyMod()
{
AddStep("add playlist item", () =>
{
SelectedRoom.Value.Playlist.Add(new PlaylistItem(new TestBeatmap(new TaikoRuleset().RulesetInfo).BeatmapInfo)
{
RulesetID = new TaikoRuleset().RulesetInfo.OnlineID,
AllowedMods = new[] { new APIMod(new TaikoModSwap()) }
});
SelectedRoom.Value!.Playlist =
[
new PlaylistItem(new TestBeatmap(new TaikoRuleset().RulesetInfo).BeatmapInfo)
{
RulesetID = new TaikoRuleset().RulesetInfo.OnlineID,
AllowedMods = new[] { new APIMod(new TaikoModSwap()) }
}
];
});
ClickButtonWhenEnabled<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>();
@ -133,32 +115,36 @@ namespace osu.Game.Tests.Visual.Multiplayer
}
[Test]
[FlakyTest] // See above
public void TestSettingValidity()
{
AddAssert("create button not enabled", () => !this.ChildrenOfType<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>().Single().Enabled.Value);
AddStep("set playlist", () =>
{
SelectedRoom.Value.Playlist.Add(new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
});
SelectedRoom.Value!.Playlist =
[
new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
];
});
AddAssert("create button enabled", () => this.ChildrenOfType<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>().Single().Enabled.Value);
}
[Test]
[FlakyTest] // See above
public void TestStartMatchWhileSpectating()
{
AddStep("set playlist", () =>
{
SelectedRoom.Value.Playlist.Add(new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First()).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
});
SelectedRoom.Value!.Playlist =
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First()).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
];
});
ClickButtonWhenEnabled<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>();
@ -179,16 +165,18 @@ namespace osu.Game.Tests.Visual.Multiplayer
}
[Test]
[FlakyTest] // See above
public void TestFreeModSelectionHasAllowedMods()
{
AddStep("add playlist item with allowed mod", () =>
{
SelectedRoom.Value.Playlist.Add(new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
AllowedMods = new[] { new APIMod(new OsuModDoubleTime()) }
});
SelectedRoom.Value!.Playlist =
[
new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
AllowedMods = new[] { new APIMod(new OsuModDoubleTime()) }
}
];
});
ClickButtonWhenEnabled<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>();
@ -206,16 +194,18 @@ namespace osu.Game.Tests.Visual.Multiplayer
}
[Test]
[FlakyTest] // See above
public void TestModSelectKeyWithAllowedMods()
{
AddStep("add playlist item with allowed mod", () =>
{
SelectedRoom.Value.Playlist.Add(new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
AllowedMods = new[] { new APIMod(new OsuModDoubleTime()) }
});
SelectedRoom.Value!.Playlist =
[
new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
AllowedMods = new[] { new APIMod(new OsuModDoubleTime()) }
}
];
});
ClickButtonWhenEnabled<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>();
@ -228,15 +218,17 @@ namespace osu.Game.Tests.Visual.Multiplayer
}
[Test]
[FlakyTest] // See above
public void TestModSelectKeyWithNoAllowedMods()
{
AddStep("add playlist item with no allowed mods", () =>
{
SelectedRoom.Value.Playlist.Add(new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
});
SelectedRoom.Value!.Playlist =
[
new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
}
];
});
ClickButtonWhenEnabled<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>();
@ -249,13 +241,12 @@ namespace osu.Game.Tests.Visual.Multiplayer
}
[Test]
[FlakyTest] // See above
public void TestNextPlaylistItemSelectedAfterCompletion()
{
AddStep("add two playlist items", () =>
{
SelectedRoom.Value.Playlist.AddRange(new[]
{
SelectedRoom.Value!.Playlist =
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First()).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
@ -264,7 +255,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
});
];
});
ClickButtonWhenEnabled<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>();
@ -286,24 +277,26 @@ namespace osu.Game.Tests.Visual.Multiplayer
}
[Test]
[FlakyTest] // See above
public void TestModSelectOverlay()
{
AddStep("add playlist item", () =>
{
SelectedRoom.Value.Playlist.Add(new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
RequiredMods = new[]
SelectedRoom.Value!.Playlist =
[
new PlaylistItem(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo)
{
new APIMod(new OsuModDoubleTime { SpeedChange = { Value = 2.0 } }),
new APIMod(new OsuModStrictTracking()),
},
AllowedMods = new[]
{
new APIMod(new OsuModFlashlight()),
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
RequiredMods = new[]
{
new APIMod(new OsuModDoubleTime { SpeedChange = { Value = 2.0 } }),
new APIMod(new OsuModStrictTracking()),
},
AllowedMods = new[]
{
new APIMod(new OsuModFlashlight()),
}
}
});
];
});
ClickButtonWhenEnabled<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>();
@ -323,8 +316,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
private partial class TestMultiplayerMatchSubScreen : MultiplayerMatchSubScreen
{
[Resolved(canBeNull: true)]
[CanBeNull]
private IDialogOverlay dialogOverlay { get; set; }
private IDialogOverlay? dialogOverlay { get; set; }
public TestMultiplayerMatchSubScreen(Room room)
: base(room)

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
@ -22,7 +20,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneMultiplayerPlayer : MultiplayerTestScene
{
private MultiplayerPlayer player;
private MultiplayerPlayer player = null!;
[Test]
public void TestGameplay()
@ -49,7 +47,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("score changed", () => player.GameplayState.ScoreProcessor.TotalScore.Value > 0);
}
private void setup(Func<IReadOnlyList<Mod>> mods = null)
private void setup(Func<IReadOnlyList<Mod>>? mods = null)
{
AddStep("set beatmap", () =>
{
@ -64,10 +62,10 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("initialise gameplay", () =>
{
Stack.Push(player = new MultiplayerPlayer(MultiplayerClient.ServerAPIRoom, new PlaylistItem(Beatmap.Value.BeatmapInfo)
Stack.Push(player = new MultiplayerPlayer(MultiplayerClient.ServerAPIRoom!, new PlaylistItem(Beatmap.Value.BeatmapInfo)
{
RulesetID = Beatmap.Value.BeatmapInfo.Ruleset.OnlineID,
}, MultiplayerClient.ServerRoom?.Users.ToArray()));
}, MultiplayerClient.ServerRoom!.Users.ToArray()));
});
AddUntilStep("wait for player to be current", () => player.IsCurrentScreen() && player.IsLoaded);

View File

@ -28,9 +28,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneMultiplayerPlaylist : MultiplayerTestScene
{
[Cached(typeof(IBindable<PlaylistItem>))]
private readonly Bindable<PlaylistItem> currentItem = new Bindable<PlaylistItem>();
private MultiplayerPlaylist list = null!;
private BeatmapManager beatmaps = null!;
private BeatmapSetInfo importedSet = null!;
@ -51,12 +48,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("create list", () =>
{
Child = list = new MultiplayerPlaylist
Child = list = new MultiplayerPlaylist(SelectedRoom.Value!)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.4f, 0.8f)
Size = new Vector2(0.4f, 0.8f),
SelectedItem = new Bindable<PlaylistItem?>()
};
});
@ -166,9 +164,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
RoomManager.CreateRoom(new Room
{
Name = { Value = "test name" },
Name = "test name",
Playlist =
{
[
new PlaylistItem(new TestBeatmap(Ruleset.Value).BeatmapInfo)
{
RulesetID = Ruleset.Value.OnlineID
@ -178,7 +176,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
RulesetID = Ruleset.Value.OnlineID,
Expired = true
}
}
]
});
});

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System;
using System.Linq;
using NUnit.Framework;
@ -27,10 +25,10 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneMultiplayerQueueList : MultiplayerTestScene
{
private MultiplayerQueueList playlist;
private BeatmapManager beatmaps;
private BeatmapSetInfo importedSet;
private BeatmapInfo importedBeatmap;
private MultiplayerQueueList playlist = null!;
private BeatmapManager beatmaps = null!;
private BeatmapSetInfo importedSet = null!;
private BeatmapInfo importedBeatmap = null!;
[BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio)
@ -46,12 +44,17 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("create playlist", () =>
{
Child = playlist = new MultiplayerQueueList
Child = playlist = new MultiplayerQueueList(SelectedRoom.Value!)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(500, 300),
Items = { BindTarget = MultiplayerClient.ClientAPIRoom!.Playlist }
};
MultiplayerClient.ClientAPIRoom!.PropertyChanged += (_, e) =>
{
if (e.PropertyName == nameof(Room.Playlist))
playlist.Items.ReplaceRange(0, playlist.Items.Count, MultiplayerClient.ClientAPIRoom.Playlist);
};
});
@ -69,7 +72,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
public void TestDeleteButtonAlwaysVisibleForHost()
{
AddStep("set all players queue mode", () => MultiplayerClient.ChangeSettings(new MultiplayerRoomSettings { QueueMode = QueueMode.AllPlayers }).WaitSafely());
AddUntilStep("wait for queue mode change", () => MultiplayerClient.ClientAPIRoom?.QueueMode.Value == QueueMode.AllPlayers);
AddUntilStep("wait for queue mode change", () => MultiplayerClient.ClientAPIRoom?.QueueMode == QueueMode.AllPlayers);
addPlaylistItem(() => API.LocalUser.Value.OnlineID);
assertDeleteButtonVisibility(1, true);
@ -81,7 +84,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
public void TestDeleteButtonOnlyVisibleForItemOwnerIfNotHost()
{
AddStep("set all players queue mode", () => MultiplayerClient.ChangeSettings(new MultiplayerRoomSettings { QueueMode = QueueMode.AllPlayers }).WaitSafely());
AddUntilStep("wait for queue mode change", () => MultiplayerClient.ClientAPIRoom?.QueueMode.Value == QueueMode.AllPlayers);
AddUntilStep("wait for queue mode change", () => MultiplayerClient.ClientAPIRoom?.QueueMode == QueueMode.AllPlayers);
AddStep("join other user", () => MultiplayerClient.AddUser(new APIUser { Id = 1234 }));
AddStep("set other user as host", () => MultiplayerClient.TransferHost(1234));
@ -100,7 +103,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
public void TestSingleItemDoesNotHaveDeleteButton()
{
AddStep("set all players queue mode", () => MultiplayerClient.ChangeSettings(new MultiplayerRoomSettings { QueueMode = QueueMode.AllPlayers }).WaitSafely());
AddUntilStep("wait for queue mode change", () => MultiplayerClient.ClientAPIRoom?.QueueMode.Value == QueueMode.AllPlayers);
AddUntilStep("wait for queue mode change", () => MultiplayerClient.ClientAPIRoom?.QueueMode == QueueMode.AllPlayers);
assertDeleteButtonVisibility(0, false);
}
@ -109,7 +112,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
public void TestCurrentItemHasDeleteButtonIfNotSingle()
{
AddStep("set all players queue mode", () => MultiplayerClient.ChangeSettings(new MultiplayerRoomSettings { QueueMode = QueueMode.AllPlayers }).WaitSafely());
AddUntilStep("wait for queue mode change", () => MultiplayerClient.ClientAPIRoom?.QueueMode.Value == QueueMode.AllPlayers);
AddUntilStep("wait for queue mode change", () => MultiplayerClient.ClientAPIRoom?.QueueMode == QueueMode.AllPlayers);
addPlaylistItem(() => API.LocalUser.Value.OnlineID);

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using NUnit.Framework;
using osu.Game.Online.Rooms;
using osu.Game.Rulesets.Osu;
@ -16,7 +14,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestDisplayResults()
{
MultiplayerResultsScreen screen = null;
MultiplayerResultsScreen screen = null!;
AddStep("show results screen", () =>
{

View File

@ -26,9 +26,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneMultiplayerSpectateButton : MultiplayerTestScene
{
[Cached(typeof(IBindable<PlaylistItem>))]
private readonly Bindable<PlaylistItem> currentItem = new Bindable<PlaylistItem>();
private MultiplayerSpectateButton spectateButton = null!;
private MatchStartControl startControl = null!;
@ -51,13 +48,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("create button", () =>
{
AvailabilityTracker.SelectedItem.BindTo(currentItem);
PlaylistItem item = SelectedRoom.Value!.Playlist.First();
AvailabilityTracker.SelectedItem.Value = item;
importedSet = beatmaps.GetAllUsableBeatmapSets().First();
Beatmap.Value = beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First());
currentItem.Value = SelectedRoom.Value.Playlist.First();
Child = new PopoverContainer
{
RelativeSizeAxes = Axes.Both,
@ -72,12 +69,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(200, 50),
SelectedItem = new Bindable<PlaylistItem?>(item)
},
startControl = new MatchStartControl
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(200, 50),
SelectedItem = new Bindable<PlaylistItem?>(item)
}
}
}

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics;
@ -16,7 +14,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneMultiplayerSpectatorPlayerGrid : OsuManualInputManagerTestScene
{
private PlayerGrid grid;
private PlayerGrid grid = null!;
[SetUp]
public void Setup() => Schedule(() =>

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System.Collections.Generic;
using NUnit.Framework;
using osu.Framework.Bindables;
@ -32,7 +30,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[TestCase(1048576, 1048576)]
public void TestDisplayTeamResults(int team1Score, int team2Score)
{
MultiplayerResultsScreen screen = null;
MultiplayerResultsScreen screen = null!;
AddStep("show results screen", () =>
{

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
@ -28,18 +26,18 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestScenePlaylistsRoomSettingsPlaylist : OnlinePlayTestScene
{
private TestPlaylist playlist;
private TestPlaylist playlist = null!;
[Test]
public void TestItemRemovedOnDeletion()
{
PlaylistItem selectedItem = null;
PlaylistItem selectedItem = null!;
createPlaylist();
moveToItem(0);
AddStep("click", () => InputManager.Click(MouseButton.Left));
AddStep("retrieve selection", () => selectedItem = playlist.SelectedItem.Value);
AddStep("retrieve selection", () => selectedItem = playlist.SelectedItem.Value!);
moveToDeleteButton(0);
AddStep("click delete button", () => InputManager.Click(MouseButton.Left));
@ -122,7 +120,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
InputManager.MoveMouseTo(item.ChildrenOfType<DrawableRoomPlaylistItem.PlaylistRemoveButton>().ElementAt(0), offset);
});
private void createPlaylist(Action<TestPlaylist> setupPlaylist = null)
private void createPlaylist(Action<TestPlaylist>? setupPlaylist = null)
{
AddStep("create playlist", () =>
{

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System;
using System.Linq;
using NUnit.Framework;
@ -27,9 +25,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestScenePlaylistsSongSelect : OnlinePlayTestScene
{
private BeatmapManager manager;
private TestPlaylistsSongSelect songSelect;
private BeatmapManager manager = null!;
private TestPlaylistsSongSelect songSelect = null!;
[BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio)
@ -60,7 +57,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
SelectedMods.Value = Array.Empty<Mod>();
});
AddStep("create song select", () => LoadScreen(songSelect = new TestPlaylistsSongSelect(SelectedRoom.Value)));
AddStep("create song select", () => LoadScreen(songSelect = new TestPlaylistsSongSelect(SelectedRoom.Value!)));
AddUntilStep("wait for present", () => songSelect.IsCurrentScreen() && songSelect.BeatmapSetsLoaded);
}
@ -68,46 +65,41 @@ namespace osu.Game.Tests.Visual.Multiplayer
public void TestItemAddedIfEmptyOnStart()
{
AddStep("finalise selection", () => songSelect.FinaliseSelection());
AddAssert("playlist has 1 item", () => SelectedRoom.Value.Playlist.Count == 1);
AddAssert("playlist has 1 item", () => SelectedRoom.Value!.Playlist.Count == 1);
}
[Test]
public void TestItemAddedWhenCreateNewItemClicked()
{
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem());
AddAssert("playlist has 1 item", () => SelectedRoom.Value.Playlist.Count == 1);
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem!());
AddAssert("playlist has 1 item", () => SelectedRoom.Value!.Playlist.Count == 1);
}
[Test]
public void TestItemNotAddedIfExistingOnStart()
{
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem());
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem!());
AddStep("finalise selection", () => songSelect.FinaliseSelection());
AddAssert("playlist has 1 item", () => SelectedRoom.Value.Playlist.Count == 1);
AddAssert("playlist has 1 item", () => SelectedRoom.Value!.Playlist.Count == 1);
}
[Test]
public void TestAddSameItemMultipleTimes()
{
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem());
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem());
AddAssert("playlist has 2 items", () => SelectedRoom.Value.Playlist.Count == 2);
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem!());
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem!());
AddAssert("playlist has 2 items", () => SelectedRoom.Value!.Playlist.Count == 2);
}
[Test]
public void TestAddItemAfterRearrangement()
{
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem());
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem());
AddStep("rearrange", () =>
{
var item = SelectedRoom.Value.Playlist[0];
SelectedRoom.Value.Playlist.RemoveAt(0);
SelectedRoom.Value.Playlist.Add(item);
});
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem!());
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem!());
AddStep("rearrange", () => SelectedRoom.Value!.Playlist = SelectedRoom.Value!.Playlist.Skip(1).Append(SelectedRoom.Value!.Playlist[0]).ToArray());
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem());
AddAssert("new item has id 2", () => SelectedRoom.Value.Playlist.Last().ID == 2);
AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem!());
AddAssert("new item has id 2", () => SelectedRoom.Value!.Playlist.Last().ID == 2);
}
/// <summary>
@ -117,19 +109,19 @@ namespace osu.Game.Tests.Visual.Multiplayer
public void TestNewItemHasNewModInstances()
{
AddStep("set dt mod", () => SelectedMods.Value = new[] { new OsuModDoubleTime() });
AddStep("create item", () => songSelect.BeatmapDetails.CreateNewItem());
AddStep("create item", () => songSelect.BeatmapDetails.CreateNewItem!());
AddStep("change mod rate", () => ((OsuModDoubleTime)SelectedMods.Value[0]).SpeedChange.Value = 2);
AddStep("create item", () => songSelect.BeatmapDetails.CreateNewItem());
AddStep("create item", () => songSelect.BeatmapDetails.CreateNewItem!());
AddAssert("item 1 has rate 1.5", () =>
{
var mod = (OsuModDoubleTime)SelectedRoom.Value.Playlist.First().RequiredMods[0].ToMod(new OsuRuleset());
var mod = (OsuModDoubleTime)SelectedRoom.Value!.Playlist.First().RequiredMods[0].ToMod(new OsuRuleset());
return Precision.AlmostEquals(1.5, mod.SpeedChange.Value);
});
AddAssert("item 2 has rate 2", () =>
{
var mod = (OsuModDoubleTime)SelectedRoom.Value.Playlist.Last().RequiredMods[0].ToMod(new OsuRuleset());
var mod = (OsuModDoubleTime)SelectedRoom.Value!.Playlist.Last().RequiredMods[0].ToMod(new OsuRuleset());
return Precision.AlmostEquals(2, mod.SpeedChange.Value);
});
}
@ -140,7 +132,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Test]
public void TestGlobalModInstancesNotRetained()
{
OsuModDoubleTime mod = null;
OsuModDoubleTime mod = null!;
AddStep("set dt mod and store", () =>
{
@ -150,12 +142,12 @@ namespace osu.Game.Tests.Visual.Multiplayer
mod = (OsuModDoubleTime)SelectedMods.Value[0];
});
AddStep("create item", () => songSelect.BeatmapDetails.CreateNewItem());
AddStep("create item", () => songSelect.BeatmapDetails.CreateNewItem!());
AddStep("change stored mod rate", () => mod.SpeedChange.Value = 2);
AddAssert("item has rate 1.5", () =>
{
var m = (OsuModDoubleTime)SelectedRoom.Value.Playlist.First().RequiredMods[0].ToMod(new OsuRuleset());
var m = (OsuModDoubleTime)SelectedRoom.Value!.Playlist.First().RequiredMods[0].ToMod(new OsuRuleset());
return Precision.AlmostEquals(1.5, m.SpeedChange.Value);
});
}

View File

@ -9,7 +9,6 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Screens.OnlinePlay.Lounge.Components;
namespace osu.Game.Tests.Visual.Multiplayer
@ -18,10 +17,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
private readonly Mock<MultiplayerClient> multiplayerClient = new Mock<MultiplayerClient>();
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) =>
// not used directly in component, but required due to it inheriting from OnlinePlayComposite.
new CachedModelDependencyContainer<Room>(base.CreateChildDependencies(parent));
[BackgroundDependencyLoader]
private void load()
{

View File

@ -20,7 +20,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
SelectedRoom.Value = new Room();
Child = new StarRatingRangeDisplay
Child = new StarRatingRangeDisplay(SelectedRoom.Value)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre
@ -33,11 +33,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
AddStep("set playlist", () =>
{
SelectedRoom.Value.Playlist.AddRange(new[]
{
SelectedRoom.Value!.Playlist =
[
new PlaylistItem(new BeatmapInfo { StarRating = min }),
new PlaylistItem(new BeatmapInfo { StarRating = max }),
});
];
});
}
}

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System;
using System.Linq;
using NUnit.Framework;
@ -29,10 +27,10 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
public partial class TestSceneTeamVersus : ScreenTestScene
{
private BeatmapManager beatmaps;
private BeatmapSetInfo importedSet;
private BeatmapManager beatmaps = null!;
private BeatmapSetInfo importedSet = null!;
private TestMultiplayerComponents multiplayerComponents;
private TestMultiplayerComponents multiplayerComponents = null!;
private TestMultiplayerClient multiplayerClient => multiplayerComponents.MultiplayerClient;
@ -64,15 +62,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Type = { Value = MatchType.TeamVersus },
Name = "Test Room",
Type = MatchType.TeamVersus,
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
}
]
});
AddUntilStep("room type is team vs", () => multiplayerClient.ClientRoom?.Settings.MatchType == MatchType.TeamVersus);
@ -84,15 +82,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Type = { Value = MatchType.TeamVersus },
Name = "Test Room",
Type = MatchType.TeamVersus,
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
}
]
});
AddUntilStep("user on team 0", () => (multiplayerClient.ClientRoom?.Users.FirstOrDefault()?.MatchState as TeamVersusUserState)?.TeamID == 0);
@ -121,25 +119,25 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Type = { Value = MatchType.HeadToHead },
Name = "Test Room",
Type = MatchType.HeadToHead,
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
}
}
]
});
AddUntilStep("match type head to head", () => multiplayerClient.ClientAPIRoom?.Type.Value == MatchType.HeadToHead);
AddUntilStep("match type head to head", () => multiplayerClient.ClientAPIRoom?.Type == MatchType.HeadToHead);
AddStep("change match type", () => multiplayerClient.ChangeSettings(new MultiplayerRoomSettings
{
MatchType = MatchType.TeamVersus
}).WaitSafely());
AddUntilStep("api room updated to team versus", () => multiplayerClient.ClientAPIRoom?.Type.Value == MatchType.TeamVersus);
AddUntilStep("api room updated to team versus", () => multiplayerClient.ClientAPIRoom?.Type == MatchType.TeamVersus);
}
[Test]
@ -147,14 +145,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Name = "Test Room",
Playlist =
{
[
new PlaylistItem(beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.Ruleset.OnlineID == 0)).BeatmapInfo)
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID,
}
}
]
});
AddUntilStep("room type is head to head", () => multiplayerClient.ClientRoom?.Settings.MatchType == MatchType.HeadToHead);

View File

@ -40,15 +40,13 @@ namespace osu.Game.Tests.Visual.Online
AddStep("import score", () =>
{
using (var resourceStream = TestResources.OpenResource("Replays/mania-replay.osr"))
{
var importTask = new ImportTask(resourceStream, "replay.osr");
var resourceStream = TestResources.OpenResource("Replays/mania-replay.osr");
var importTask = new ImportTask(resourceStream, "replay.osr");
Game.ScoreManager.Import(new[] { importTask });
}
Game.ScoreManager.Import(new[] { importTask });
});
AddUntilStep("Replay missing notification show", () => Game.Notifications.ChildrenOfType<MissingBeatmapNotification>().Any());
AddUntilStep("Replay missing notification shown", () => Game.Notifications.ChildrenOfType<MissingBeatmapNotification>().Any());
}
[Test]
@ -58,15 +56,13 @@ namespace osu.Game.Tests.Visual.Online
AddStep("import score", () =>
{
using (var resourceStream = TestResources.OpenResource("Replays/mania-replay.osr"))
{
var importTask = new ImportTask(resourceStream, "replay.osr");
var resourceStream = TestResources.OpenResource("Replays/mania-replay.osr");
var importTask = new ImportTask(resourceStream, "replay.osr");
Game.ScoreManager.Import(new[] { importTask });
}
Game.ScoreManager.Import(new[] { importTask });
});
AddUntilStep("Replay missing notification not show", () => !Game.Notifications.ChildrenOfType<MissingBeatmapNotification>().Any());
AddUntilStep("Replay missing notification not shown", () => !Game.Notifications.ChildrenOfType<MissingBeatmapNotification>().Any());
}
private void setupBeatmapResponse(APIBeatmap b)

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System.Linq;
using NUnit.Framework;
using osu.Framework.Bindables;
@ -21,7 +19,7 @@ namespace osu.Game.Tests.Visual.Playlists
{
protected new TestRoomManager RoomManager => (TestRoomManager)base.RoomManager;
private TestLoungeSubScreen loungeScreen;
private TestLoungeSubScreen loungeScreen = null!;
public override void SetUpSteps()
{
@ -97,7 +95,7 @@ namespace osu.Game.Tests.Visual.Playlists
private partial class TestLoungeSubScreen : PlaylistsLoungeSubScreen
{
public new Bindable<Room> SelectedRoom => base.SelectedRoom;
public new Bindable<Room?> SelectedRoom => base.SelectedRoom;
}
}
}

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System;
using NUnit.Framework;
using osu.Framework.Bindables;
@ -22,7 +20,7 @@ namespace osu.Game.Tests.Visual.Playlists
{
protected new TestRoomManager RoomManager => (TestRoomManager)base.RoomManager;
private TestRoomSettings settings;
private TestRoomSettings settings = null!;
protected override OnlinePlayTestSceneDependencies CreateOnlinePlayDependencies() => new TestDependencies();
@ -34,7 +32,7 @@ namespace osu.Game.Tests.Visual.Playlists
{
SelectedRoom.Value = new Room();
Child = settings = new TestRoomSettings(SelectedRoom.Value)
Child = settings = new TestRoomSettings(SelectedRoom.Value!)
{
RelativeSizeAxes = Axes.Both,
State = { Value = Visibility.Visible }
@ -47,19 +45,19 @@ namespace osu.Game.Tests.Visual.Playlists
{
AddStep("clear name and beatmap", () =>
{
SelectedRoom.Value.Name.Value = "";
SelectedRoom.Value.Playlist.Clear();
SelectedRoom.Value!.Name = "";
SelectedRoom.Value!.Playlist = [];
});
AddAssert("button disabled", () => !settings.ApplyButton.Enabled.Value);
AddStep("set name", () => SelectedRoom.Value.Name.Value = "Room name");
AddStep("set name", () => SelectedRoom.Value!.Name = "Room name");
AddAssert("button disabled", () => !settings.ApplyButton.Enabled.Value);
AddStep("set beatmap", () => SelectedRoom.Value.Playlist.Add(new PlaylistItem(CreateBeatmap(Ruleset.Value).BeatmapInfo)));
AddStep("set beatmap", () => SelectedRoom.Value!.Playlist = [new PlaylistItem(CreateBeatmap(Ruleset.Value).BeatmapInfo)]);
AddAssert("button enabled", () => settings.ApplyButton.Enabled.Value);
AddStep("clear name", () => SelectedRoom.Value.Name.Value = "");
AddStep("clear name", () => SelectedRoom.Value!.Name = "");
AddAssert("button disabled", () => !settings.ApplyButton.Enabled.Value);
}
@ -69,13 +67,13 @@ namespace osu.Game.Tests.Visual.Playlists
const string expected_name = "expected name";
TimeSpan expectedDuration = TimeSpan.FromMinutes(15);
Room createdRoom = null;
Room createdRoom = null!;
AddStep("setup", () =>
{
settings.NameField.Current.Value = expected_name;
settings.DurationField.Current.Value = expectedDuration;
SelectedRoom.Value.Playlist.Add(new PlaylistItem(CreateBeatmap(Ruleset.Value).BeatmapInfo));
SelectedRoom.Value!.Playlist = [new PlaylistItem(CreateBeatmap(Ruleset.Value).BeatmapInfo)];
RoomManager.CreateRequested = r =>
{
@ -85,8 +83,8 @@ namespace osu.Game.Tests.Visual.Playlists
});
AddStep("create room", () => settings.ApplyButton.Action.Invoke());
AddAssert("has correct name", () => createdRoom.Name.Value == expected_name);
AddAssert("has correct duration", () => createdRoom.Duration.Value == expectedDuration);
AddAssert("has correct name", () => createdRoom.Name == expected_name);
AddAssert("has correct duration", () => createdRoom.Duration == expectedDuration);
}
[Test]
@ -94,14 +92,14 @@ namespace osu.Game.Tests.Visual.Playlists
{
const string not_found_prefix = "beatmaps not found:";
string errorMessage = null;
string errorMessage = null!;
AddStep("setup", () =>
{
var beatmap = CreateBeatmap(Ruleset.Value).BeatmapInfo;
SelectedRoom.Value.Name.Value = "Test Room";
SelectedRoom.Value.Playlist.Add(new PlaylistItem(beatmap));
SelectedRoom.Value!.Name = "Test Room";
SelectedRoom.Value!.Playlist = [new PlaylistItem(beatmap)];
errorMessage = $"{not_found_prefix} {beatmap.OnlineID}";
@ -109,13 +107,13 @@ namespace osu.Game.Tests.Visual.Playlists
});
AddAssert("error not displayed", () => !settings.ErrorText.IsPresent);
AddAssert("playlist item valid", () => SelectedRoom.Value.Playlist[0].Valid.Value);
AddAssert("playlist item valid", () => SelectedRoom.Value!.Playlist[0].Valid.Value);
AddStep("create room", () => settings.ApplyButton.Action.Invoke());
AddAssert("error displayed", () => settings.ErrorText.IsPresent);
AddAssert("error has custom text", () => settings.ErrorText.Text != errorMessage);
AddAssert("playlist item marked invalid", () => !SelectedRoom.Value.Playlist[0].Valid.Value);
AddAssert("playlist item marked invalid", () => !SelectedRoom.Value!.Playlist[0].Valid.Value);
}
[Test]
@ -127,8 +125,8 @@ namespace osu.Game.Tests.Visual.Playlists
AddStep("setup", () =>
{
SelectedRoom.Value.Name.Value = "Test Room";
SelectedRoom.Value.Playlist.Add(new PlaylistItem(CreateBeatmap(Ruleset.Value).BeatmapInfo));
SelectedRoom.Value!.Name = "Test Room";
SelectedRoom.Value!.Playlist = [new PlaylistItem(CreateBeatmap(Ruleset.Value).BeatmapInfo)];
RoomManager.CreateRequested = _ => failText;
});
@ -169,7 +167,7 @@ namespace osu.Game.Tests.Visual.Playlists
protected class TestRoomManager : IRoomManager
{
public Func<Room, string> CreateRequested;
public Func<Room, string>? CreateRequested;
public event Action RoomsUpdated
{
@ -187,7 +185,7 @@ namespace osu.Game.Tests.Visual.Playlists
public void ClearRooms() => throw new NotImplementedException();
public void CreateRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null)
public void CreateRoom(Room room, Action<Room>? onSuccess = null, Action<string>? onError = null)
{
if (CreateRequested == null)
return;
@ -200,7 +198,7 @@ namespace osu.Game.Tests.Visual.Playlists
onSuccess?.Invoke(room);
}
public void JoinRoom(Room room, string password, Action<Room> onSuccess = null, Action<string> onError = null) => throw new NotImplementedException();
public void JoinRoom(Room room, string? password, Action<Room>? onSuccess = null, Action<string>? onError = null) => throw new NotImplementedException();
public void PartRoom() => throw new NotImplementedException();
}

View File

@ -1,6 +1,7 @@
// 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.Linq;
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Game.Online.API.Requests.Responses;
@ -19,17 +20,16 @@ namespace osu.Game.Tests.Visual.Playlists
AddStep("create list", () =>
{
SelectedRoom.Value = new Room { RoomID = { Value = 7 } };
for (int i = 0; i < 50; i++)
SelectedRoom.Value = new Room
{
SelectedRoom.Value.RecentParticipants.Add(new APIUser
RoomID = 7,
RecentParticipants = Enumerable.Range(0, 50).Select(_ => new APIUser
{
Username = "peppy",
Statistics = new UserStatistics { GlobalRank = 1234 },
Id = 2
});
}
}).ToArray()
};
});
}
@ -38,7 +38,7 @@ namespace osu.Game.Tests.Visual.Playlists
{
AddStep("create component", () =>
{
Child = new ParticipantsDisplay(Direction.Horizontal)
Child = new ParticipantsDisplay(SelectedRoom.Value!, Direction.Horizontal)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@ -52,7 +52,7 @@ namespace osu.Game.Tests.Visual.Playlists
{
AddStep("create component", () =>
{
Child = new ParticipantsDisplay(Direction.Vertical)
Child = new ParticipantsDisplay(SelectedRoom.Value!, Direction.Vertical)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,

View File

@ -1,13 +1,10 @@
// 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.
#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using JetBrains.Annotations;
using Newtonsoft.Json.Linq;
using NUnit.Framework;
using osu.Framework.Graphics.Containers;
@ -34,14 +31,14 @@ namespace osu.Game.Tests.Visual.Playlists
private const int scores_per_result = 10;
private const int real_user_position = 200;
private TestResultsScreen resultsScreen;
private TestResultsScreen resultsScreen = null!;
private int lowestScoreId; // Score ID of the lowest score in the list.
private int highestScoreId; // Score ID of the highest score in the list.
private bool requestComplete;
private int totalCount;
private ScoreInfo userScore;
private ScoreInfo userScore = null!;
[SetUpSteps]
public override void SetUpSteps()
@ -205,7 +202,7 @@ namespace osu.Game.Tests.Visual.Playlists
AddAssert("placeholder shown", () => this.ChildrenOfType<MessagePlaceholder>().Count(), () => Is.EqualTo(1));
}
private void createResults(Func<ScoreInfo> getScore = null)
private void createResults(Func<ScoreInfo>? getScore = null)
{
AddStep("load results", () =>
{
@ -229,7 +226,7 @@ namespace osu.Game.Tests.Visual.Playlists
AddWaitStep("wait for display", 5);
}
private void bindHandler(bool delayed = false, ScoreInfo userScore = null, bool failRequests = false, bool noScores = false) => ((DummyAPIAccess)API).HandleRequest = request =>
private void bindHandler(bool delayed = false, ScoreInfo? userScore = null, bool failRequests = false, bool noScores = false) => ((DummyAPIAccess)API).HandleRequest = request =>
{
// pre-check for requests we should be handling (as they are scheduled below).
switch (request)
@ -286,7 +283,7 @@ namespace osu.Game.Tests.Visual.Playlists
req.TriggerFailure(new WebException("Failed."));
}
private MultiplayerScore createUserResponse([NotNull] ScoreInfo userScore)
private MultiplayerScore createUserResponse(ScoreInfo userScore)
{
var multiplayerUserScore = new MultiplayerScore
{
@ -420,7 +417,7 @@ namespace osu.Game.Tests.Visual.Playlists
public new LoadingSpinner RightSpinner => base.RightSpinner;
public new ScorePanelList ScorePanelList => base.ScorePanelList;
public TestResultsScreen([CanBeNull] ScoreInfo score, int roomId, PlaylistItem playlistItem)
public TestResultsScreen(ScoreInfo? score, int roomId, PlaylistItem playlistItem)
: base(score, roomId, playlistItem)
{
AllowRetry = true;

View File

@ -1,12 +1,9 @@
// 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.
#nullable disable
using System;
using System.Diagnostics;
using System.Linq;
using JetBrains.Annotations;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
@ -35,11 +32,9 @@ namespace osu.Game.Tests.Visual.Playlists
{
public partial class TestScenePlaylistsRoomCreation : OnlinePlayTestScene
{
private BeatmapManager manager;
private TestPlaylistsRoomSubScreen match;
private BeatmapSetInfo importedBeatmap;
private BeatmapManager manager = null!;
private TestPlaylistsRoomSubScreen match = null!;
private BeatmapSetInfo importedBeatmap = null!;
[BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio)
@ -52,11 +47,11 @@ namespace osu.Game.Tests.Visual.Playlists
[SetUpSteps]
public void SetupSteps()
{
AddStep("set room", () => SelectedRoom!.Value = new Room());
AddStep("set room", () => SelectedRoom.Value = new Room());
importBeatmap();
AddStep("load match", () => LoadScreen(match = new TestPlaylistsRoomSubScreen(SelectedRoom!.Value)));
AddStep("load match", () => LoadScreen(match = new TestPlaylistsRoomSubScreen(SelectedRoom.Value!)));
AddUntilStep("wait for load", () => match.IsCurrentScreen());
}
@ -65,14 +60,17 @@ namespace osu.Game.Tests.Visual.Playlists
{
setupAndCreateRoom(room =>
{
room.Name.Value = "my awesome room";
room.Host.Value = API.LocalUser.Value;
room.RecentParticipants.Add(room.Host.Value);
room.EndDate.Value = DateTimeOffset.Now.AddMinutes(5);
room.Playlist.Add(new PlaylistItem(importedBeatmap.Beatmaps.First())
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
});
room.Name = "my awesome room";
room.Host = API.LocalUser.Value;
room.RecentParticipants = [room.Host];
room.EndDate = DateTimeOffset.Now.AddMinutes(5);
room.Playlist =
[
new PlaylistItem(importedBeatmap.Beatmaps.First())
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
];
});
AddUntilStep("Progress details are hidden", () => match.ChildrenOfType<RoomLocalUserInfo>().FirstOrDefault()?.Parent!.Alpha == 0);
@ -88,15 +86,18 @@ namespace osu.Game.Tests.Visual.Playlists
{
setupAndCreateRoom(room =>
{
room.Name.Value = "my awesome room";
room.MaxAttempts.Value = 5;
room.Host.Value = API.LocalUser.Value;
room.RecentParticipants.Add(room.Host.Value);
room.EndDate.Value = DateTimeOffset.Now.AddMinutes(5);
room.Playlist.Add(new PlaylistItem(importedBeatmap.Beatmaps.First())
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
});
room.Name = "my awesome room";
room.MaxAttempts = 5;
room.Host = API.LocalUser.Value;
room.RecentParticipants = [room.Host];
room.EndDate = DateTimeOffset.Now.AddMinutes(5);
room.Playlist =
[
new PlaylistItem(importedBeatmap.Beatmaps.First())
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
];
});
AddUntilStep("Progress details are visible", () => match.ChildrenOfType<RoomLocalUserInfo>().FirstOrDefault()?.Parent!.Alpha == 1);
@ -107,21 +108,24 @@ namespace osu.Game.Tests.Visual.Playlists
{
setupAndCreateRoom(room =>
{
room.Name.Value = "my awesome room";
room.Host.Value = API.LocalUser.Value;
room.Playlist.Add(new PlaylistItem(importedBeatmap.Beatmaps.First())
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
});
room.Name = "my awesome room";
room.Host = API.LocalUser.Value;
room.Playlist =
[
new PlaylistItem(importedBeatmap.Beatmaps.First())
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
];
});
AddAssert("first playlist item selected", () => match.SelectedItem.Value == SelectedRoom!.Value.Playlist[0]);
AddAssert("first playlist item selected", () => match.SelectedItem.Value == SelectedRoom.Value!.Playlist[0]);
}
[Test]
public void TestBeatmapUpdatedOnReImport()
{
string realHash = null;
string realHash = null!;
int realOnlineId = 0;
int realOnlineSetId = 0;
@ -139,40 +143,40 @@ namespace osu.Game.Tests.Visual.Playlists
BeatmapInfo =
{
OnlineID = realOnlineId,
Metadata = new BeatmapMetadata(),
BeatmapSet =
{
OnlineID = realOnlineSetId
}
Metadata = new BeatmapMetadata()
},
};
Debug.Assert(modifiedBeatmap.BeatmapInfo.BeatmapSet != null);
modifiedBeatmap.BeatmapInfo.BeatmapSet!.OnlineID = realOnlineSetId;
modifiedBeatmap.HitObjects.Clear();
modifiedBeatmap.HitObjects.Add(new HitCircle { StartTime = 5000 });
Debug.Assert(modifiedBeatmap.BeatmapInfo.BeatmapSet != null);
manager.Import(modifiedBeatmap.BeatmapInfo.BeatmapSet);
});
// Create the room using the real beatmap values.
setupAndCreateRoom(room =>
{
room.Name.Value = "my awesome room";
room.Host.Value = API.LocalUser.Value;
room.Playlist.Add(new PlaylistItem(new BeatmapInfo
{
MD5Hash = realHash,
OnlineID = realOnlineId,
Metadata = new BeatmapMetadata(),
BeatmapSet = new BeatmapSetInfo
room.Name = "my awesome room";
room.Host = API.LocalUser.Value;
room.Playlist =
[
new PlaylistItem(new BeatmapInfo
{
OnlineID = realOnlineSetId,
MD5Hash = realHash,
OnlineID = realOnlineId,
Metadata = new BeatmapMetadata(),
BeatmapSet = new BeatmapSetInfo
{
OnlineID = realOnlineSetId,
}
})
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
}
})
{
RulesetID = new OsuRuleset().RulesetInfo.OnlineID
});
];
});
AddAssert("match has default beatmap", () => match.Beatmap.IsDefault);
@ -181,17 +185,11 @@ namespace osu.Game.Tests.Visual.Playlists
{
var originalBeatmap = new TestBeatmap(new OsuRuleset().RulesetInfo)
{
BeatmapInfo =
{
OnlineID = realOnlineId,
BeatmapSet =
{
OnlineID = realOnlineSetId
}
},
BeatmapInfo = { OnlineID = realOnlineId },
};
Debug.Assert(originalBeatmap.BeatmapInfo.BeatmapSet != null);
originalBeatmap.BeatmapInfo.BeatmapSet.OnlineID = realOnlineSetId;
manager.Import(originalBeatmap.BeatmapInfo.BeatmapSet);
});
@ -201,7 +199,7 @@ namespace osu.Game.Tests.Visual.Playlists
private void setupAndCreateRoom(Action<Room> room)
{
AddStep("setup room", () => room(SelectedRoom!.Value));
AddStep("setup room", () => room(SelectedRoom.Value!));
AddStep("click create button", () =>
{
@ -215,19 +213,17 @@ namespace osu.Game.Tests.Visual.Playlists
var beatmap = CreateBeatmap(new OsuRuleset().RulesetInfo);
Debug.Assert(beatmap.BeatmapInfo.BeatmapSet != null);
importedBeatmap = manager.Import(beatmap.BeatmapInfo.BeatmapSet)?.Value.Detach();
importedBeatmap = manager.Import(beatmap.BeatmapInfo.BeatmapSet)!.Value.Detach();
});
private partial class TestPlaylistsRoomSubScreen : PlaylistsRoomSubScreen
{
public new Bindable<PlaylistItem> SelectedItem => base.SelectedItem;
public new Bindable<PlaylistItem?> SelectedItem => base.SelectedItem;
public new Bindable<WorkingBeatmap> Beatmap => base.Beatmap;
[Resolved(canBeNull: true)]
[CanBeNull]
private IDialogOverlay dialogOverlay { get; set; }
private IDialogOverlay? dialogOverlay { get; set; }
public TestPlaylistsRoomSubScreen(Room room)
: base(room)

View File

@ -0,0 +1,41 @@
// 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.Screens;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms;
using osu.Game.Online.Rooms.RoomStatuses;
using osu.Game.Screens.OnlinePlay.Playlists;
using osu.Game.Tests.Visual.OnlinePlay;
namespace osu.Game.Tests.Visual.Playlists
{
public partial class TestScenePlaylistsRoomSubScreen : OnlinePlayTestScene
{
protected new TestRoomManager RoomManager => (TestRoomManager)base.RoomManager;
[Test]
public void TestStatusUpdateOnEnter()
{
Room room = null!;
PlaylistsRoomSubScreen roomScreen = null!;
AddStep("create room", () =>
{
RoomManager.AddRoom(room = new Room
{
Name = @"Test Room",
Host = new APIUser { Username = @"Host" },
Category = RoomCategory.Normal,
EndDate = DateTimeOffset.Now.AddMinutes(-1)
});
});
AddStep("push screen", () => LoadScreen(roomScreen = new PlaylistsRoomSubScreen(room)));
AddUntilStep("wait for screen load", () => roomScreen.IsCurrentScreen());
AddAssert("status is still ended", () => roomScreen.Room.Status, Is.TypeOf<RoomStatusEnded>);
}
}
}

View File

@ -73,10 +73,10 @@ namespace osu.Game.Tests.Visual.UserInterface
});
});
[TestCase(BeatmapAttribute.CircleSize, "Circle Size: 1.00")]
[TestCase(BeatmapAttribute.HPDrain, "HP Drain: 2.00")]
[TestCase(BeatmapAttribute.Accuracy, "Accuracy: 3.00")]
[TestCase(BeatmapAttribute.ApproachRate, "Approach Rate: 4.00")]
[TestCase(BeatmapAttribute.CircleSize, "Circle Size: 1")]
[TestCase(BeatmapAttribute.HPDrain, "HP Drain: 2")]
[TestCase(BeatmapAttribute.Accuracy, "Accuracy: 3")]
[TestCase(BeatmapAttribute.ApproachRate, "Approach Rate: 4")]
[TestCase(BeatmapAttribute.Title, "Title: _Title")]
[TestCase(BeatmapAttribute.Artist, "Artist: _Artist")]
[TestCase(BeatmapAttribute.Creator, "Creator: _Creator")]
@ -121,15 +121,15 @@ namespace osu.Game.Tests.Visual.UserInterface
Difficulty =
{
ApproachRate = 10,
CircleSize = 9
CircleSize = 9.5f
}
}
}));
test(BeatmapAttribute.BPM, new OsuModDoubleTime(), "BPM: 100.00", "BPM: 150.00");
test(BeatmapAttribute.BPM, new OsuModDoubleTime(), "BPM: 100", "BPM: 150");
test(BeatmapAttribute.Length, new OsuModDoubleTime(), "Length: 00:30", "Length: 00:20");
test(BeatmapAttribute.ApproachRate, new OsuModDoubleTime(), "Approach Rate: 10.00", "Approach Rate: 11.00");
test(BeatmapAttribute.CircleSize, new OsuModHardRock(), "Circle Size: 9.00", "Circle Size: 10.00");
test(BeatmapAttribute.ApproachRate, new OsuModDoubleTime(), "Approach Rate: 10", "Approach Rate: 11");
test(BeatmapAttribute.CircleSize, new OsuModHardRock(), "Circle Size: 9.5", "Circle Size: 10");
void test(BeatmapAttribute attribute, Mod mod, string before, string after)
{

View File

@ -53,13 +53,13 @@ namespace osu.Game.Tests.Visual.UserInterface
beatmap.OnlineID = 1001;
getRoomRequest.TriggerSuccess(new Room
{
RoomID = { Value = 1234 },
RoomID = 1234,
Playlist =
{
[
new PlaylistItem(beatmap)
},
StartDate = { Value = DateTimeOffset.Now.AddMinutes(-5) },
EndDate = { Value = DateTimeOffset.Now.AddSeconds(30) }
],
StartDate = DateTimeOffset.Now.AddMinutes(-5),
EndDate = DateTimeOffset.Now.AddSeconds(30)
});
return true;
@ -131,13 +131,13 @@ namespace osu.Game.Tests.Visual.UserInterface
beatmap.OnlineID = 1001;
getRoomRequest.TriggerSuccess(new Room
{
RoomID = { Value = 1234 },
RoomID = 1234,
Playlist =
{
[
new PlaylistItem(beatmap)
},
StartDate = { Value = DateTimeOffset.Now.AddMinutes(-50) },
EndDate = { Value = DateTimeOffset.Now.AddSeconds(30) }
],
StartDate = DateTimeOffset.Now.AddMinutes(-50),
EndDate = DateTimeOffset.Now.AddSeconds(30)
});
return true;

Some files were not shown because too many files have changed in this diff Show More