1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 10:43:04 +08:00

Merge branch 'master' into beatmap-background-with-storyboard-stopping

This commit is contained in:
Bartłomiej Dach 2022-01-11 21:39:49 +01:00
commit 970e0cc85a
No known key found for this signature in database
GPG Key ID: BCECCD4FA41F6497
225 changed files with 2420 additions and 1076 deletions

View File

@ -13,3 +13,5 @@ M:System.Enum.HasFlag(System.Enum);Use osu.Framework.Extensions.EnumExtensions.H
M:Realms.IRealmCollection`1.SubscribeForNotifications`1(Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IRealmCollection<T>,NotificationCallbackDelegate<T>) instead.
M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Linq.IQueryable{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IQueryable<T>,NotificationCallbackDelegate<T>) instead.
M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Collections.Generic.IList{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IList<T>,NotificationCallbackDelegate<T>) instead.
M:System.Threading.Tasks.Task.Wait();Don't use Task.Wait. Use Task.WaitSafely() to ensure we avoid deadlocks.
P:System.Threading.Tasks.Task`1.Result;Don't use Task.Result. Use Task.GetResultSafely() to ensure we avoid deadlocks.

View File

@ -51,8 +51,8 @@
<Reference Include="Java.Interop" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1215.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.1225.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.109.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.111.0" />
</ItemGroup>
<ItemGroup Label="Transitive Dependencies">
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->

View File

@ -76,7 +76,7 @@ namespace osu.Desktop.Security
private void load(OsuColour colours, NotificationOverlay notificationOverlay)
{
Icon = FontAwesome.Solid.ShieldAlt;
IconBackgound.Colour = colours.YellowDark;
IconBackground.Colour = colours.YellowDark;
}
}
}

View File

@ -14,7 +14,6 @@ using osu.Game.Tests.Beatmaps;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
[Timeout(10000)]
public class CatchBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
{
protected override string ResourceAssembly => "osu.Game.Rulesets.Catch";

View File

@ -72,7 +72,7 @@ namespace osu.Game.Rulesets.Catch.Tests
}
[Test]
public void TestJuicestream()
public void TestJuiceStream()
{
AddStep("hit juicestream", () => spawnJuiceStream(true));
AddUntilStep("wait for completion", () => playfieldIsEmpty);

View File

@ -37,20 +37,20 @@ namespace osu.Game.Rulesets.Catch.Tests
AddStep("show hyperdash droplet", () => SetContents(_ => createDrawableDroplet(true)));
}
private Drawable createDrawableFruit(int indexInBeatmap, bool hyperdash = false) =>
private Drawable createDrawableFruit(int indexInBeatmap, bool hyperDash = false) =>
new TestDrawableCatchHitObjectSpecimen(new DrawableFruit(new Fruit
{
IndexInBeatmap = indexInBeatmap,
HyperDashBindable = { Value = hyperdash }
HyperDashBindable = { Value = hyperDash }
}));
private Drawable createDrawableBanana() =>
new TestDrawableCatchHitObjectSpecimen(new DrawableBanana(new Banana()));
private Drawable createDrawableDroplet(bool hyperdash = false) =>
private Drawable createDrawableDroplet(bool hyperDash = false) =>
new TestDrawableCatchHitObjectSpecimen(new DrawableDroplet(new Droplet
{
HyperDashBindable = { Value = hyperdash }
HyperDashBindable = { Value = hyperDash }
}));
private Drawable createDrawableTinyDroplet() => new TestDrawableCatchHitObjectSpecimen(new DrawableTinyDroplet(new TinyDroplet()));

View File

@ -52,16 +52,25 @@ namespace osu.Game.Rulesets.Catch.Edit
return true;
}
public override bool HandleFlip(Direction direction)
public override bool HandleFlip(Direction direction, bool flipOverOrigin)
{
if (SelectedItems.Count == 0)
return false;
// This could be implemented in the future if there's a requirement for it.
if (direction == Direction.Vertical)
return false;
var selectionRange = CatchHitObjectUtils.GetPositionRange(SelectedItems);
bool changed = false;
EditorBeatmap.PerformOnSelection(h =>
{
if (h is CatchHitObject catchObject)
changed |= handleFlip(selectionRange, catchObject);
changed |= handleFlip(selectionRange, catchObject, flipOverOrigin);
});
return changed;
}
@ -116,7 +125,7 @@ namespace osu.Game.Rulesets.Catch.Edit
return Math.Clamp(deltaX, lowerBound, upperBound);
}
private bool handleFlip(PositionRange selectionRange, CatchHitObject hitObject)
private bool handleFlip(PositionRange selectionRange, CatchHitObject hitObject, bool flipOverOrigin)
{
switch (hitObject)
{
@ -124,7 +133,7 @@ namespace osu.Game.Rulesets.Catch.Edit
return false;
case JuiceStream juiceStream:
juiceStream.OriginalX = selectionRange.GetFlippedPosition(juiceStream.OriginalX);
juiceStream.OriginalX = getFlippedPosition(juiceStream.OriginalX);
foreach (var point in juiceStream.Path.ControlPoints)
point.Position *= new Vector2(-1, 1);
@ -133,9 +142,11 @@ namespace osu.Game.Rulesets.Catch.Edit
return true;
default:
hitObject.OriginalX = selectionRange.GetFlippedPosition(hitObject.OriginalX);
hitObject.OriginalX = getFlippedPosition(hitObject.OriginalX);
return true;
}
float getFlippedPosition(float original) => flipOverOrigin ? CatchPlayfield.WIDTH - original : selectionRange.GetFlippedPosition(original);
}
}
}

View File

@ -90,9 +90,9 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default
.ResizeTo(largeFaint.Size * new Vector2(5, 1), duration, Easing.OutQuint)
.FadeOut(duration * 2);
const float angle_variangle = 15; // should be less than 45
directionalGlow1.Rotation = StatelessRNG.NextSingle(-angle_variangle, angle_variangle, randomSeed, 4);
directionalGlow2.Rotation = StatelessRNG.NextSingle(-angle_variangle, angle_variangle, randomSeed, 5);
const float angle_variance = 15; // should be less than 45
directionalGlow1.Rotation = StatelessRNG.NextSingle(-angle_variance, angle_variance, randomSeed, 4);
directionalGlow2.Rotation = StatelessRNG.NextSingle(-angle_variance, angle_variance, randomSeed, 5);
this.FadeInFromZero(50).Then().FadeOut(duration, Easing.Out);
}

View File

@ -14,7 +14,6 @@ using osu.Game.Tests.Beatmaps;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
[Timeout(10000)]
public class ManiaBeatmapConversionTest : BeatmapConversionTest<ManiaConvertMapping, ConvertValue>
{
protected override string ResourceAssembly => "osu.Game.Rulesets.Mania";

View File

@ -24,13 +24,13 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
public TestSceneHitExplosion()
{
int runcount = 0;
int runCount = 0;
AddRepeatStep("explode", () =>
{
runcount++;
runCount++;
if (runcount % 15 > 12)
if (runCount % 15 > 12)
return;
int poolIndex = 0;
@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
{
c.Add(hitExplosionPools[poolIndex].Get(e =>
{
e.Apply(new JudgementResult(new HitObject(), runcount % 6 == 0 ? new HoldNoteTickJudgement() : new ManiaJudgement()));
e.Apply(new JudgementResult(new HitObject(), runCount % 6 == 0 ? new HoldNoteTickJudgement() : new ManiaJudgement()));
e.Anchor = Anchor.Centre;
e.Origin = Anchor.Centre;

View File

@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
public override IEnumerable<BeatmapStatistic> GetStatistics()
{
int notes = HitObjects.Count(s => s is Note);
int holdnotes = HitObjects.Count(s => s is HoldNote);
int holdNotes = HitObjects.Count(s => s is HoldNote);
return new[]
{
@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
{
Name = @"Hold Note Count",
CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders),
Content = holdnotes.ToString(),
Content = holdNotes.ToString(),
},
};
}

View File

@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
/// Mapping of <see cref="HitResult"/> to their corresponding
/// <see cref="LegacyManiaSkinConfigurationLookups"/> value.
/// </summary>
private static readonly IReadOnlyDictionary<HitResult, LegacyManiaSkinConfigurationLookups> hitresult_mapping
private static readonly IReadOnlyDictionary<HitResult, LegacyManiaSkinConfigurationLookups> hit_result_mapping
= new Dictionary<HitResult, LegacyManiaSkinConfigurationLookups>
{
{ HitResult.Perfect, LegacyManiaSkinConfigurationLookups.Hit300g },
@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
/// Mapping of <see cref="HitResult"/> to their corresponding
/// default filenames.
/// </summary>
private static readonly IReadOnlyDictionary<HitResult, string> default_hitresult_skin_filenames
private static readonly IReadOnlyDictionary<HitResult, string> default_hit_result_skin_filenames
= new Dictionary<HitResult, string>
{
{ HitResult.Perfect, "mania-hit300g" },
@ -126,11 +126,11 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
private Drawable getResult(HitResult result)
{
if (!hitresult_mapping.ContainsKey(result))
if (!hit_result_mapping.ContainsKey(result))
return null;
string filename = this.GetManiaSkinConfig<string>(hitresult_mapping[result])?.Value
?? default_hitresult_skin_filenames[result];
string filename = this.GetManiaSkinConfig<string>(hit_result_mapping[result])?.Value
?? default_hit_result_skin_filenames[result];
var animation = this.GetAnimation(filename, true, true);
return animation == null ? null : new LegacyManiaJudgementPiece(result, animation);

View File

@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mania.UI
[BackgroundDependencyLoader]
private void load(IScrollingInfo scrollingInfo)
{
const float angle_variangle = 15; // should be less than 45
const float angle_variance = 15; // should be less than 45
const float roundness = 80;
const float initial_height = 10;
@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Mania.UI
Masking = true,
Size = new Vector2(0.01f, initial_height),
Blending = BlendingParameters.Additive,
Rotation = RNG.NextSingle(-angle_variangle, angle_variangle),
Rotation = RNG.NextSingle(-angle_variance, angle_variance),
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
@ -107,7 +107,7 @@ namespace osu.Game.Rulesets.Mania.UI
Masking = true,
Size = new Vector2(0.01f, initial_height),
Blending = BlendingParameters.Additive,
Rotation = RNG.NextSingle(-angle_variangle, angle_variangle),
Rotation = RNG.NextSingle(-angle_variance, angle_variance),
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,

View File

@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Mania.UI
public override bool Remove(DrawableHitObject h) => getStageByColumn(((ManiaHitObject)h.HitObject).Column).Remove(h);
public void Add(BarLine barline) => stages.ForEach(s => s.Add(barline));
public void Add(BarLine barLine) => stages.ForEach(s => s.Add(barLine));
/// <summary>
/// Retrieves a column from a screen-space position.

View File

@ -147,7 +147,7 @@ namespace osu.Game.Rulesets.Mania.UI
public override bool Remove(DrawableHitObject h) => Columns.ElementAt(((ManiaHitObject)h.HitObject).Column - firstColumnIndex).Remove(h);
public void Add(BarLine barline) => base.Add(new DrawableBarLine(barline));
public void Add(BarLine barLine) => base.Add(new DrawableBarLine(barLine));
internal void OnNewResult(DrawableHitObject judgedObject, JudgementResult result)
{

View File

@ -12,7 +12,6 @@ using osu.Game.Tests.Beatmaps;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
[Timeout(10000)]
public class OsuBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
{
protected override string ResourceAssembly => "osu.Game.Rulesets.Osu";

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -70,8 +70,15 @@ namespace osu.Game.Rulesets.Osu.Difficulty
SliderFactor = values[ATTRIB_ID_SLIDER_FACTOR];
}
// Used implicitly by Newtonsoft.Json to not serialize flashlight property in some cases.
#region Newtonsoft.Json implicit ShouldSerialize() methods
// The properties in this region are used implicitly by Newtonsoft.Json to not serialise certain fields in some cases.
// They rely on being named exactly the same as the corresponding fields (casing included) and as such should NOT be renamed
// unless the fields are also renamed.
[UsedImplicitly]
public bool ShouldSerializeFlashlightRating() => Mods.Any(m => m is ModFlashlight);
#endregion
}
}

View File

@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (mods.Any(m => m is OsuModNoFail))
multiplier *= Math.Max(0.90, 1.0 - 0.02 * effectiveMissCount);
if (mods.Any(m => m is OsuModSpunOut))
if (mods.Any(m => m is OsuModSpunOut) && totalHits > 0)
multiplier *= 1.0 - Math.Pow((double)Attributes.SpinnerCount / totalHits, 0.85);
if (mods.Any(h => h is OsuModRelax))

View File

@ -250,7 +250,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
switch (pathType)
{
case PathType.Catmull:
return colours.Seafoam;
return colours.SeaFoam;
case PathType.Bezier:
return colours.Pink;

View File

@ -10,6 +10,7 @@ using osu.Game.Extensions;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.UI;
using osu.Game.Screens.Edit.Compose.Components;
using osuTK;
@ -84,18 +85,28 @@ namespace osu.Game.Rulesets.Osu.Edit
return true;
}
public override bool HandleFlip(Direction direction)
public override bool HandleFlip(Direction direction, bool flipOverOrigin)
{
var hitObjects = selectedMovableObjects;
var selectedObjectsQuad = getSurroundingQuad(hitObjects);
var flipQuad = flipOverOrigin ? new Quad(0, 0, OsuPlayfield.BASE_SIZE.X, OsuPlayfield.BASE_SIZE.Y) : getSurroundingQuad(hitObjects);
bool didFlip = false;
foreach (var h in hitObjects)
{
h.Position = GetFlippedPosition(direction, selectedObjectsQuad, h.Position);
var flippedPosition = GetFlippedPosition(direction, flipQuad, h.Position);
if (!Precision.AlmostEquals(flippedPosition, h.Position))
{
h.Position = flippedPosition;
didFlip = true;
}
if (h is Slider slider)
{
didFlip = true;
foreach (var point in slider.Path.ControlPoints)
{
point.Position = new Vector2(
@ -106,7 +117,7 @@ namespace osu.Game.Rulesets.Osu.Edit
}
}
return true;
return didFlip;
}
public override bool HandleScale(Vector2 scale, Anchor reference)

View File

@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Mods
{
public override string Name => "Spun Out";
public override string Acronym => "SO";
public override IconUsage? Icon => OsuIcon.ModSpunout;
public override IconUsage? Icon => OsuIcon.ModSpunOut;
public override ModType Type => ModType.Automation;
public override string Description => @"Spinners will be automatically completed.";
public override double ScoreMultiplier => 0.9;

View File

@ -0,0 +1,52 @@
// 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 osu.Framework.Audio.Track;
using osu.Framework.Graphics;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics.Containers;
#nullable enable
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{
internal class KiaiFlashingDrawable : BeatSyncedContainer
{
private readonly Drawable flashingDrawable;
private const float flash_opacity = 0.3f;
public KiaiFlashingDrawable(Func<Drawable?> creationFunc)
{
AutoSizeAxes = Axes.Both;
Children = new[]
{
(creationFunc.Invoke() ?? Empty()).With(d =>
{
d.Anchor = Anchor.Centre;
d.Origin = Anchor.Centre;
}),
flashingDrawable = (creationFunc.Invoke() ?? Empty()).With(d =>
{
d.Anchor = Anchor.Centre;
d.Origin = Anchor.Centre;
d.Alpha = 0;
d.Blending = BlendingParameters.Additive;
})
};
}
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
{
if (!effectPoint.KiaiMode)
return;
flashingDrawable
.FadeTo(flash_opacity)
.Then()
.FadeOut(timingPoint.BeatLength * 0.75f);
}
}
}

View File

@ -1,61 +0,0 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Audio.Track;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics.Containers;
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{
internal class KiaiFlashingSprite : BeatSyncedContainer
{
private readonly Sprite mainSprite;
private readonly Sprite flashingSprite;
public Texture Texture
{
set
{
mainSprite.Texture = value;
flashingSprite.Texture = value;
}
}
private const float flash_opacity = 0.3f;
public KiaiFlashingSprite()
{
AutoSizeAxes = Axes.Both;
Children = new Drawable[]
{
mainSprite = new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
flashingSprite = new Sprite
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Alpha = 0,
Blending = BlendingParameters.Additive,
}
};
}
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
{
if (!effectPoint.KiaiMode)
return;
flashingSprite
.FadeTo(flash_opacity)
.Then()
.FadeOut(timingPoint.BeatLength * 0.75f);
}
}
}

View File

@ -5,6 +5,7 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
@ -68,13 +69,11 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
// at this point, any further texture fetches should be correctly using the priority source if the base texture was retrieved using it.
// the flow above handles the case where a sliderendcircle.png is retrieved from the skin, but sliderendcircleoverlay.png doesn't exist.
// expected behaviour in this scenario is not showing the overlay, rather than using hitcircleoverlay.png (potentially from the default/fall-through skin).
Texture overlayTexture = getTextureWithFallback("overlay");
InternalChildren = new[]
{
hitCircleSprite = new KiaiFlashingSprite
hitCircleSprite = new KiaiFlashingDrawable(() => new Sprite { Texture = baseTexture })
{
Texture = baseTexture,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
@ -82,9 +81,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Child = hitCircleOverlay = new KiaiFlashingSprite
Child = hitCircleOverlay = new KiaiFlashingDrawable(() => getAnimationWithFallback(@"overlay", 1000 / 2d))
{
Texture = overlayTexture,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
@ -126,6 +124,21 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
return tex ?? skin.GetTexture($"hitcircle{name}");
}
Drawable getAnimationWithFallback(string name, double frameLength)
{
Drawable animation = null;
if (!string.IsNullOrEmpty(priorityLookup))
{
animation = skin.GetAnimation($"{priorityLookup}{name}", true, true, frameLength: frameLength);
if (!allowFallback)
return animation;
}
return animation ?? skin.GetAnimation($"hitcircle{name}", true, true, frameLength: frameLength);
}
}
protected override void LoadComplete()

View File

@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
private BarLine createBarLineAtCurrentTime(bool major = false)
{
var barline = new BarLine
var barLine = new BarLine
{
Major = major,
StartTime = Time.Current + 2000,
@ -92,9 +92,9 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
var cpi = new ControlPointInfo();
cpi.Add(0, new TimingControlPoint { BeatLength = 500 });
barline.ApplyDefaults(cpi, new BeatmapDifficulty());
barLine.ApplyDefaults(cpi, new BeatmapDifficulty());
return barline;
return barLine;
}
}
}

View File

@ -12,7 +12,6 @@ using osu.Game.Tests.Beatmaps;
namespace osu.Game.Rulesets.Taiko.Tests
{
[TestFixture]
[Timeout(10000)]
public class TaikoBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
{
protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko";

View File

@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
public override IEnumerable<BeatmapStatistic> GetStatistics()
{
int hits = HitObjects.Count(s => s is Hit);
int drumrolls = HitObjects.Count(s => s is DrumRoll);
int drumRolls = HitObjects.Count(s => s is DrumRoll);
int swells = HitObjects.Count(s => s is Swell);
return new[]
@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
{
Name = @"Drumroll Count",
CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Sliders),
Content = drumrolls.ToString(),
Content = drumRolls.ToString(),
},
new BeatmapStatistic
{

View File

@ -95,7 +95,6 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.That(decodedAfterEncode, Is.Not.Null);
Assert.That(decodedAfterEncode.ScoreInfo.User.Username, Is.EqualTo(scoreInfo.User.Username));
Assert.That(decodedAfterEncode.ScoreInfo.BeatmapInfoID, Is.EqualTo(scoreInfo.BeatmapInfoID));
Assert.That(decodedAfterEncode.ScoreInfo.Ruleset, Is.EqualTo(scoreInfo.Ruleset));
Assert.That(decodedAfterEncode.ScoreInfo.TotalScore, Is.EqualTo(scoreInfo.TotalScore));
Assert.That(decodedAfterEncode.ScoreInfo.MaxCombo, Is.EqualTo(scoreInfo.MaxCombo));

View File

@ -93,7 +93,7 @@ namespace osu.Game.Tests.Beatmaps.IO
using (var stream = File.OpenRead(tempPath))
{
importedSet = await manager.Import(new ImportTask(stream, Path.GetFileName(tempPath)));
ensureLoaded(osu);
await ensureLoaded(osu);
}
Assert.IsTrue(File.Exists(tempPath), "Stream source file somehow went missing");
@ -171,7 +171,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu);
await ensureLoaded(osu);
// but contents doesn't, so existing should still be used.
Assert.IsTrue(imported.ID == importedSecondTime.Value.ID);
@ -225,7 +225,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu);
await ensureLoaded(osu);
// check the newly "imported" beatmap is not the original.
Assert.IsTrue(imported.ID != importedSecondTime.Value.ID);
@ -277,7 +277,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu);
await ensureLoaded(osu);
// check the newly "imported" beatmap is not the original.
Assert.IsTrue(imported.ID != importedSecondTime.Value.ID);
@ -328,7 +328,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu);
await ensureLoaded(osu);
// check the newly "imported" beatmap is not the original.
Assert.IsTrue(imported.ID != importedSecondTime.Value.ID);
@ -637,7 +637,7 @@ namespace osu.Game.Tests.Beatmaps.IO
if (!importer.ImportAsync(temp).Wait(10000))
Assert.Fail(@"IPC took too long to send");
ensureLoaded(osu);
ensureLoaded(osu).WaitSafely();
waitForOrAssert(() => !File.Exists(temp), "Temporary still exists after IPC import", 5000);
}
@ -659,7 +659,7 @@ namespace osu.Game.Tests.Beatmaps.IO
string temp = TestResources.GetTestBeatmapForImport();
using (File.OpenRead(temp))
await osu.Dependencies.Get<BeatmapManager>().Import(temp);
ensureLoaded(osu);
await ensureLoaded(osu);
File.Delete(temp);
Assert.IsFalse(File.Exists(temp), "We likely held a read lock on the file when we shouldn't");
}
@ -698,7 +698,7 @@ namespace osu.Game.Tests.Beatmaps.IO
await osu.Dependencies.Get<BeatmapManager>().Import(temp);
ensureLoaded(osu);
await ensureLoaded(osu);
}
finally
{
@ -741,7 +741,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var imported = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu);
await ensureLoaded(osu);
Assert.IsFalse(imported.Value.Files.Any(f => f.Filename.Contains("subfolder")), "Files contain common subfolder");
}
@ -794,7 +794,7 @@ namespace osu.Game.Tests.Beatmaps.IO
var imported = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
ensureLoaded(osu);
await ensureLoaded(osu);
Assert.IsFalse(imported.Value.Files.Any(f => f.Filename.Contains("__MACOSX")), "Files contain resource fork folder, which should be ignored");
Assert.IsFalse(imported.Value.Files.Any(f => f.Filename.Contains("actual_data")), "Files contain common subfolder");
@ -812,7 +812,7 @@ namespace osu.Game.Tests.Beatmaps.IO
}
[Test]
public async Task TestUpdateBeatmapInfo()
public void TestUpdateBeatmapInfo()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
{
@ -822,7 +822,8 @@ namespace osu.Game.Tests.Beatmaps.IO
var manager = osu.Dependencies.Get<BeatmapManager>();
string temp = TestResources.GetTestBeatmapForImport();
await osu.Dependencies.Get<BeatmapManager>().Import(temp);
osu.Dependencies.Get<BeatmapManager>().Import(temp).WaitSafely();
// Update via the beatmap, not the beatmap info, to ensure correct linking
BeatmapSetInfo setToUpdate = manager.GetAllUsableBeatmapSets()[0];
@ -842,7 +843,7 @@ namespace osu.Game.Tests.Beatmaps.IO
}
[Test]
public async Task TestUpdateBeatmapFile()
public void TestUpdateBeatmapFile()
{
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
{
@ -852,7 +853,8 @@ namespace osu.Game.Tests.Beatmaps.IO
var manager = osu.Dependencies.Get<BeatmapManager>();
string temp = TestResources.GetTestBeatmapForImport();
await osu.Dependencies.Get<BeatmapManager>().Import(temp);
osu.Dependencies.Get<BeatmapManager>().Import(temp).WaitSafely();
BeatmapSetInfo setToUpdate = manager.GetAllUsableBeatmapSets()[0];
@ -976,35 +978,35 @@ namespace osu.Game.Tests.Beatmaps.IO
}
}
public static async Task<BeatmapSetInfo> LoadQuickOszIntoOsu(OsuGameBase osu)
public static Task<BeatmapSetInfo> LoadQuickOszIntoOsu(OsuGameBase osu) => Task.Factory.StartNew(() =>
{
string temp = TestResources.GetQuickTestBeatmapForImport();
var manager = osu.Dependencies.Get<BeatmapManager>();
var importedSet = await manager.Import(new ImportTask(temp)).ConfigureAwait(false);
var importedSet = manager.Import(new ImportTask(temp)).GetResultSafely();
ensureLoaded(osu);
ensureLoaded(osu).WaitSafely();
waitForOrAssert(() => !File.Exists(temp), "Temporary file still exists after standard import", 5000);
return manager.GetAllUsableBeatmapSets().Find(beatmapSet => beatmapSet.ID == importedSet.Value.ID);
}
}, TaskCreationOptions.LongRunning);
public static async Task<BeatmapSetInfo> LoadOszIntoOsu(OsuGameBase osu, string path = null, bool virtualTrack = false)
public static Task<BeatmapSetInfo> LoadOszIntoOsu(OsuGameBase osu, string path = null, bool virtualTrack = false) => Task.Factory.StartNew(() =>
{
string temp = path ?? TestResources.GetTestBeatmapForImport(virtualTrack);
var manager = osu.Dependencies.Get<BeatmapManager>();
var importedSet = await manager.Import(new ImportTask(temp)).ConfigureAwait(false);
var importedSet = manager.Import(new ImportTask(temp)).GetResultSafely();
ensureLoaded(osu);
ensureLoaded(osu).WaitSafely();
waitForOrAssert(() => !File.Exists(temp), "Temporary file still exists after standard import", 5000);
return manager.GetAllUsableBeatmapSets().Find(beatmapSet => beatmapSet.ID == importedSet.Value.ID);
}
}, TaskCreationOptions.LongRunning);
private void deleteBeatmapSet(BeatmapSetInfo imported, OsuGameBase osu)
{
@ -1053,7 +1055,7 @@ namespace osu.Game.Tests.Beatmaps.IO
Assert.AreEqual(expected, osu.Dependencies.Get<DatabaseContextFactory>().Get().FileInfo.Count(f => f.ReferenceCount == 1));
}
private static void ensureLoaded(OsuGameBase osu, int timeout = 60000)
private static Task ensureLoaded(OsuGameBase osu, int timeout = 60000) => Task.Factory.StartNew(() =>
{
IEnumerable<BeatmapSetInfo> resultSets = null;
var store = osu.Dependencies.Get<BeatmapManager>();
@ -1089,14 +1091,14 @@ namespace osu.Game.Tests.Beatmaps.IO
Assert.IsTrue(beatmap?.HitObjects.Any() == true);
beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 3))?.Beatmap;
Assert.IsTrue(beatmap?.HitObjects.Any() == true);
}
}, TaskCreationOptions.LongRunning);
private static void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
{
Task task = Task.Run(() =>
Task task = Task.Factory.StartNew(() =>
{
while (!result()) Thread.Sleep(200);
});
}, TaskCreationOptions.LongRunning);
Assert.IsTrue(task.Wait(timeout), failureMessage);
}

View File

@ -8,6 +8,7 @@ using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
@ -32,7 +33,7 @@ namespace osu.Game.Tests.Beatmaps
[BackgroundDependencyLoader]
private void load(OsuGameBase osu)
{
importedSet = ImportBeatmapTest.LoadQuickOszIntoOsu(osu).Result;
importedSet = ImportBeatmapTest.LoadQuickOszIntoOsu(osu).GetResultSafely();
}
[SetUpSteps]

View File

@ -9,6 +9,21 @@ namespace osu.Game.Tests.Chat
[TestFixture]
public class MessageFormatterTests
{
private string originalWebsiteRootUrl;
[OneTimeSetUp]
public void OneTimeSetUp()
{
originalWebsiteRootUrl = MessageFormatter.WebsiteRootUrl;
MessageFormatter.WebsiteRootUrl = "dev.ppy.sh";
}
[OneTimeTearDown]
public void OneTimeTearDown()
{
MessageFormatter.WebsiteRootUrl = originalWebsiteRootUrl;
}
[Test]
public void TestBareLink()
{
@ -32,8 +47,6 @@ namespace osu.Game.Tests.Chat
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/discussions/123", "https://dev.ppy.sh/beatmapsets/discussions/123")]
public void TestBeatmapLinks(LinkAction expectedAction, string expectedArg, string link)
{
MessageFormatter.WebsiteRootUrl = "dev.ppy.sh";
Message result = MessageFormatter.FormatMessage(new Message { Content = link });
Assert.AreEqual(result.Content, result.DisplayContent);
@ -47,7 +60,10 @@ namespace osu.Game.Tests.Chat
[Test]
public void TestMultipleComplexLinks()
{
Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a http://test.io/link#fragment. (see https://twitter.com). Also, This string should not be altered. http://example.com/" });
Message result = MessageFormatter.FormatMessage(new Message
{
Content = "This is a http://test.io/link#fragment. (see https://twitter.com). Also, This string should not be altered. http://example.com/"
});
Assert.AreEqual(result.Content, result.DisplayContent);
Assert.AreEqual(3, result.Links.Count);
@ -104,7 +120,7 @@ namespace osu.Game.Tests.Chat
Assert.AreEqual("This is a Wiki Link.", result.DisplayContent);
Assert.AreEqual(1, result.Links.Count);
Assert.AreEqual("https://osu.ppy.sh/wiki/Wiki Link", result.Links[0].Url);
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki Link", result.Links[0].Url);
Assert.AreEqual(10, result.Links[0].Index);
Assert.AreEqual(9, result.Links[0].Length);
}
@ -117,15 +133,15 @@ namespace osu.Game.Tests.Chat
Assert.AreEqual("This is a Wiki Link Wiki:LinkWiki.Link.", result.DisplayContent);
Assert.AreEqual(3, result.Links.Count);
Assert.AreEqual("https://osu.ppy.sh/wiki/Wiki Link", result.Links[0].Url);
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki Link", result.Links[0].Url);
Assert.AreEqual(10, result.Links[0].Index);
Assert.AreEqual(9, result.Links[0].Length);
Assert.AreEqual("https://osu.ppy.sh/wiki/Wiki:Link", result.Links[1].Url);
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki:Link", result.Links[1].Url);
Assert.AreEqual(20, result.Links[1].Index);
Assert.AreEqual(9, result.Links[1].Length);
Assert.AreEqual("https://osu.ppy.sh/wiki/Wiki.Link", result.Links[2].Url);
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki.Link", result.Links[2].Url);
Assert.AreEqual(29, result.Links[2].Index);
Assert.AreEqual(9, result.Links[2].Length);
}
@ -445,12 +461,15 @@ namespace osu.Game.Tests.Chat
[Test]
public void TestLinkComplex()
{
Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a [http://www.simple-test.com simple test] with some [traps] and [[wiki links]]. Don't forget to visit https://osu.ppy.sh (now!)[http://google.com]\uD83D\uDE12" });
Message result = MessageFormatter.FormatMessage(new Message
{
Content = "This is a [http://www.simple-test.com simple test] with some [traps] and [[wiki links]]. Don't forget to visit https://osu.ppy.sh (now!)[http://google.com]\uD83D\uDE12"
});
Assert.AreEqual("This is a simple test with some [traps] and wiki links. Don't forget to visit https://osu.ppy.sh now!\0\0\0", result.DisplayContent);
Assert.AreEqual(5, result.Links.Count);
Link f = result.Links.Find(l => l.Url == "https://osu.ppy.sh/wiki/wiki links");
Link f = result.Links.Find(l => l.Url == "https://dev.ppy.sh/wiki/wiki links");
Assert.That(f, Is.Not.Null);
Assert.AreEqual(44, f.Index);
Assert.AreEqual(10, f.Length);
@ -514,8 +533,6 @@ namespace osu.Game.Tests.Chat
[TestCase("https://dev.ppy.sh/home/changelog/lazer/2021.1012", "lazer/2021.1012")]
public void TestChangelogLinks(string link, string expectedArg)
{
MessageFormatter.WebsiteRootUrl = "dev.ppy.sh";
LinkDetails result = MessageFormatter.GetLinkDetails(link);
Assert.AreEqual(LinkAction.OpenChangelog, result.Action);

View File

@ -6,6 +6,7 @@ using System.IO;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Framework.Testing;
using osu.Game.Tests.Resources;
@ -179,7 +180,7 @@ namespace osu.Game.Tests.Collections.IO
{
// intentionally spin this up on a separate task to avoid disposal deadlocks.
// see https://github.com/EventStore/EventStore/issues/1179
await Task.Run(() => osu.CollectionManager.Import(stream).Wait());
await Task.Factory.StartNew(() => osu.CollectionManager.Import(stream).WaitSafely(), TaskCreationOptions.LongRunning);
}
}
}

View File

@ -6,6 +6,7 @@ using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Testing;
using osu.Game.Database;
using osu.Game.Models;
@ -104,7 +105,7 @@ namespace osu.Game.Tests.Database
liveBeatmap = beatmap.ToLive(realmFactory);
}
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
Debug.Assert(liveBeatmap != null);
@ -115,7 +116,7 @@ namespace osu.Game.Tests.Database
Assert.IsTrue(beatmap.IsValid);
Assert.IsFalse(beatmap.Hidden);
});
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
});
}
@ -133,7 +134,7 @@ namespace osu.Game.Tests.Database
liveBeatmap = beatmap.ToLive(realmFactory);
}
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
Debug.Assert(liveBeatmap != null);
@ -141,7 +142,7 @@ namespace osu.Game.Tests.Database
{
liveBeatmap.PerformWrite(beatmap => { beatmap.Hidden = true; });
liveBeatmap.PerformRead(beatmap => { Assert.IsTrue(beatmap.Hidden); });
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
});
}
@ -175,7 +176,7 @@ namespace osu.Game.Tests.Database
liveBeatmap = beatmap.ToLive(realmFactory);
}
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
Debug.Assert(liveBeatmap != null);
@ -195,7 +196,7 @@ namespace osu.Game.Tests.Database
var __ = liveBeatmap.Value;
});
}
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
});
}
@ -213,7 +214,7 @@ namespace osu.Game.Tests.Database
liveBeatmap = beatmap.ToLive(realmFactory);
}
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
Debug.Assert(liveBeatmap != null);
@ -223,7 +224,7 @@ namespace osu.Game.Tests.Database
{
var unused = liveBeatmap.Value;
});
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
});
}
@ -252,7 +253,7 @@ namespace osu.Game.Tests.Database
liveBeatmap = beatmap.ToLive(realmFactory);
}
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).Wait();
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler).WaitSafely();
Debug.Assert(liveBeatmap != null);

View File

@ -40,80 +40,80 @@ namespace osu.Game.Tests.Editing.Checks
[Test]
public void TestNormalControlPointVolume()
{
var hitcircle = new HitCircle
var hitCircle = new HitCircle
{
StartTime = 0,
Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) }
};
hitcircle.ApplyDefaults(cpi, new BeatmapDifficulty());
hitCircle.ApplyDefaults(cpi, new BeatmapDifficulty());
assertOk(new List<HitObject> { hitcircle });
assertOk(new List<HitObject> { hitCircle });
}
[Test]
public void TestLowControlPointVolume()
{
var hitcircle = new HitCircle
var hitCircle = new HitCircle
{
StartTime = 1000,
Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) }
};
hitcircle.ApplyDefaults(cpi, new BeatmapDifficulty());
hitCircle.ApplyDefaults(cpi, new BeatmapDifficulty());
assertLowVolume(new List<HitObject> { hitcircle });
assertLowVolume(new List<HitObject> { hitCircle });
}
[Test]
public void TestMutedControlPointVolume()
{
var hitcircle = new HitCircle
var hitCircle = new HitCircle
{
StartTime = 2000,
Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) }
};
hitcircle.ApplyDefaults(cpi, new BeatmapDifficulty());
hitCircle.ApplyDefaults(cpi, new BeatmapDifficulty());
assertMuted(new List<HitObject> { hitcircle });
assertMuted(new List<HitObject> { hitCircle });
}
[Test]
public void TestNormalSampleVolume()
{
// The sample volume should take precedence over the control point volume.
var hitcircle = new HitCircle
var hitCircle = new HitCircle
{
StartTime = 2000,
Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: volume_regular) }
};
hitcircle.ApplyDefaults(cpi, new BeatmapDifficulty());
hitCircle.ApplyDefaults(cpi, new BeatmapDifficulty());
assertOk(new List<HitObject> { hitcircle });
assertOk(new List<HitObject> { hitCircle });
}
[Test]
public void TestLowSampleVolume()
{
var hitcircle = new HitCircle
var hitCircle = new HitCircle
{
StartTime = 2000,
Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: volume_low) }
};
hitcircle.ApplyDefaults(cpi, new BeatmapDifficulty());
hitCircle.ApplyDefaults(cpi, new BeatmapDifficulty());
assertLowVolume(new List<HitObject> { hitcircle });
assertLowVolume(new List<HitObject> { hitCircle });
}
[Test]
public void TestMutedSampleVolume()
{
var hitcircle = new HitCircle
var hitCircle = new HitCircle
{
StartTime = 0,
Samples = new List<HitSampleInfo> { new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: volume_muted) }
};
hitcircle.ApplyDefaults(cpi, new BeatmapDifficulty());
hitCircle.ApplyDefaults(cpi, new BeatmapDifficulty());
assertMuted(new List<HitObject> { hitcircle });
assertMuted(new List<HitObject> { hitCircle });
}
[Test]

View File

@ -6,6 +6,7 @@ using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Game.Collections;
using osu.Game.Tests.Resources;
@ -58,7 +59,7 @@ namespace osu.Game.Tests
{
// Beatmap must be imported before the collection manager is loaded.
if (withBeatmap)
BeatmapManager.Import(TestResources.GetTestBeatmapForImport()).Wait();
BeatmapManager.Import(TestResources.GetTestBeatmapForImport()).WaitSafely();
AddInternal(CollectionManager = new CollectionManager(Storage));
}

View File

@ -34,20 +34,20 @@ namespace osu.Game.Tests.Mods
var mod3 = new OsuModDoubleTime { SpeedChange = { Value = 1.26 } };
var doubleConvertedMod1 = new APIMod(mod1).ToMod(ruleset);
var doulbeConvertedMod2 = new APIMod(mod2).ToMod(ruleset);
var doulbeConvertedMod3 = new APIMod(mod3).ToMod(ruleset);
var doubleConvertedMod2 = new APIMod(mod2).ToMod(ruleset);
var doubleConvertedMod3 = new APIMod(mod3).ToMod(ruleset);
Assert.That(mod1, Is.Not.EqualTo(mod2));
Assert.That(doubleConvertedMod1, Is.Not.EqualTo(doulbeConvertedMod2));
Assert.That(doubleConvertedMod1, Is.Not.EqualTo(doubleConvertedMod2));
Assert.That(mod2, Is.EqualTo(mod2));
Assert.That(doulbeConvertedMod2, Is.EqualTo(doulbeConvertedMod2));
Assert.That(doubleConvertedMod2, Is.EqualTo(doubleConvertedMod2));
Assert.That(mod2, Is.EqualTo(mod3));
Assert.That(doulbeConvertedMod2, Is.EqualTo(doulbeConvertedMod3));
Assert.That(doubleConvertedMod2, Is.EqualTo(doubleConvertedMod3));
Assert.That(mod3, Is.EqualTo(mod2));
Assert.That(doulbeConvertedMod3, Is.EqualTo(doulbeConvertedMod2));
Assert.That(doubleConvertedMod3, Is.EqualTo(doubleConvertedMod2));
}
}
}

View File

@ -16,7 +16,8 @@ namespace osu.Game.Tests.NonVisual.Filtering
{
private BeatmapInfo getExampleBeatmap() => new BeatmapInfo
{
Ruleset = new RulesetInfo { OnlineID = 5 },
Ruleset = new RulesetInfo { OnlineID = 0 },
RulesetID = 0,
StarRating = 4.0d,
BaseDifficulty = new BeatmapDifficulty
{

View File

@ -4,6 +4,7 @@
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Game.Utils;
namespace osu.Game.Tests.NonVisual
@ -42,9 +43,9 @@ namespace osu.Game.Tests.NonVisual
await Task.WhenAll(task1.task, task2.task, task3.task);
Assert.That(task1.task.Result, Is.EqualTo(1));
Assert.That(task2.task.Result, Is.EqualTo(2));
Assert.That(task3.task.Result, Is.EqualTo(3));
Assert.That(task1.task.GetResultSafely(), Is.EqualTo(1));
Assert.That(task2.task.GetResultSafely(), Is.EqualTo(2));
Assert.That(task3.task.GetResultSafely(), Is.EqualTo(3));
}
[Test]
@ -68,9 +69,9 @@ namespace osu.Game.Tests.NonVisual
// Wait on both tasks.
await Task.WhenAll(task1.task, task3.task);
Assert.That(task1.task.Result, Is.EqualTo(1));
Assert.That(task1.task.GetResultSafely(), Is.EqualTo(1));
Assert.That(task2.task.IsCompleted, Is.False);
Assert.That(task3.task.Result, Is.EqualTo(2));
Assert.That(task3.task.GetResultSafely(), Is.EqualTo(2));
}
[Test]

View File

@ -39,7 +39,7 @@ namespace osu.Game.Tests.Online
}
[Test]
public void TestSerialiseUnionFailsWithSingalR()
public void TestSerialiseUnionFailsWithSignalR()
{
var state = new TeamVersusUserState();

View File

@ -100,7 +100,7 @@ namespace osu.Game.Tests.Online
public void TestTrackerRespectsSoftDeleting()
{
AddStep("allow importing", () => beatmaps.AllowImport.SetResult(true));
AddStep("import beatmap", () => beatmaps.Import(testBeatmapFile).Wait());
AddStep("import beatmap", () => beatmaps.Import(testBeatmapFile).WaitSafely());
addAvailabilityCheckStep("state locally available", BeatmapAvailability.LocallyAvailable);
AddStep("delete beatmap", () => beatmaps.Delete(beatmaps.QueryBeatmapSet(b => b.OnlineID == testBeatmapSet.OnlineID)));
@ -114,12 +114,12 @@ namespace osu.Game.Tests.Online
public void TestTrackerRespectsChecksum()
{
AddStep("allow importing", () => beatmaps.AllowImport.SetResult(true));
AddStep("import beatmap", () => beatmaps.Import(testBeatmapFile).Wait());
AddStep("import beatmap", () => beatmaps.Import(testBeatmapFile).WaitSafely());
addAvailabilityCheckStep("initially locally available", BeatmapAvailability.LocallyAvailable);
AddStep("import altered beatmap", () =>
{
beatmaps.Import(TestResources.GetTestBeatmapForImport(true)).Wait();
beatmaps.Import(TestResources.GetTestBeatmapForImport(true)).WaitSafely();
});
addAvailabilityCheckStep("state not downloaded", BeatmapAvailability.NotDownloaded);
@ -129,7 +129,7 @@ namespace osu.Game.Tests.Online
});
addAvailabilityCheckStep("state not downloaded as well", BeatmapAvailability.NotDownloaded);
AddStep("reimport original beatmap", () => beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait());
AddStep("reimport original beatmap", () => beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely());
addAvailabilityCheckStep("locally available after re-import", BeatmapAvailability.LocallyAvailable);
}

View File

@ -8,6 +8,7 @@ using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Game.Database;
using osu.Game.IO;
@ -187,7 +188,7 @@ namespace osu.Game.Tests.Skins.IO
var imported = skinManager.Import(new ImportTask(exportStream, "exported.osk"));
imported.Result.PerformRead(s =>
imported.GetResultSafely().PerformRead(s =>
{
Assert.IsFalse(s.Protected);
Assert.AreNotEqual(originalSkinId, s.ID);
@ -222,7 +223,7 @@ namespace osu.Game.Tests.Skins.IO
var imported = skinManager.Import(new ImportTask(exportStream, "exported.osk"));
imported.Result.PerformRead(s =>
imported.GetResultSafely().PerformRead(s =>
{
Assert.IsFalse(s.Protected);
Assert.AreNotEqual(originalSkinId, s.ID);

View File

@ -4,6 +4,7 @@
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions;
using osu.Framework.Testing;
using osu.Game.Audio;
using osu.Game.Beatmaps;
@ -24,7 +25,7 @@ namespace osu.Game.Tests.Skins
[BackgroundDependencyLoader]
private void load()
{
var imported = beatmaps.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-beatmap.osz"))).Result;
var imported = beatmaps.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-beatmap.osz"))).GetResultSafely();
beatmap = beatmaps.GetWorkingBeatmap(imported.Value.Beatmaps[0]);
beatmap.LoadTrack();
}

View File

@ -3,6 +3,7 @@
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Testing;
using osu.Game.Audio;
using osu.Game.IO.Archives;
@ -23,7 +24,7 @@ namespace osu.Game.Tests.Skins
[BackgroundDependencyLoader]
private void load()
{
var imported = skins.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-skin.osk"))).Result;
var imported = skins.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-skin.osk"))).GetResultSafely();
skin = imported.PerformRead(skinInfo => skins.GetSkin(skinInfo));
}

View File

@ -7,12 +7,14 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Framework.Input.States;
using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Framework.Utils;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Graphics;
@ -49,7 +51,7 @@ namespace osu.Game.Tests.Visual.Background
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
Dependencies.Cache(new OsuConfigManager(LocalStorage));
manager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
manager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
Beatmap.SetDefault();
}
@ -322,7 +324,7 @@ namespace osu.Game.Tests.Visual.Background
public bool IsBackgroundUndimmed() => background.CurrentColour == Color4.White;
public bool IsUserBlurApplied() => background.CurrentBlur == new Vector2((float)BlurLevel.Value * BackgroundScreenBeatmap.USER_BLUR_FACTOR);
public bool IsUserBlurApplied() => Precision.AlmostEquals(background.CurrentBlur, new Vector2((float)BlurLevel.Value * BackgroundScreenBeatmap.USER_BLUR_FACTOR), 0.1f);
public bool IsUserBlurDisabled() => background.CurrentBlur == new Vector2(0);
@ -330,9 +332,9 @@ namespace osu.Game.Tests.Visual.Background
public bool IsBackgroundVisible() => background.CurrentAlpha == 1;
public bool IsBackgroundBlur() => background.CurrentBlur == new Vector2(BACKGROUND_BLUR);
public bool IsBackgroundBlur() => Precision.AlmostEquals(background.CurrentBlur, new Vector2(BACKGROUND_BLUR), 0.1f);
public bool CheckBackgroundBlur(Vector2 expected) => background.CurrentBlur == expected;
public bool CheckBackgroundBlur(Vector2 expected) => Precision.AlmostEquals(background.CurrentBlur, expected, 0.1f);
/// <summary>
/// Make sure every time a screen gets pushed, the background doesn't get replaced

View File

@ -4,6 +4,7 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
@ -38,7 +39,7 @@ namespace osu.Game.Tests.Visual.Collections
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, Audio, Resources, host, Beatmap.Default));
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
base.Content.AddRange(new Drawable[]
{

View File

@ -5,6 +5,7 @@ using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Overlays.Dialog;
@ -32,7 +33,7 @@ namespace osu.Game.Tests.Visual.Editing
public override void SetUpSteps()
{
AddStep("import test beatmap", () => importedBeatmapSet = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).Result);
AddStep("import test beatmap", () => importedBeatmapSet = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).GetResultSafely());
base.SetUpSteps();
}

View File

@ -5,6 +5,7 @@ using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
@ -38,7 +39,7 @@ namespace osu.Game.Tests.Visual.Editing
public override void SetUpSteps()
{
AddStep("import test beatmap", () => importedBeatmapSet = ImportBeatmapTest.LoadOszIntoOsu(game).Result);
AddStep("import test beatmap", () => importedBeatmapSet = ImportBeatmapTest.LoadOszIntoOsu(game).GetResultSafely());
base.SetUpSteps();
}

View File

@ -3,6 +3,7 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Screens;
@ -36,7 +37,9 @@ namespace osu.Game.Tests.Visual.Gameplay
protected override bool HasCustomSteps => true;
protected override TestPlayer CreatePlayer(Ruleset ruleset) => new NonImportingPlayer(false);
protected override TestPlayer CreatePlayer(Ruleset ruleset) => new FakeImportingPlayer(false);
protected new FakeImportingPlayer Player => (FakeImportingPlayer)base.Player;
protected override Ruleset CreatePlayerRuleset() => createCustomRuleset?.Invoke() ?? new OsuRuleset();
@ -54,7 +57,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestNoSubmissionOnResultsWithNoToken()
{
prepareTokenResponse(false);
prepareTestAPI(false);
createPlayerTest();
@ -74,7 +77,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestSubmissionOnResults()
{
prepareTokenResponse(true);
prepareTestAPI(true);
createPlayerTest();
@ -93,7 +96,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestSubmissionForDifferentRuleset()
{
prepareTokenResponse(true);
prepareTestAPI(true);
createPlayerTest(createRuleset: () => new TaikoRuleset());
@ -113,7 +116,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestSubmissionForConvertedBeatmap()
{
prepareTokenResponse(true);
prepareTestAPI(true);
createPlayerTest(createRuleset: () => new ManiaRuleset(), createBeatmap: _ => createTestBeatmap(new OsuRuleset().RulesetInfo));
@ -133,7 +136,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestNoSubmissionOnExitWithNoToken()
{
prepareTokenResponse(false);
prepareTestAPI(false);
createPlayerTest();
@ -150,7 +153,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestNoSubmissionOnEmptyFail()
{
prepareTokenResponse(true);
prepareTestAPI(true);
createPlayerTest(true);
@ -165,7 +168,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestSubmissionOnFail()
{
prepareTokenResponse(true);
prepareTestAPI(true);
createPlayerTest(true);
@ -182,7 +185,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestNoSubmissionOnEmptyExit()
{
prepareTokenResponse(true);
prepareTestAPI(true);
createPlayerTest();
@ -195,7 +198,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestSubmissionOnExit()
{
prepareTokenResponse(true);
prepareTestAPI(true);
createPlayerTest();
@ -207,10 +210,29 @@ namespace osu.Game.Tests.Visual.Gameplay
AddAssert("ensure failing submission", () => Player.SubmittedScore?.ScoreInfo.Passed == false);
}
[Test]
public void TestSubmissionOnExitDuringImport()
{
prepareTestAPI(true);
createPlayerTest();
AddStep("block imports", () => Player.AllowImportCompletion.Wait());
AddUntilStep("wait for token request", () => Player.TokenCreationRequested);
addFakeHit();
AddUntilStep("wait for import to start", () => Player.ScoreImportStarted);
AddStep("exit", () => Player.Exit());
AddStep("allow import to proceed", () => Player.AllowImportCompletion.Release(1));
AddUntilStep("ensure submission", () => Player.SubmittedScore != null && Player.ImportedScore != null);
}
[Test]
public void TestNoSubmissionOnLocalBeatmap()
{
prepareTokenResponse(true);
prepareTestAPI(true);
createPlayerTest(false, r =>
{
@ -231,7 +253,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[TestCase(10)]
public void TestNoSubmissionOnCustomRuleset(int? rulesetId)
{
prepareTokenResponse(true);
prepareTestAPI(true);
createPlayerTest(false, createRuleset: () => new OsuRuleset { RulesetInfo = { OnlineID = rulesetId ?? -1 } });
@ -253,7 +275,7 @@ namespace osu.Game.Tests.Visual.Gameplay
}));
}
private void prepareTokenResponse(bool validToken)
private void prepareTestAPI(bool validToken)
{
AddStep("Prepare test API", () =>
{
@ -267,6 +289,31 @@ namespace osu.Game.Tests.Visual.Gameplay
else
tokenRequest.TriggerFailure(new APIException("something went wrong!", null));
return true;
case SubmitSoloScoreRequest submissionRequest:
if (validToken)
{
var requestScore = submissionRequest.Score;
submissionRequest.TriggerSuccess(new MultiplayerScore
{
ID = 1234,
User = dummyAPI.LocalUser.Value,
Rank = requestScore.Rank,
TotalScore = requestScore.TotalScore,
Accuracy = requestScore.Accuracy,
MaxCombo = requestScore.MaxCombo,
Mods = requestScore.Mods,
Statistics = requestScore.Statistics,
Passed = requestScore.Passed,
EndedAt = DateTimeOffset.Now,
Position = 1
});
return true;
}
break;
}
return false;
@ -288,15 +335,26 @@ namespace osu.Game.Tests.Visual.Gameplay
});
}
private class NonImportingPlayer : TestPlayer
protected class FakeImportingPlayer : TestPlayer
{
public NonImportingPlayer(bool allowPause = true, bool showResults = true, bool pauseOnFocusLost = false)
public bool ScoreImportStarted { get; set; }
public SemaphoreSlim AllowImportCompletion { get; }
public Score ImportedScore { get; private set; }
public FakeImportingPlayer(bool allowPause = true, bool showResults = true, bool pauseOnFocusLost = false)
: base(allowPause, showResults, pauseOnFocusLost)
{
AllowImportCompletion = new SemaphoreSlim(1);
}
protected override Task ImportScore(Score score)
protected override async Task ImportScore(Score score)
{
ScoreImportStarted = true;
await AllowImportCompletion.WaitAsync().ConfigureAwait(false);
ImportedScore = score;
// It was discovered that Score members could sometimes be half-populated.
// In particular, the RulesetID property could be set to 0 even on non-osu! maps.
// We want to test that the state of that property is consistent in this test.
@ -311,8 +369,7 @@ namespace osu.Game.Tests.Visual.Gameplay
// In the above instance, if a ScoreInfo with Ruleset = {mania} and RulesetID = 0 is attached to an EF context,
// RulesetID WILL BE SILENTLY SET TO THE CORRECT VALUE of 3.
//
// For the above reasons, importing is disabled in this test.
return Task.CompletedTask;
// For the above reasons, actual importing is disabled in this test.
}
}
}

View File

@ -9,6 +9,7 @@ using osu.Game.Online.API.Requests.Responses;
using osu.Game.Scoring;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Testing;
using osu.Game.Database;
using osu.Game.Graphics.UserInterface;
@ -135,7 +136,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddUntilStep("state is not downloaded", () => downloadButton.State.Value == DownloadState.NotDownloaded);
AddStep("import score", () => imported = scoreManager.Import(getScoreInfo(true)).Result);
AddStep("import score", () => imported = scoreManager.Import(getScoreInfo(true)).GetResultSafely());
AddUntilStep("state is available", () => downloadButton.State.Value == DownloadState.LocallyAvailable);

View File

@ -4,6 +4,7 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Screens;
using osu.Framework.Testing;
@ -60,7 +61,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddStep("import beatmap", () =>
{
importedBeatmap = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).Result;
importedBeatmap = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).GetResultSafely();
importedBeatmapId = importedBeatmap.Beatmaps.First(b => b.RulesetID == 0).OnlineID ?? -1;
});
}

View File

@ -53,8 +53,8 @@ namespace osu.Game.Tests.Visual.Gameplay
CreateTest(null);
AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value);
AddStep("skip outro", () => InputManager.Key(osuTK.Input.Key.Space));
AddAssert("player is no longer current screen", () => !Player.IsCurrentScreen());
AddUntilStep("wait for score shown", () => Player.IsScoreShown);
AddUntilStep("time less than storyboard duration", () => Player.GameplayClockContainer.GameplayClock.CurrentTime < currentStoryboardDuration);
}
[Test]

View File

@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Database;
@ -33,11 +34,11 @@ namespace osu.Game.Tests.Visual.Menus
Queue<(IWorkingBeatmap working, TrackChangeDirection changeDirection)> trackChangeQueue = null;
// ensure we have at least two beatmaps available to identify the direction the music controller navigated to.
AddRepeatStep("import beatmap", () => Game.BeatmapManager.Import(TestResources.CreateTestBeatmapSetInfo()).Wait(), 5);
AddRepeatStep("import beatmap", () => Game.BeatmapManager.Import(TestResources.CreateTestBeatmapSetInfo()).WaitSafely(), 5);
AddStep("import beatmap with track", () =>
{
var setWithTrack = Game.BeatmapManager.Import(new ImportTask(TestResources.GetTestBeatmapForImport())).Result;
var setWithTrack = Game.BeatmapManager.Import(new ImportTask(TestResources.GetTestBeatmapForImport())).GetResultSafely();
Beatmap.Value = Game.BeatmapManager.GetWorkingBeatmap(setWithTrack.Value.Beatmaps.First());
});

View File

@ -5,6 +5,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Framework.Testing;
@ -56,7 +57,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("import beatmap", () =>
{
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
InitialBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0);
OtherBeatmap = importedSet.Beatmaps.Last(b => b.RulesetID == 0);

View File

@ -1,13 +1,25 @@
// 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 enable
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Online.Multiplayer;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Screens.OnlinePlay.Multiplayer;
using osu.Game.Screens.OnlinePlay.Multiplayer.Match;
using osu.Game.Screens.Play;
using osuTK.Input;
namespace osu.Game.Tests.Visual.Multiplayer
@ -83,16 +95,60 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddUntilStep("selected beatmap is initial beatmap", () => Beatmap.Value.BeatmapInfo.OnlineID == InitialBeatmap.OnlineID);
}
private void addItem(Func<BeatmapInfo> beatmap)
[Test]
public void TestCorrectRulesetSelectedAfterNewItemAdded()
{
addItem(() => OtherBeatmap, new CatchRuleset().RulesetInfo);
AddUntilStep("selected beatmap is initial beatmap", () => Beatmap.Value.BeatmapInfo.OnlineID == InitialBeatmap.OnlineID);
AddUntilStep("wait for idle", () => Client.LocalUser?.State == MultiplayerUserState.Idle);
ClickButtonWhenEnabled<MultiplayerReadyButton>();
AddUntilStep("wait for ready", () => Client.LocalUser?.State == MultiplayerUserState.Ready);
ClickButtonWhenEnabled<MultiplayerReadyButton>();
AddUntilStep("wait for player", () => CurrentScreen is Player player && player.IsLoaded);
AddAssert("ruleset is correct", () => ((Player)CurrentScreen).Ruleset.Value.Equals(new OsuRuleset().RulesetInfo));
AddStep("exit player", () => CurrentScreen.Exit());
}
[Test]
public void TestCorrectModsSelectedAfterNewItemAdded()
{
addItem(() => OtherBeatmap, mods: new Mod[] { new OsuModDoubleTime() });
AddUntilStep("selected beatmap is initial beatmap", () => Beatmap.Value.BeatmapInfo.OnlineID == InitialBeatmap.OnlineID);
AddUntilStep("wait for idle", () => Client.LocalUser?.State == MultiplayerUserState.Idle);
ClickButtonWhenEnabled<MultiplayerReadyButton>();
AddUntilStep("wait for ready", () => Client.LocalUser?.State == MultiplayerUserState.Ready);
ClickButtonWhenEnabled<MultiplayerReadyButton>();
AddUntilStep("wait for player", () => CurrentScreen is Player player && player.IsLoaded);
AddAssert("mods are correct", () => !((Player)CurrentScreen).Mods.Value.Any());
AddStep("exit player", () => CurrentScreen.Exit());
}
private void addItem(Func<BeatmapInfo> beatmap, RulesetInfo? ruleset = null, IReadOnlyList<Mod>? mods = null)
{
Screens.Select.SongSelect? songSelect = null;
AddStep("click add button", () =>
{
InputManager.MoveMouseTo(this.ChildrenOfType<MultiplayerMatchSubScreen.AddItemButton>().Single());
InputManager.Click(MouseButton.Left);
});
AddUntilStep("wait for song select", () => CurrentSubScreen is Screens.Select.SongSelect select && select.BeatmapSetsLoaded);
AddStep("select other beatmap", () => ((Screens.Select.SongSelect)CurrentSubScreen).FinaliseSelection(beatmap()));
AddUntilStep("wait for song select", () => (songSelect = CurrentSubScreen as Screens.Select.SongSelect) != null);
AddUntilStep("wait for loaded", () => songSelect.AsNonNull().BeatmapSetsLoaded);
if (ruleset != null)
AddStep($"set {ruleset.Name} ruleset", () => songSelect.AsNonNull().Ruleset.Value = ruleset);
if (mods != null)
AddStep($"set mods to {string.Join(",", mods.Select(m => m.Acronym))}", () => songSelect.AsNonNull().Mods.Value = mods);
AddStep("select other beatmap", () => songSelect.AsNonNull().FinaliseSelection(beatmap()));
AddUntilStep("wait for return to match", () => CurrentSubScreen is MultiplayerMatchSubScreen);
}
}

View File

@ -8,6 +8,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Platform;
@ -153,7 +154,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
var beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo;
AddStep("import beatmap", () => manager.Import(beatmap.BeatmapSet).Wait());
AddStep("import beatmap", () => manager.Import(beatmap.BeatmapSet).WaitSafely());
createPlaylistWithBeatmaps(beatmap);

View File

@ -50,6 +50,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
});
AddUntilStep("wait for load", () => leaderboard.IsLoaded);
AddUntilStep("wait for user population", () => leaderboard.ChildrenOfType<GameplayLeaderboardScore>().Count() == 2);
AddStep("add clock sources", () =>
{

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -46,7 +47,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
[BackgroundDependencyLoader]
private void load()
{
importedSet = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).Result;
importedSet = ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).GetResultSafely();
importedBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0);
importedBeatmapId = importedBeatmap.OnlineID ?? -1;
}

View File

@ -7,6 +7,8 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
@ -22,6 +24,8 @@ using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Overlays.Mods;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Screens.OnlinePlay.Components;
@ -67,7 +71,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("import beatmap", () =>
{
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
});
@ -438,6 +442,84 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddAssert("Beatmap matches current item", () => Beatmap.Value.BeatmapInfo.OnlineID == client.Room?.Playlist.First().BeatmapID);
}
[Test]
public void TestPlayStartsWithCorrectRulesetWhileAtSongSelect()
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Playlist =
{
new PlaylistItem
{
Beatmap = { Value = beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.RulesetID == 0)).BeatmapInfo },
Ruleset = { Value = new OsuRuleset().RulesetInfo },
}
}
});
pressReadyButton();
AddStep("Enter song select", () =>
{
var currentSubScreen = ((Screens.OnlinePlay.Multiplayer.Multiplayer)multiplayerComponents.CurrentScreen).CurrentSubScreen;
((MultiplayerMatchSubScreen)currentSubScreen).OpenSongSelection(client.Room?.Settings.PlaylistItemId);
});
AddUntilStep("wait for song select", () => this.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault()?.BeatmapSetsLoaded == true);
AddAssert("Ruleset matches current item", () => Ruleset.Value.OnlineID == client.Room?.Playlist.First().RulesetID);
AddStep("Switch ruleset", () => ((MultiplayerMatchSongSelect)multiplayerComponents.MultiplayerScreen.CurrentSubScreen).Ruleset.Value = new CatchRuleset().RulesetInfo);
AddUntilStep("Ruleset doesn't match current item", () => Ruleset.Value.OnlineID != client.Room?.Playlist.First().RulesetID);
AddStep("start match externally", () => client.StartMatch());
AddUntilStep("play started", () => multiplayerComponents.CurrentScreen is Player);
AddAssert("Ruleset matches current item", () => Ruleset.Value.OnlineID == client.Room?.Playlist.First().RulesetID);
}
[Test]
public void TestPlayStartsWithCorrectModsWhileAtSongSelect()
{
createRoom(() => new Room
{
Name = { Value = "Test Room" },
Playlist =
{
new PlaylistItem
{
Beatmap = { Value = beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.RulesetID == 0)).BeatmapInfo },
Ruleset = { Value = new OsuRuleset().RulesetInfo },
}
}
});
pressReadyButton();
AddStep("Enter song select", () =>
{
var currentSubScreen = ((Screens.OnlinePlay.Multiplayer.Multiplayer)multiplayerComponents.CurrentScreen).CurrentSubScreen;
((MultiplayerMatchSubScreen)currentSubScreen).OpenSongSelection(client.Room?.Settings.PlaylistItemId);
});
AddUntilStep("wait for song select", () => this.ChildrenOfType<MultiplayerMatchSongSelect>().FirstOrDefault()?.BeatmapSetsLoaded == true);
AddAssert("Mods match current item", () => SelectedMods.Value.Select(m => m.Acronym).SequenceEqual(client.Room.AsNonNull().Playlist.First().RequiredMods.Select(m => m.Acronym)));
AddStep("Switch required mods", () => ((MultiplayerMatchSongSelect)multiplayerComponents.MultiplayerScreen.CurrentSubScreen).Mods.Value = new Mod[] { new OsuModDoubleTime() });
AddAssert("Mods don't match current item", () => !SelectedMods.Value.Select(m => m.Acronym).SequenceEqual(client.Room.AsNonNull().Playlist.First().RequiredMods.Select(m => m.Acronym)));
AddStep("start match externally", () => client.StartMatch());
AddUntilStep("play started", () => multiplayerComponents.CurrentScreen is Player);
AddAssert("Mods match current item", () => SelectedMods.Value.Select(m => m.Acronym).SequenceEqual(client.Room.AsNonNull().Playlist.First().RequiredMods.Select(m => m.Acronym)));
}
[Test]
public void TestLocalPlayDoesNotStartWhileSpectatingWithNoBeatmap()
{
@ -505,7 +587,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("restore beatmap", () =>
{
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
});

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Utils;
@ -43,7 +44,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
base.SetUpSteps();
AddStep("set local user", () => ((DummyAPIAccess)API).LocalUser.Value = LookupCache.GetUserAsync(1).Result);
AddStep("set local user", () => ((DummyAPIAccess)API).LocalUser.Value = LookupCache.GetUserAsync(1).GetResultSafely());
AddStep("create leaderboard", () =>
{
@ -90,7 +91,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
public void TestUserQuit()
{
foreach (int user in users)
AddStep($"mark user {user} quit", () => Client.RemoveUser(LookupCache.GetUserAsync(user).Result.AsNonNull()));
AddStep($"mark user {user} quit", () => Client.RemoveUser(LookupCache.GetUserAsync(user).GetResultSafely().AsNonNull()));
}
[Test]

View File

@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Utils;
using osu.Game.Online.API;
@ -47,7 +48,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
base.SetUpSteps();
AddStep("set local user", () => ((DummyAPIAccess)API).LocalUser.Value = LookupCache.GetUserAsync(1).Result);
AddStep("set local user", () => ((DummyAPIAccess)API).LocalUser.Value = LookupCache.GetUserAsync(1).GetResultSafely());
AddStep("create leaderboard", () =>
{

View File

@ -83,7 +83,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
beatmapSetInfo.Beatmaps.Add(beatmap);
}
manager.Import(beatmapSetInfo).Wait();
manager.Import(beatmapSetInfo).WaitSafely();
}
public override void SetUpSteps()

View File

@ -5,6 +5,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Framework.Testing;
@ -39,7 +40,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
}

View File

@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Platform;
using osu.Framework.Testing;
@ -53,7 +54,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
AddStep("import beatmap", () =>
{
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
importedBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0);
});

View File

@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Platform;
@ -58,7 +59,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("import beatmap", () =>
{
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
importedBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0);
});

View File

@ -8,6 +8,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Platform;
using osu.Framework.Testing;
@ -41,7 +42,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
}
[SetUp]

View File

@ -8,6 +8,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Platform;
@ -42,7 +43,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
}
[SetUp]

View File

@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Framework.Utils;
@ -38,7 +39,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
var beatmapSet = TestResources.CreateTestBeatmapSetInfo();
manager.Import(beatmapSet).Wait();
manager.Import(beatmapSet).WaitSafely();
}
public override void SetUpSteps()

View File

@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
@ -51,7 +52,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("import beatmap", () =>
{
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
});

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Game.Configuration;
using osu.Game.Screens.Play;
using osu.Game.Tests.Beatmaps.IO;
@ -82,7 +83,7 @@ namespace osu.Game.Tests.Visual.Navigation
PushAndConfirm(() => songSelect = new TestSceneScreenNavigation.TestPlaySongSelect());
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).Wait());
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).WaitSafely());
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
AddStep("press enter", () => InputManager.Key(Key.Enter));

View File

@ -4,6 +4,7 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics.Containers;
using osu.Framework.Screens;
using osu.Framework.Testing;
@ -172,7 +173,7 @@ namespace osu.Game.Tests.Visual.Navigation
private void importAndWaitForSongSelect()
{
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).Wait());
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).WaitSafely());
PushAndConfirm(() => new TestPlaySongSelect());
AddUntilStep("beatmap updated", () => Game.Beatmap.Value.BeatmapSetInfo.OnlineID == 241526);
}

View File

@ -4,6 +4,7 @@
using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Screens;
using osu.Game.Beatmaps;
using osu.Game.Extensions;
@ -20,30 +21,30 @@ namespace osu.Game.Tests.Visual.Navigation
public void TestFromMainMenu()
{
var firstImport = importBeatmap(1);
var secondimport = importBeatmap(3);
var secondImport = importBeatmap(3);
presentAndConfirm(firstImport);
returnToMenu();
presentAndConfirm(secondimport);
presentAndConfirm(secondImport);
returnToMenu();
presentSecondDifficultyAndConfirm(firstImport, 1);
returnToMenu();
presentSecondDifficultyAndConfirm(secondimport, 3);
presentSecondDifficultyAndConfirm(secondImport, 3);
}
[Test]
public void TestFromMainMenuDifferentRuleset()
{
var firstImport = importBeatmap(1);
var secondimport = importBeatmap(3, new ManiaRuleset().RulesetInfo);
var secondImport = importBeatmap(3, new ManiaRuleset().RulesetInfo);
presentAndConfirm(firstImport);
returnToMenu();
presentAndConfirm(secondimport);
presentAndConfirm(secondImport);
returnToMenu();
presentSecondDifficultyAndConfirm(firstImport, 1);
returnToMenu();
presentSecondDifficultyAndConfirm(secondimport, 3);
presentSecondDifficultyAndConfirm(secondImport, 3);
}
[Test]
@ -52,17 +53,17 @@ namespace osu.Game.Tests.Visual.Navigation
var firstImport = importBeatmap(1);
presentAndConfirm(firstImport);
var secondimport = importBeatmap(3);
presentAndConfirm(secondimport);
var secondImport = importBeatmap(3);
presentAndConfirm(secondImport);
// Test presenting same beatmap more than once
presentAndConfirm(secondimport);
presentAndConfirm(secondImport);
presentSecondDifficultyAndConfirm(firstImport, 1);
presentSecondDifficultyAndConfirm(secondimport, 3);
presentSecondDifficultyAndConfirm(secondImport, 3);
// Test presenting same beatmap more than once
presentSecondDifficultyAndConfirm(secondimport, 3);
presentSecondDifficultyAndConfirm(secondImport, 3);
}
[Test]
@ -71,11 +72,11 @@ namespace osu.Game.Tests.Visual.Navigation
var firstImport = importBeatmap(1);
presentAndConfirm(firstImport);
var secondimport = importBeatmap(3, new ManiaRuleset().RulesetInfo);
presentAndConfirm(secondimport);
var secondImport = importBeatmap(3, new ManiaRuleset().RulesetInfo);
presentAndConfirm(secondImport);
presentSecondDifficultyAndConfirm(firstImport, 1);
presentSecondDifficultyAndConfirm(secondimport, 3);
presentSecondDifficultyAndConfirm(secondImport, 3);
}
private void returnToMenu()
@ -126,7 +127,7 @@ namespace osu.Game.Tests.Visual.Navigation
Ruleset = ruleset ?? new OsuRuleset().RulesetInfo
},
}
}).Result.Value;
}).GetResultSafely().Value;
});
AddAssert($"import {i} succeeded", () => imported != null);

View File

@ -4,6 +4,7 @@
using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
@ -57,7 +58,7 @@ namespace osu.Game.Tests.Visual.Navigation
Ruleset = new OsuRuleset().RulesetInfo
},
}
}).Result.Value;
}).GetResultSafely().Value;
});
}
@ -65,11 +66,11 @@ namespace osu.Game.Tests.Visual.Navigation
public void TestFromMainMenu([Values] ScorePresentType type)
{
var firstImport = importScore(1);
var secondimport = importScore(3);
var secondImport = importScore(3);
presentAndConfirm(firstImport, type);
returnToMenu();
presentAndConfirm(secondimport, type);
presentAndConfirm(secondImport, type);
returnToMenu();
returnToMenu();
}
@ -78,11 +79,11 @@ namespace osu.Game.Tests.Visual.Navigation
public void TestFromMainMenuDifferentRuleset([Values] ScorePresentType type)
{
var firstImport = importScore(1);
var secondimport = importScore(3, new ManiaRuleset().RulesetInfo);
var secondImport = importScore(3, new ManiaRuleset().RulesetInfo);
presentAndConfirm(firstImport, type);
returnToMenu();
presentAndConfirm(secondimport, type);
presentAndConfirm(secondImport, type);
returnToMenu();
returnToMenu();
}
@ -93,8 +94,8 @@ namespace osu.Game.Tests.Visual.Navigation
var firstImport = importScore(1);
presentAndConfirm(firstImport, type);
var secondimport = importScore(3);
presentAndConfirm(secondimport, type);
var secondImport = importScore(3);
presentAndConfirm(secondImport, type);
}
[Test]
@ -103,8 +104,8 @@ namespace osu.Game.Tests.Visual.Navigation
var firstImport = importScore(1);
presentAndConfirm(firstImport, type);
var secondimport = importScore(3, new ManiaRuleset().RulesetInfo);
presentAndConfirm(secondimport, type);
var secondImport = importScore(3, new ManiaRuleset().RulesetInfo);
presentAndConfirm(secondImport, type);
}
private void returnToMenu()
@ -131,7 +132,7 @@ namespace osu.Game.Tests.Visual.Navigation
OnlineID = i,
BeatmapInfo = beatmap.Beatmaps.First(),
Ruleset = ruleset ?? new OsuRuleset().RulesetInfo
}).Result.Value;
}).GetResultSafely().Value;
});
AddAssert($"import {i} succeeded", () => imported != null);

View File

@ -4,6 +4,7 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics.Containers;
using osu.Framework.Screens;
using osu.Framework.Testing;
@ -70,7 +71,7 @@ namespace osu.Game.Tests.Visual.Navigation
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).Wait());
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).WaitSafely());
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
@ -104,7 +105,7 @@ namespace osu.Game.Tests.Visual.Navigation
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).Wait());
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).WaitSafely());
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
@ -138,7 +139,7 @@ namespace osu.Game.Tests.Visual.Navigation
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).Wait());
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).WaitSafely());
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);

View File

@ -30,7 +30,7 @@ namespace osu.Game.Tests.Visual.Online
},
});
visiblityAssert(true);
visibilityAssert(true);
}
[Test]
@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual.Online
},
});
visiblityAssert(true);
visibilityAssert(true);
}
[Test]
@ -59,7 +59,7 @@ namespace osu.Game.Tests.Visual.Online
},
});
visiblityAssert(true);
visibilityAssert(true);
}
[Test]
@ -73,10 +73,10 @@ namespace osu.Game.Tests.Visual.Online
},
});
visiblityAssert(false);
visibilityAssert(false);
}
private void visiblityAssert(bool shown)
private void visibilityAssert(bool shown)
{
AddAssert($"is container {(shown ? "visible" : "hidden")}", () => container.Alpha == (shown ? 1 : 0));
}

View File

@ -107,19 +107,31 @@ namespace osu.Game.Tests.Visual.Online
AddUntilStep("is hidden", () => overlay.State.Value == Visibility.Hidden);
}
[Test]
public void TestCorrectOldContentExpiration()
{
AddAssert("is visible", () => overlay.State.Value == Visibility.Visible);
AddStep("show many results", () => fetchFor(Enumerable.Repeat(CreateAPIBeatmapSet(Ruleset.Value), 100).ToArray()));
assertAllCardsOfType<BeatmapCardNormal>(100);
AddStep("show more results", () => fetchFor(Enumerable.Repeat(CreateAPIBeatmapSet(Ruleset.Value), 30).ToArray()));
assertAllCardsOfType<BeatmapCardNormal>(30);
}
[Test]
public void TestCardSizeSwitching()
{
AddAssert("is visible", () => overlay.State.Value == Visibility.Visible);
AddStep("show many results", () => fetchFor(Enumerable.Repeat(CreateAPIBeatmapSet(Ruleset.Value), 100).ToArray()));
assertAllCardsOfType<BeatmapCardNormal>();
assertAllCardsOfType<BeatmapCardNormal>(100);
setCardSize(BeatmapCardSize.Extra);
assertAllCardsOfType<BeatmapCardExtra>();
assertAllCardsOfType<BeatmapCardExtra>(100);
setCardSize(BeatmapCardSize.Normal);
assertAllCardsOfType<BeatmapCardNormal>();
assertAllCardsOfType<BeatmapCardNormal>(100);
AddStep("fetch for 0 beatmaps", () => fetchFor());
AddUntilStep("placeholder shown", () => overlay.ChildrenOfType<BeatmapListingOverlay.NotFoundDrawable>().SingleOrDefault()?.IsPresent == true);
@ -323,13 +335,12 @@ namespace osu.Game.Tests.Visual.Online
private void setCardSize(BeatmapCardSize cardSize) => AddStep($"set card size to {cardSize}", () => overlay.ChildrenOfType<BeatmapListingCardSizeTabControl>().Single().Current.Value = cardSize);
private void assertAllCardsOfType<T>()
private void assertAllCardsOfType<T>(int expectedCount)
where T : BeatmapCard =>
AddUntilStep($"all loaded beatmap cards are {typeof(T)}", () =>
{
int loadedCorrectCount = this.ChildrenOfType<BeatmapCard>().Count(card => card.IsLoaded && card.GetType() == typeof(T));
int totalCount = this.ChildrenOfType<BeatmapCard>().Count();
return loadedCorrectCount > 0 && loadedCorrectCount == totalCount;
return loadedCorrectCount > 0 && loadedCorrectCount == expectedCount;
});
}
}

View File

@ -50,63 +50,24 @@ namespace osu.Game.Tests.Visual.Online
Dependencies.Cache(new ChatOverlay());
Dependencies.Cache(dialogOverlay);
testLinksGeneral();
testEcho();
}
private void clear() => AddStep("clear messages", textContainer.Clear);
private void addMessageWithChecks(string text, int linkAmount = 0, bool isAction = false, bool isImportant = false, params LinkAction[] expectedActions)
[SetUp]
public void Setup() => Schedule(() =>
{
int index = textContainer.Count + 1;
var newLine = new ChatLine(new DummyMessage(text, isAction, isImportant, index));
textContainer.Add(newLine);
textContainer.Clear();
});
AddAssert($"msg #{index} has {linkAmount} link(s)", () => newLine.Message.Links.Count == linkAmount);
AddAssert($"msg #{index} has the right action", hasExpectedActions);
//AddAssert($"msg #{index} is " + (isAction ? "italic" : "not italic"), () => newLine.ContentFlow.Any() && isAction == isItalic());
AddAssert($"msg #{index} shows {linkAmount} link(s)", isShowingLinks);
bool hasExpectedActions()
{
var expectedActionsList = expectedActions.ToList();
if (expectedActionsList.Count != newLine.Message.Links.Count)
return false;
for (int i = 0; i < newLine.Message.Links.Count; i++)
{
var action = newLine.Message.Links[i].Action;
if (action != expectedActions[i]) return false;
}
return true;
}
//bool isItalic() => newLine.ContentFlow.Where(d => d is OsuSpriteText).Cast<OsuSpriteText>().All(sprite => sprite.Font.Italics);
bool isShowingLinks()
{
bool hasBackground = !string.IsNullOrEmpty(newLine.Message.Sender.Colour);
Color4 textColour = isAction && hasBackground ? Color4Extensions.FromHex(newLine.Message.Sender.Colour) : Color4.White;
var linkCompilers = newLine.ContentFlow.Where(d => d is DrawableLinkCompiler).ToList();
var linkSprites = linkCompilers.SelectMany(comp => ((DrawableLinkCompiler)comp).Parts);
return linkSprites.All(d => d.Colour == linkColour)
&& newLine.ContentFlow.Except(linkSprites.Concat(linkCompilers)).All(d => d.Colour == textColour);
}
}
private void testLinksGeneral()
[Test]
public void TestLinksGeneral()
{
int messageIndex = 0;
addMessageWithChecks("test!");
addMessageWithChecks("dev.ppy.sh!");
addMessageWithChecks("https://dev.ppy.sh!", 1, expectedActions: LinkAction.External);
addMessageWithChecks("00:12:345 (1,2) - Test?", 1, expectedActions: LinkAction.OpenEditorTimestamp);
addMessageWithChecks("Wiki link for tasty [[Performance Points]]", 1, expectedActions: LinkAction.External);
addMessageWithChecks("Wiki link for tasty [[Performance Points]]", 1, expectedActions: LinkAction.OpenWiki);
addMessageWithChecks("(osu forums)[https://dev.ppy.sh/forum] (old link format)", 1, expectedActions: LinkAction.External);
addMessageWithChecks("[https://dev.ppy.sh/home New site] (new link format)", 1, expectedActions: LinkAction.External);
addMessageWithChecks("[osu forums](https://dev.ppy.sh/forum) (new link format 2)", 1, expectedActions: LinkAction.External);
@ -117,7 +78,8 @@ namespace osu.Game.Tests.Visual.Online
expectedActions: new[] { LinkAction.External, LinkAction.OpenBeatmap, LinkAction.External });
addMessageWithChecks("[https://dev.ppy.sh/home New link format with escaped [and \\[ paired] braces]", 1, expectedActions: LinkAction.External);
addMessageWithChecks("[Markdown link format with escaped [and \\[ paired] braces](https://dev.ppy.sh/home)", 1, expectedActions: LinkAction.External);
addMessageWithChecks("(Old link format with escaped (and \\( paired) parentheses)[https://dev.ppy.sh/home] and [[also a rogue wiki link]]", 2, expectedActions: new[] { LinkAction.External, LinkAction.External });
addMessageWithChecks("(Old link format with escaped (and \\( paired) parentheses)[https://dev.ppy.sh/home] and [[also a rogue wiki link]]", 2,
expectedActions: new[] { LinkAction.External, LinkAction.OpenWiki });
// note that there's 0 links here (they get removed if a channel is not found)
addMessageWithChecks("#lobby or #osu would be blue (and work) in the ChatDisplay test (when a proper ChatOverlay is present).");
addMessageWithChecks("I am important!", 0, false, true);
@ -129,11 +91,60 @@ namespace osu.Game.Tests.Visual.Online
addMessageWithChecks("Join my osu://chan/#english.", 1, expectedActions: LinkAction.OpenChannel);
addMessageWithChecks("Join my #english or #japanese channels.", 2, expectedActions: new[] { LinkAction.OpenChannel, LinkAction.OpenChannel });
addMessageWithChecks("Join my #english or #nonexistent #hashtag channels.", 1, expectedActions: LinkAction.OpenChannel);
void addMessageWithChecks(string text, int linkAmount = 0, bool isAction = false, bool isImportant = false, params LinkAction[] expectedActions)
{
ChatLine newLine = null;
int index = messageIndex++;
AddStep("add message", () =>
{
newLine = new ChatLine(new DummyMessage(text, isAction, isImportant, index));
textContainer.Add(newLine);
});
AddAssert($"msg #{index} has {linkAmount} link(s)", () => newLine.Message.Links.Count == linkAmount);
AddAssert($"msg #{index} has the right action", hasExpectedActions);
//AddAssert($"msg #{index} is " + (isAction ? "italic" : "not italic"), () => newLine.ContentFlow.Any() && isAction == isItalic());
AddAssert($"msg #{index} shows {linkAmount} link(s)", isShowingLinks);
bool hasExpectedActions()
{
var expectedActionsList = expectedActions.ToList();
if (expectedActionsList.Count != newLine.Message.Links.Count)
return false;
for (int i = 0; i < newLine.Message.Links.Count; i++)
{
var action = newLine.Message.Links[i].Action;
if (action != expectedActions[i]) return false;
}
return true;
}
//bool isItalic() => newLine.ContentFlow.Where(d => d is OsuSpriteText).Cast<OsuSpriteText>().All(sprite => sprite.Font.Italics);
bool isShowingLinks()
{
bool hasBackground = !string.IsNullOrEmpty(newLine.Message.Sender.Colour);
Color4 textColour = isAction && hasBackground ? Color4Extensions.FromHex(newLine.Message.Sender.Colour) : Color4.White;
var linkCompilers = newLine.ContentFlow.Where(d => d is DrawableLinkCompiler).ToList();
var linkSprites = linkCompilers.SelectMany(comp => ((DrawableLinkCompiler)comp).Parts);
return linkSprites.All(d => d.Colour == linkColour)
&& newLine.ContentFlow.Except(linkSprites.Concat(linkCompilers)).All(d => d.Colour == textColour);
}
}
}
private void testEcho()
[Test]
public void TestEcho()
{
int echoCounter = 0;
int messageIndex = 0;
addEchoWithWait("sent!", "received!");
addEchoWithWait("https://dev.ppy.sh/home", null, 500);
@ -142,15 +153,16 @@ namespace osu.Game.Tests.Visual.Online
void addEchoWithWait(string text, string completeText = null, double delay = 250)
{
var newLine = new ChatLine(new DummyEchoMessage(text));
int index = messageIndex++;
AddStep($"send msg #{++echoCounter} after {delay}ms", () =>
AddStep($"send msg #{index} after {delay}ms", () =>
{
ChatLine newLine = new ChatLine(new DummyEchoMessage(text));
textContainer.Add(newLine);
Scheduler.AddDelayed(() => newLine.Message = new DummyMessage(completeText ?? text), delay);
});
AddUntilStep($"wait for msg #{echoCounter}", () => textContainer.All(line => line.Message is DummyMessage));
AddUntilStep($"wait for msg #{index}", () => textContainer.All(line => line.Message is DummyMessage));
}
}

View File

@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual.Online
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
background.Colour = colours.GreySeafoam;
background.Colour = colours.GreySeaFoam;
}
private readonly IEnumerable<APIKudosuHistory> items = new[]

View File

@ -87,7 +87,7 @@ namespace osu.Game.Tests.Visual.Online
{
AddStep("Load user", () => user.Value = user_with_filled_values);
AddAssert("Section is visible", () => section.Alpha == 1);
AddAssert("Array length is the same", () => user_with_filled_values.MonthlyPlaycounts.Length == getChartValuesLength());
AddAssert("Array length is the same", () => user_with_filled_values.MonthlyPlayCounts.Length == getChartValuesLength());
}
[Test]
@ -108,13 +108,13 @@ namespace osu.Game.Tests.Visual.Online
private static readonly APIUser user_with_empty_values = new APIUser
{
Id = 2,
MonthlyPlaycounts = Array.Empty<APIUserHistoryCount>()
MonthlyPlayCounts = Array.Empty<APIUserHistoryCount>()
};
private static readonly APIUser user_with_one_value = new APIUser
{
Id = 3,
MonthlyPlaycounts = new[]
MonthlyPlayCounts = new[]
{
new APIUserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 100 }
}
@ -123,7 +123,7 @@ namespace osu.Game.Tests.Visual.Online
private static readonly APIUser user_with_two_values = new APIUser
{
Id = 4,
MonthlyPlaycounts = new[]
MonthlyPlayCounts = new[]
{
new APIUserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 1 },
new APIUserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 2 }
@ -133,7 +133,7 @@ namespace osu.Game.Tests.Visual.Online
private static readonly APIUser user_with_constant_values = new APIUser
{
Id = 5,
MonthlyPlaycounts = new[]
MonthlyPlayCounts = new[]
{
new APIUserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 5 },
new APIUserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 5 },
@ -144,7 +144,7 @@ namespace osu.Game.Tests.Visual.Online
private static readonly APIUser user_with_zero_values = new APIUser
{
Id = 6,
MonthlyPlaycounts = new[]
MonthlyPlayCounts = new[]
{
new APIUserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 0 },
new APIUserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 0 },
@ -155,7 +155,7 @@ namespace osu.Game.Tests.Visual.Online
private static readonly APIUser user_with_filled_values = new APIUser
{
Id = 7,
MonthlyPlaycounts = new[]
MonthlyPlayCounts = new[]
{
new APIUserHistoryCount { Date = new DateTime(2010, 5, 1), Count = 1000 },
new APIUserHistoryCount { Date = new DateTime(2010, 6, 1), Count = 20 },
@ -170,7 +170,7 @@ namespace osu.Game.Tests.Visual.Online
private static readonly APIUser user_with_missing_values = new APIUser
{
Id = 8,
MonthlyPlaycounts = new[]
MonthlyPlayCounts = new[]
{
new APIUserHistoryCount { Date = new DateTime(2020, 1, 1), Count = 100 },
new APIUserHistoryCount { Date = new DateTime(2020, 7, 1), Count = 200 }

View File

@ -1,38 +1,27 @@
// 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 osu.Framework.Graphics.Containers;
using osu.Game.Overlays.Rankings.Tables;
using osu.Framework.Graphics;
using osu.Game.Online.API.Requests;
using osu.Game.Rulesets;
using System.Threading;
using osu.Game.Online.API;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Taiko;
using osu.Game.Rulesets.Catch;
using osu.Framework.Allocation;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Overlays.Rankings;
using osu.Game.Users;
namespace osu.Game.Tests.Visual.Online
{
public class TestSceneRankingsTables : OsuTestScene
{
protected override bool UseOnlineAPI => true;
[Resolved]
private IAPIProvider api { get; set; }
[Cached]
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green);
private readonly BasicScrollContainer scrollFlow;
private readonly LoadingLayer loading;
private CancellationTokenSource cancellationToken;
private APIRequest request;
public TestSceneRankingsTables()
{
@ -53,73 +42,120 @@ namespace osu.Game.Tests.Visual.Online
{
base.LoadComplete();
AddStep("Osu performance", () => createPerformanceTable(new OsuRuleset().RulesetInfo, null));
AddStep("Mania scores", () => createScoreTable(new ManiaRuleset().RulesetInfo));
AddStep("Taiko country scores", () => createCountryTable(new TaikoRuleset().RulesetInfo));
AddStep("Catch US performance page 10", () => createPerformanceTable(new CatchRuleset().RulesetInfo, "US", 10));
AddStep("Osu spotlight table (chart 271)", () => createSpotlightTable(new OsuRuleset().RulesetInfo, 271));
AddStep("User performance", createPerformanceTable);
AddStep("User scores", createScoreTable);
AddStep("Country scores", createCountryTable);
}
private void createCountryTable(RulesetInfo ruleset, int page = 1)
private void createCountryTable()
{
onLoadStarted();
request = new GetCountryRankingsRequest(ruleset, page);
((GetCountryRankingsRequest)request).Success += rankings => Schedule(() =>
var countries = new List<CountryStatistics>
{
var table = new CountriesTable(page, rankings.Countries);
loadTable(table);
});
new CountryStatistics
{
Country = new Country { FlagName = "US", FullName = "United States" },
FlagName = "US",
ActiveUsers = 2_972_623,
PlayCount = 3_086_515_743,
RankedScore = 449_407_643_332_546,
Performance = 371_974_024
},
new CountryStatistics
{
Country = new Country { FlagName = "RU", FullName = "Russian Federation" },
FlagName = "RU",
ActiveUsers = 1_609_989,
PlayCount = 1_637_052_841,
RankedScore = 221_660_827_473_004,
Performance = 163_426_476
}
};
api.Queue(request);
var table = new CountriesTable(1, countries);
loadTable(table);
}
private void createPerformanceTable(RulesetInfo ruleset, string country, int page = 1)
private static List<UserStatistics> createUserStatistics() => new List<UserStatistics>
{
new UserStatistics
{
User = new APIUser
{
Username = "first active user",
Country = new Country { FlagName = "JP" },
Active = true,
},
Accuracy = 0.9972,
PlayCount = 233_215,
TotalScore = 983_231_234_656,
RankedScore = 593_231_345_897,
PP = 23_934,
GradesCount = new UserStatistics.Grades
{
SS = 35_132,
S = 23_345,
A = 12_234
}
},
new UserStatistics
{
User = new APIUser
{
Username = "inactive user",
Country = new Country { FlagName = "AU" },
Active = false,
},
Accuracy = 0.9831,
PlayCount = 195_342,
TotalScore = 683_231_234_656,
RankedScore = 393_231_345_897,
PP = 20_934,
GradesCount = new UserStatistics.Grades
{
SS = 32_132,
S = 20_345,
A = 9_234
}
},
new UserStatistics
{
User = new APIUser
{
Username = "second active user",
Country = new Country { FlagName = "PL" },
Active = true,
},
Accuracy = 0.9584,
PlayCount = 100_903,
TotalScore = 97_242_983_434,
RankedScore = 3_156_345_897,
PP = 9_568,
GradesCount = new UserStatistics.Grades
{
SS = 13_152,
S = 24_375,
A = 9_960
}
},
};
private void createPerformanceTable()
{
onLoadStarted();
request = new GetUserRankingsRequest(ruleset, country: country, page: page);
((GetUserRankingsRequest)request).Success += rankings => Schedule(() =>
{
var table = new PerformanceTable(page, rankings.Users);
loadTable(table);
});
api.Queue(request);
loadTable(new PerformanceTable(1, createUserStatistics()));
}
private void createScoreTable(RulesetInfo ruleset, int page = 1)
private void createScoreTable()
{
onLoadStarted();
request = new GetUserRankingsRequest(ruleset, UserRankingsType.Score, page);
((GetUserRankingsRequest)request).Success += rankings => Schedule(() =>
{
var table = new ScoresTable(page, rankings.Users);
loadTable(table);
});
api.Queue(request);
}
private void createSpotlightTable(RulesetInfo ruleset, int spotlight)
{
onLoadStarted();
request = new GetSpotlightRankingsRequest(ruleset, spotlight, RankingsSortCriteria.All);
((GetSpotlightRankingsRequest)request).Success += rankings => Schedule(() =>
{
var table = new ScoresTable(1, rankings.Users);
loadTable(table);
});
api.Queue(request);
loadTable(new ScoresTable(1, createUserStatistics()));
}
private void onLoadStarted()
{
loading.Show();
request?.Cancel();
cancellationToken?.Cancel();
cancellationToken = new CancellationTokenSource();
}

View File

@ -0,0 +1,57 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Timing;
using osu.Game.Overlays.BeatmapSet.Scores;
namespace osu.Game.Tests.Visual.Online
{
public class TestSceneScoreboardTime : OsuTestScene
{
private StopwatchClock stopwatch;
[Test]
public void TestVariousUnits()
{
AddStep("create various scoreboard times", () => Child = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Clock = new FramedClock(stopwatch = new StopwatchClock()), // prevent time from naturally elapsing.
Direction = FillDirection.Vertical,
ChildrenEnumerable = testCases.Select(dateTime => new ScoreboardTime(dateTime, 24).With(time => time.Anchor = time.Origin = Anchor.TopCentre))
});
AddStep("start stopwatch", () => stopwatch.Start());
}
private static IEnumerable<DateTimeOffset> testCases => new[]
{
DateTimeOffset.Now,
DateTimeOffset.Now.AddSeconds(-1),
DateTimeOffset.Now.AddSeconds(-25),
DateTimeOffset.Now.AddSeconds(-59),
DateTimeOffset.Now.AddMinutes(-1),
DateTimeOffset.Now.AddMinutes(-25),
DateTimeOffset.Now.AddMinutes(-59),
DateTimeOffset.Now.AddHours(-1),
DateTimeOffset.Now.AddHours(-13),
DateTimeOffset.Now.AddHours(-23),
DateTimeOffset.Now.AddDays(-1),
DateTimeOffset.Now.AddDays(-6),
DateTimeOffset.Now.AddDays(-16),
DateTimeOffset.Now.AddMonths(-1),
DateTimeOffset.Now.AddMonths(-11),
DateTimeOffset.Now.AddYears(-1),
DateTimeOffset.Now.AddYears(-5)
};
}
}

View File

@ -309,8 +309,8 @@ namespace osu.Game.Tests.Visual.Online
private class TestStandAloneChatDisplay : StandAloneChatDisplay
{
public TestStandAloneChatDisplay(bool textbox = false)
: base(textbox)
public TestStandAloneChatDisplay(bool textBox = false)
: base(textBox)
{
}

View File

@ -87,7 +87,7 @@ namespace osu.Game.Tests.Visual.Playlists
{
const string not_found_prefix = "beatmaps not found:";
string errorMesage = null;
string errorMessage = null;
AddStep("setup", () =>
{
@ -96,9 +96,9 @@ namespace osu.Game.Tests.Visual.Playlists
SelectedRoom.Value.Name.Value = "Test Room";
SelectedRoom.Value.Playlist.Add(new PlaylistItem { Beatmap = { Value = beatmap } });
errorMesage = $"{not_found_prefix} {beatmap.OnlineID}";
errorMessage = $"{not_found_prefix} {beatmap.OnlineID}";
RoomManager.CreateRequested = _ => errorMesage;
RoomManager.CreateRequested = _ => errorMessage;
});
AddAssert("error not displayed", () => !settings.ErrorText.IsPresent);
@ -107,7 +107,7 @@ namespace osu.Game.Tests.Visual.Playlists
AddStep("create room", () => settings.ApplyButton.Action.Invoke());
AddAssert("error displayed", () => settings.ErrorText.IsPresent);
AddAssert("error has custom text", () => settings.ErrorText.Text != errorMesage);
AddAssert("error has custom text", () => settings.ErrorText.Text != errorMessage);
AddAssert("playlist item marked invalid", () => !SelectedRoom.Value.Playlist[0].Valid.Value);
}

View File

@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Framework.Testing;
@ -142,7 +143,7 @@ namespace osu.Game.Tests.Visual.Playlists
modifiedBeatmap.HitObjects.Clear();
modifiedBeatmap.HitObjects.Add(new HitCircle { StartTime = 5000 });
manager.Import(modifiedBeatmap.BeatmapInfo.BeatmapSet).Wait();
manager.Import(modifiedBeatmap.BeatmapInfo.BeatmapSet).WaitSafely();
});
// Create the room using the real beatmap values.
@ -184,7 +185,7 @@ namespace osu.Game.Tests.Visual.Playlists
},
};
manager.Import(originalBeatmap.BeatmapInfo.BeatmapSet).Wait();
manager.Import(originalBeatmap.BeatmapInfo.BeatmapSet).WaitSafely();
});
AddUntilStep("match has correct beatmap", () => realHash == match.Beatmap.Value.BeatmapInfo.MD5Hash);
@ -201,7 +202,7 @@ namespace osu.Game.Tests.Visual.Playlists
});
}
private void importBeatmap() => AddStep("import beatmap", () => importedBeatmap = manager.Import(CreateBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo.BeatmapSet).Result);
private void importBeatmap() => AddStep("import beatmap", () => importedBeatmap = manager.Import(CreateBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo.BeatmapSet).GetResultSafely());
private class TestPlaylistsRoomSubScreen : PlaylistsRoomSubScreen
{

View File

@ -39,7 +39,7 @@ namespace osu.Game.Tests.Visual.Settings
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colours.GreySeafoam
Colour = colours.GreySeaFoam
},
restoreDefaultValueButton = new RestoreDefaultValueButton<float>
{

View File

@ -61,7 +61,7 @@ namespace osu.Game.Tests.Visual.Settings
};
[SettingSource("Sample number textbox", "Textbox number entry", SettingControlType = typeof(SettingsNumberBox))]
public Bindable<int?> IntTextboxBindable { get; } = new Bindable<int?>
public Bindable<int?> IntTextBoxBindable { get; } = new Bindable<int?>
{
Default = null,
Value = null

View File

@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Platform;
using osu.Framework.Testing;
@ -74,7 +75,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep(@"Set beatmap", () =>
{
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
beatmapInfo = beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps.First();
leaderboard.BeatmapInfo = beatmapInfo;
@ -175,7 +176,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep(@"Load new scores via manager", () =>
{
foreach (var score in generateSampleScores(beatmapInfo()))
scoreManager.Import(score).Wait();
scoreManager.Import(score).WaitSafely();
});
}

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Extensions;
@ -181,7 +182,7 @@ namespace osu.Game.Tests.Visual.SongSelect
beatmap.DifficultyName = $"SR{i + 1}";
}
return Game.BeatmapManager.Import(beatmapSet).Result.Value;
return Game.BeatmapManager.Import(beatmapSet).GetResultSafely().Value;
}
private bool ensureAllBeatmapSetsImported(IEnumerable<BeatmapSetInfo> beatmapSets) => beatmapSets.All(set => set != null);

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
@ -38,7 +39,7 @@ namespace osu.Game.Tests.Visual.SongSelect
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, Audio, Resources, host, Beatmap.Default));
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely();
base.Content.AddRange(new Drawable[]
{

View File

@ -8,6 +8,7 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Framework.Testing;
@ -256,7 +257,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("import multi-ruleset map", () =>
{
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
manager.Import(TestResources.CreateTestBeatmapSetInfo(rulesets: usableRulesets)).Wait();
manager.Import(TestResources.CreateTestBeatmapSetInfo(rulesets: usableRulesets)).WaitSafely();
});
}
else
@ -670,7 +671,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("import multi-ruleset map", () =>
{
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
manager.Import(TestResources.CreateTestBeatmapSetInfo(3, usableRulesets)).Wait();
manager.Import(TestResources.CreateTestBeatmapSetInfo(3, usableRulesets)).WaitSafely();
});
int previousSetID = 0;
@ -710,7 +711,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("import multi-ruleset map", () =>
{
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
manager.Import(TestResources.CreateTestBeatmapSetInfo(3, usableRulesets)).Wait();
manager.Import(TestResources.CreateTestBeatmapSetInfo(3, usableRulesets)).WaitSafely();
});
DrawableCarouselBeatmapSet set = null;
@ -759,7 +760,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("import huge difficulty count map", () =>
{
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
imported = manager.Import(TestResources.CreateTestBeatmapSetInfo(50, usableRulesets)).Result.Value;
imported = manager.Import(TestResources.CreateTestBeatmapSetInfo(50, usableRulesets)).GetResultSafely().Value;
});
AddStep("select the first beatmap of import", () => Beatmap.Value = manager.GetWorkingBeatmap(imported.Beatmaps.First()));
@ -868,7 +869,7 @@ namespace osu.Game.Tests.Visual.SongSelect
private void addRulesetImportStep(int id) => AddStep($"import test map for ruleset {id}", () => importForRuleset(id));
private void importForRuleset(int id) => manager.Import(TestResources.CreateTestBeatmapSetInfo(3, rulesets.AvailableRulesets.Where(r => r.OnlineID == id).ToArray())).Wait();
private void importForRuleset(int id) => manager.Import(TestResources.CreateTestBeatmapSetInfo(3, rulesets.AvailableRulesets.Where(r => r.OnlineID == id).ToArray())).WaitSafely();
private void checkMusicPlaying(bool playing) =>
AddUntilStep($"music {(playing ? "" : "not ")}playing", () => music.IsPlaying == playing);
@ -898,7 +899,7 @@ namespace osu.Game.Tests.Visual.SongSelect
var usableRulesets = rulesets.AvailableRulesets.Where(r => r.OnlineID != 2).ToArray();
for (int i = 0; i < 10; i++)
manager.Import(TestResources.CreateTestBeatmapSetInfo(difficultyCountPerSet, usableRulesets)).Wait();
manager.Import(TestResources.CreateTestBeatmapSetInfo(difficultyCountPerSet, usableRulesets)).WaitSafely();
});
}

View File

@ -7,6 +7,7 @@ using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Extensions;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Platform;
using osu.Framework.Testing;
@ -85,7 +86,7 @@ namespace osu.Game.Tests.Visual.UserInterface
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesetStore, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default));
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, ContextFactory, Scheduler));
beatmapInfo = beatmapManager.Import(new ImportTask(TestResources.GetQuickTestBeatmapForImport())).Result.Value.Beatmaps[0];
beatmapInfo = beatmapManager.Import(new ImportTask(TestResources.GetQuickTestBeatmapForImport())).GetResultSafely().Value.Beatmaps[0];
for (int i = 0; i < 50; i++)
{
@ -101,7 +102,7 @@ namespace osu.Game.Tests.Visual.UserInterface
User = new APIUser { Username = "TestUser" },
};
importedScores.Add(scoreManager.Import(score).Result.Value);
importedScores.Add(scoreManager.Import(score).GetResultSafely().Value);
}
return dependencies;

View File

@ -29,10 +29,10 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("Display toast with lengthy text", () => osd.Display(new LengthyToast()));
AddAssert("Toast width is greater than 240", () => osd.Child.Width > 240);
AddRepeatStep("Change toggle (no bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingNoKeybind), 2);
AddRepeatStep("Change toggle (with bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingWithKeybind), 2);
AddRepeatStep("Change enum (no bind)", () => config.IncrementEnumSetting(TestConfigSetting.EnumSettingNoKeybind), 3);
AddRepeatStep("Change enum (with bind)", () => config.IncrementEnumSetting(TestConfigSetting.EnumSettingWithKeybind), 3);
AddRepeatStep("Change toggle (no bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingNoKeyBind), 2);
AddRepeatStep("Change toggle (with bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingWithKeyBind), 2);
AddRepeatStep("Change enum (no bind)", () => config.IncrementEnumSetting(TestConfigSetting.EnumSettingNoKeyBind), 3);
AddRepeatStep("Change enum (with bind)", () => config.IncrementEnumSetting(TestConfigSetting.EnumSettingWithKeyBind), 3);
}
private class TestConfigManager : ConfigManager<TestConfigSetting>
@ -44,10 +44,10 @@ namespace osu.Game.Tests.Visual.UserInterface
protected override void InitialiseDefaults()
{
SetDefault(TestConfigSetting.ToggleSettingNoKeybind, false);
SetDefault(TestConfigSetting.EnumSettingNoKeybind, EnumSetting.Setting1);
SetDefault(TestConfigSetting.ToggleSettingWithKeybind, false);
SetDefault(TestConfigSetting.EnumSettingWithKeybind, EnumSetting.Setting1);
SetDefault(TestConfigSetting.ToggleSettingNoKeyBind, false);
SetDefault(TestConfigSetting.EnumSettingNoKeyBind, EnumSetting.Setting1);
SetDefault(TestConfigSetting.ToggleSettingWithKeyBind, false);
SetDefault(TestConfigSetting.EnumSettingWithKeyBind, EnumSetting.Setting1);
base.InitialiseDefaults();
}
@ -64,10 +64,10 @@ namespace osu.Game.Tests.Visual.UserInterface
public override TrackedSettings CreateTrackedSettings() => new TrackedSettings
{
new TrackedSetting<bool>(TestConfigSetting.ToggleSettingNoKeybind, b => new SettingDescription(b, "toggle setting with no keybind", b ? "enabled" : "disabled")),
new TrackedSetting<EnumSetting>(TestConfigSetting.EnumSettingNoKeybind, v => new SettingDescription(v, "enum setting with no keybind", v.ToString())),
new TrackedSetting<bool>(TestConfigSetting.ToggleSettingWithKeybind, b => new SettingDescription(b, "toggle setting with keybind", b ? "enabled" : "disabled", "fake keybind")),
new TrackedSetting<EnumSetting>(TestConfigSetting.EnumSettingWithKeybind, v => new SettingDescription(v, "enum setting with keybind", v.ToString(), "fake keybind")),
new TrackedSetting<bool>(TestConfigSetting.ToggleSettingNoKeyBind, b => new SettingDescription(b, "toggle setting with no keybind", b ? "enabled" : "disabled")),
new TrackedSetting<EnumSetting>(TestConfigSetting.EnumSettingNoKeyBind, v => new SettingDescription(v, "enum setting with no keybind", v.ToString())),
new TrackedSetting<bool>(TestConfigSetting.ToggleSettingWithKeyBind, b => new SettingDescription(b, "toggle setting with keybind", b ? "enabled" : "disabled", "fake keybind")),
new TrackedSetting<EnumSetting>(TestConfigSetting.EnumSettingWithKeyBind, v => new SettingDescription(v, "enum setting with keybind", v.ToString(), "fake keybind")),
};
protected override void PerformLoad()
@ -79,10 +79,10 @@ namespace osu.Game.Tests.Visual.UserInterface
private enum TestConfigSetting
{
ToggleSettingNoKeybind,
EnumSettingNoKeybind,
ToggleSettingWithKeybind,
EnumSettingWithKeybind
ToggleSettingNoKeyBind,
EnumSettingNoKeyBind,
ToggleSettingWithKeyBind,
EnumSettingWithKeyBind
}
private enum EnumSetting

View File

@ -62,6 +62,6 @@ namespace osu.Game.Tests.Visual.UserInterface
}
private void clearTextboxes(IEnumerable<OsuTextBox> textBoxes) => AddStep("clear textbox", () => textBoxes.ForEach(textBox => textBox.Text = null));
private void expectedValue(IEnumerable<OsuTextBox> textBoxes, string value) => AddAssert("expected textbox value", () => textBoxes.All(textbox => textbox.Text == value));
private void expectedValue(IEnumerable<OsuTextBox> textBoxes, string value) => AddAssert("expected textbox value", () => textBoxes.All(textBox => textBox.Text == value));
}
}

View File

@ -0,0 +1,79 @@
// 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.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface.PageSelector;
using osu.Game.Overlays;
namespace osu.Game.Tests.Visual.UserInterface
{
public class TestScenePageSelector : OsuTestScene
{
[Cached]
private OverlayColourProvider provider { get; } = new OverlayColourProvider(OverlayColourScheme.Green);
private readonly PageSelector pageSelector;
public TestScenePageSelector()
{
AddRange(new Drawable[]
{
pageSelector = new PageSelector
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
});
}
[Test]
public void TestOmittedPages()
{
setAvailablePages(100);
selectPageIndex(0);
checkVisiblePageNumbers(new[] { 1, 2, 3, 100 });
selectPageIndex(6);
checkVisiblePageNumbers(new[] { 1, 5, 6, 7, 8, 9, 100 });
selectPageIndex(49);
checkVisiblePageNumbers(new[] { 1, 48, 49, 50, 51, 52, 100 });
selectPageIndex(99);
checkVisiblePageNumbers(new[] { 1, 98, 99, 100 });
}
[Test]
public void TestResetCurrentPage()
{
setAvailablePages(10);
selectPageIndex(6);
setAvailablePages(11);
AddAssert("Page 1 is current", () => pageSelector.CurrentPage.Value == 0);
}
[Test]
public void TestOutOfBoundsSelection()
{
setAvailablePages(10);
selectPageIndex(11);
AddAssert("Page 10 is current", () => pageSelector.CurrentPage.Value == pageSelector.AvailablePages.Value - 1);
selectPageIndex(-1);
AddAssert("Page 1 is current", () => pageSelector.CurrentPage.Value == 0);
}
private void checkVisiblePageNumbers(int[] expected) => AddAssert($"Sequence is {string.Join(',', expected.Select(i => i.ToString()))}", () => pageSelector.ChildrenOfType<PageSelectorPageButton>().Select(p => p.PageNumber).SequenceEqual(expected));
private void selectPageIndex(int pageIndex) =>
AddStep($"Select page {pageIndex}", () => pageSelector.CurrentPage.Value = pageIndex);
private void setAvailablePages(int availablePages) =>
AddStep($"Set available pages to {availablePages}", () => pageSelector.AvailablePages.Value = availablePages);
}
}

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
@ -31,7 +32,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{
this.api = api;
testBeatmap = ImportBeatmapTest.LoadOszIntoOsu(osu).Result;
testBeatmap = ImportBeatmapTest.LoadOszIntoOsu(osu).GetResultSafely();
}
[Test]

View File

@ -27,7 +27,7 @@ namespace osu.Game.Tests.Visual.UserInterface
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colours.GreySeafoam
Colour = colours.GreySeaFoam
},
CreateContent()
});

View File

@ -36,7 +36,7 @@ namespace osu.Game.Tournament.Tests.NonVisual
TournamentStorage storage = (TournamentStorage)osu.Dependencies.Get<Storage>();
FileBasedIPC ipc = null;
WaitForOrAssert(() => (ipc = osu.Dependencies.Get<MatchIPCInfo>() as FileBasedIPC) != null, @"ipc could not be populated in a reasonable amount of time");
WaitForOrAssert(() => (ipc = osu.Dependencies.Get<MatchIPCInfo>() as FileBasedIPC)?.IsLoaded == true, @"ipc could not be populated in a reasonable amount of time");
Assert.True(ipc.SetIPCLocation(testStableInstallDirectory));
Assert.True(storage.AllTournaments.Exists("stable.json"));

View File

@ -85,14 +85,14 @@ namespace osu.Game.Tournament.Screens.Drawings.Components
private ScrollState scrollState;
private void setScrollState(ScrollState newstate)
private void setScrollState(ScrollState newState)
{
if (scrollState == newstate)
if (scrollState == newState)
return;
delayedStateChangeDelegate?.Cancel();
switch (scrollState = newstate)
switch (scrollState = newState)
{
case ScrollState.Scrolling:
resetSelected();

View File

@ -208,10 +208,10 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
{
if (Match.Round.Value == null) return;
int instaWinAmount = Match.Round.Value.BestOf.Value / 2;
int instantWinAmount = Match.Round.Value.BestOf.Value / 2;
Match.Completed.Value = Match.Round.Value.BestOf.Value > 0
&& (Match.Team1Score.Value + Match.Team2Score.Value >= Match.Round.Value.BestOf.Value || Match.Team1Score.Value > instaWinAmount || Match.Team2Score.Value > instaWinAmount);
&& (Match.Team1Score.Value + Match.Team2Score.Value >= Match.Round.Value.BestOf.Value || Match.Team1Score.Value > instantWinAmount || Match.Team2Score.Value > instantWinAmount);
}
protected override void LoadComplete()

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