mirror of
https://github.com/osukey/osukey.git
synced 2025-08-04 07:06:35 +09:00
Merge remote-tracking branch 'upstream/master' into cache-ruleset-dependencies-for-tests
This commit is contained in:
@ -241,6 +241,11 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
{
|
||||
var controlPoints = decoder.Decode(stream).ControlPointInfo;
|
||||
|
||||
Assert.That(controlPoints.TimingPoints.Count, Is.EqualTo(4));
|
||||
Assert.That(controlPoints.DifficultyPoints.Count, Is.EqualTo(3));
|
||||
Assert.That(controlPoints.EffectPoints.Count, Is.EqualTo(3));
|
||||
Assert.That(controlPoints.SamplePoints.Count, Is.EqualTo(3));
|
||||
|
||||
Assert.That(controlPoints.DifficultyPointAt(500).SpeedMultiplier, Is.EqualTo(1.5).Within(0.1));
|
||||
Assert.That(controlPoints.DifficultyPointAt(1500).SpeedMultiplier, Is.EqualTo(1.5).Within(0.1));
|
||||
Assert.That(controlPoints.DifficultyPointAt(2500).SpeedMultiplier, Is.EqualTo(0.75).Within(0.1));
|
||||
@ -360,7 +365,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
{
|
||||
var hitObjects = decoder.Decode(stream).HitObjects;
|
||||
|
||||
var curveData = hitObjects[0] as IHasCurve;
|
||||
var curveData = hitObjects[0] as IHasPathWithRepeats;
|
||||
var positionData = hitObjects[0] as IHasPosition;
|
||||
|
||||
Assert.IsNotNull(positionData);
|
||||
|
@ -1,14 +1,24 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Beatmaps.Formats;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.IO.Serialization;
|
||||
using osu.Game.Rulesets.Catch;
|
||||
using osu.Game.Rulesets.Mania;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Taiko;
|
||||
using osu.Game.Tests.Resources;
|
||||
|
||||
namespace osu.Game.Tests.Beatmaps.Formats
|
||||
@ -16,39 +26,87 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
[TestFixture]
|
||||
public class LegacyBeatmapEncoderTest
|
||||
{
|
||||
private const string normal = "Soleily - Renatus (Gamu) [Insane].osu";
|
||||
|
||||
private static IEnumerable<string> allBeatmaps => TestResources.GetStore().GetAvailableResources().Where(res => res.EndsWith(".osu"));
|
||||
|
||||
[TestCaseSource(nameof(allBeatmaps))]
|
||||
public void TestDecodeEncodedBeatmap(string name)
|
||||
public void TestEncodeDecodeStability(string name)
|
||||
{
|
||||
var decoded = decode(normal, out var encoded);
|
||||
var decoded = decodeFromLegacy(TestResources.GetStore().GetStream(name));
|
||||
var decodedAfterEncode = decodeFromLegacy(encodeToLegacy(decoded));
|
||||
|
||||
Assert.That(decoded.HitObjects.Count, Is.EqualTo(encoded.HitObjects.Count));
|
||||
Assert.That(encoded.Serialize(), Is.EqualTo(decoded.Serialize()));
|
||||
sort(decoded);
|
||||
sort(decodedAfterEncode);
|
||||
|
||||
Assert.That(decodedAfterEncode.Serialize(), Is.EqualTo(decoded.Serialize()));
|
||||
}
|
||||
|
||||
private Beatmap decode(string filename, out Beatmap encoded)
|
||||
private void sort(IBeatmap beatmap)
|
||||
{
|
||||
using (var stream = TestResources.OpenResource(filename))
|
||||
using (var sr = new LineBufferedReader(stream))
|
||||
// Sort control points to ensure a sane ordering, as they may be parsed in different orders. This works because each group contains only uniquely-typed control points.
|
||||
foreach (var g in beatmap.ControlPointInfo.Groups)
|
||||
{
|
||||
var legacyDecoded = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(sr);
|
||||
|
||||
using (var ms = new MemoryStream())
|
||||
using (var sw = new StreamWriter(ms))
|
||||
using (var sr2 = new LineBufferedReader(ms))
|
||||
{
|
||||
new LegacyBeatmapEncoder(legacyDecoded).Encode(sw);
|
||||
sw.Flush();
|
||||
|
||||
ms.Position = 0;
|
||||
|
||||
encoded = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(sr2);
|
||||
return legacyDecoded;
|
||||
}
|
||||
ArrayList.Adapter((IList)g.ControlPoints).Sort(
|
||||
Comparer<ControlPoint>.Create((c1, c2) => string.Compare(c1.GetType().ToString(), c2.GetType().ToString(), StringComparison.Ordinal)));
|
||||
}
|
||||
}
|
||||
|
||||
private IBeatmap decodeFromLegacy(Stream stream)
|
||||
{
|
||||
using (var reader = new LineBufferedReader(stream))
|
||||
return convert(new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(reader));
|
||||
}
|
||||
|
||||
private Stream encodeToLegacy(IBeatmap beatmap)
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
|
||||
using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true))
|
||||
new LegacyBeatmapEncoder(beatmap).Encode(writer);
|
||||
|
||||
stream.Position = 0;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
private IBeatmap convert(IBeatmap beatmap)
|
||||
{
|
||||
switch (beatmap.BeatmapInfo.RulesetID)
|
||||
{
|
||||
case 0:
|
||||
beatmap.BeatmapInfo.Ruleset = new OsuRuleset().RulesetInfo;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
beatmap.BeatmapInfo.Ruleset = new TaikoRuleset().RulesetInfo;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
beatmap.BeatmapInfo.Ruleset = new CatchRuleset().RulesetInfo;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
beatmap.BeatmapInfo.Ruleset = new ManiaRuleset().RulesetInfo;
|
||||
break;
|
||||
}
|
||||
|
||||
return new TestWorkingBeatmap(beatmap).GetPlayableBeatmap(beatmap.BeatmapInfo.Ruleset);
|
||||
}
|
||||
|
||||
private class TestWorkingBeatmap : WorkingBeatmap
|
||||
{
|
||||
private readonly IBeatmap beatmap;
|
||||
|
||||
public TestWorkingBeatmap(IBeatmap beatmap)
|
||||
: base(beatmap.BeatmapInfo, null)
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
protected override IBeatmap GetBeatmap() => beatmap;
|
||||
|
||||
protected override Texture GetBackground() => throw new NotImplementedException();
|
||||
|
||||
protected override Track GetTrack() => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
var storyboard = decoder.Decode(stream);
|
||||
|
||||
Assert.IsTrue(storyboard.HasDrawable);
|
||||
Assert.AreEqual(5, storyboard.Layers.Count());
|
||||
Assert.AreEqual(6, storyboard.Layers.Count());
|
||||
|
||||
StoryboardLayer background = storyboard.Layers.FirstOrDefault(l => l.Depth == 3);
|
||||
Assert.IsNotNull(background);
|
||||
@ -56,6 +56,13 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
Assert.IsTrue(foreground.VisibleWhenPassing);
|
||||
Assert.AreEqual("Foreground", foreground.Name);
|
||||
|
||||
StoryboardLayer overlay = storyboard.Layers.FirstOrDefault(l => l.Depth == int.MinValue);
|
||||
Assert.IsNotNull(overlay);
|
||||
Assert.IsEmpty(overlay.Elements);
|
||||
Assert.IsTrue(overlay.VisibleWhenFailing);
|
||||
Assert.IsTrue(overlay.VisibleWhenPassing);
|
||||
Assert.AreEqual("Overlay", overlay.Name);
|
||||
|
||||
int spriteCount = background.Elements.Count(x => x.GetType() == typeof(StoryboardSprite));
|
||||
int animationCount = background.Elements.Count(x => x.GetType() == typeof(StoryboardAnimation));
|
||||
int sampleCount = background.Elements.Count(x => x.GetType() == typeof(StoryboardSampleInfo));
|
||||
|
@ -95,7 +95,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
{
|
||||
var beatmap = decodeAsJson(normal);
|
||||
|
||||
var curveData = beatmap.HitObjects[0] as IHasCurve;
|
||||
var curveData = beatmap.HitObjects[0] as IHasPathWithRepeats;
|
||||
var positionData = beatmap.HitObjects[0] as IHasPosition;
|
||||
|
||||
Assert.IsNotNull(positionData);
|
||||
|
@ -5,16 +5,15 @@ using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.IPC;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Formats;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Tests.Resources;
|
||||
@ -22,6 +21,7 @@ using SharpCompress.Archives;
|
||||
using SharpCompress.Archives.Zip;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Writers.Zip;
|
||||
using FileInfo = System.IO.FileInfo;
|
||||
|
||||
namespace osu.Game.Tests.Beatmaps.IO
|
||||
{
|
||||
@ -31,7 +31,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
[Test]
|
||||
public async Task TestImportWhenClosed()
|
||||
{
|
||||
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||
// unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportWhenClosed)))
|
||||
{
|
||||
try
|
||||
@ -48,7 +48,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
[Test]
|
||||
public async Task TestImportThenDelete()
|
||||
{
|
||||
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||
// unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportThenDelete)))
|
||||
{
|
||||
try
|
||||
@ -69,7 +69,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
[Test]
|
||||
public async Task TestImportThenImport()
|
||||
{
|
||||
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||
// unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportThenImport)))
|
||||
{
|
||||
try
|
||||
@ -93,10 +93,170 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestImportThenImportWithReZip()
|
||||
{
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportThenImportWithReZip)))
|
||||
{
|
||||
try
|
||||
{
|
||||
var osu = loadOsu(host);
|
||||
|
||||
var temp = TestResources.GetTestBeatmapForImport();
|
||||
|
||||
string extractedFolder = $"{temp}_extracted";
|
||||
Directory.CreateDirectory(extractedFolder);
|
||||
|
||||
try
|
||||
{
|
||||
var imported = await LoadOszIntoOsu(osu);
|
||||
|
||||
string hashBefore = hashFile(temp);
|
||||
|
||||
using (var zip = ZipArchive.Open(temp))
|
||||
zip.WriteToDirectory(extractedFolder);
|
||||
|
||||
using (var zip = ZipArchive.Create())
|
||||
{
|
||||
zip.AddAllFromDirectory(extractedFolder);
|
||||
zip.SaveTo(temp, new ZipWriterOptions(CompressionType.Deflate));
|
||||
}
|
||||
|
||||
// zip files differ because different compression or encoder.
|
||||
Assert.AreNotEqual(hashBefore, hashFile(temp));
|
||||
|
||||
var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(temp);
|
||||
|
||||
ensureLoaded(osu);
|
||||
|
||||
// but contents doesn't, so existing should still be used.
|
||||
Assert.IsTrue(imported.ID == importedSecondTime.ID);
|
||||
Assert.IsTrue(imported.Beatmaps.First().ID == importedSecondTime.Beatmaps.First().ID);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Directory.Delete(extractedFolder, true);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string hashFile(string filename)
|
||||
{
|
||||
using (var s = File.OpenRead(filename))
|
||||
return s.ComputeMD5Hash();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestImportThenImportWithChangedFile()
|
||||
{
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportThenImportWithChangedFile)))
|
||||
{
|
||||
try
|
||||
{
|
||||
var osu = loadOsu(host);
|
||||
|
||||
var temp = TestResources.GetTestBeatmapForImport();
|
||||
|
||||
string extractedFolder = $"{temp}_extracted";
|
||||
Directory.CreateDirectory(extractedFolder);
|
||||
|
||||
try
|
||||
{
|
||||
var imported = await LoadOszIntoOsu(osu);
|
||||
|
||||
using (var zip = ZipArchive.Open(temp))
|
||||
zip.WriteToDirectory(extractedFolder);
|
||||
|
||||
// arbitrary write to non-hashed file
|
||||
using (var sw = new FileInfo(Directory.GetFiles(extractedFolder, "*.mp3").First()).AppendText())
|
||||
await sw.WriteLineAsync("text");
|
||||
|
||||
using (var zip = ZipArchive.Create())
|
||||
{
|
||||
zip.AddAllFromDirectory(extractedFolder);
|
||||
zip.SaveTo(temp, new ZipWriterOptions(CompressionType.Deflate));
|
||||
}
|
||||
|
||||
var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(temp);
|
||||
|
||||
ensureLoaded(osu);
|
||||
|
||||
// check the newly "imported" beatmap is not the original.
|
||||
Assert.IsTrue(imported.ID != importedSecondTime.ID);
|
||||
Assert.IsTrue(imported.Beatmaps.First().ID != importedSecondTime.Beatmaps.First().ID);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Directory.Delete(extractedFolder, true);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestImportThenImportWithDifferentFilename()
|
||||
{
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportThenImportWithDifferentFilename)))
|
||||
{
|
||||
try
|
||||
{
|
||||
var osu = loadOsu(host);
|
||||
|
||||
var temp = TestResources.GetTestBeatmapForImport();
|
||||
|
||||
string extractedFolder = $"{temp}_extracted";
|
||||
Directory.CreateDirectory(extractedFolder);
|
||||
|
||||
try
|
||||
{
|
||||
var imported = await LoadOszIntoOsu(osu);
|
||||
|
||||
using (var zip = ZipArchive.Open(temp))
|
||||
zip.WriteToDirectory(extractedFolder);
|
||||
|
||||
// change filename
|
||||
var firstFile = new FileInfo(Directory.GetFiles(extractedFolder).First());
|
||||
firstFile.MoveTo(Path.Combine(firstFile.DirectoryName, $"{firstFile.Name}-changed{firstFile.Extension}"));
|
||||
|
||||
using (var zip = ZipArchive.Create())
|
||||
{
|
||||
zip.AddAllFromDirectory(extractedFolder);
|
||||
zip.SaveTo(temp, new ZipWriterOptions(CompressionType.Deflate));
|
||||
}
|
||||
|
||||
var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(temp);
|
||||
|
||||
ensureLoaded(osu);
|
||||
|
||||
// check the newly "imported" beatmap is not the original.
|
||||
Assert.IsTrue(imported.ID != importedSecondTime.ID);
|
||||
Assert.IsTrue(imported.Beatmaps.First().ID != importedSecondTime.Beatmaps.First().ID);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Directory.Delete(extractedFolder, true);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestImportCorruptThenImport()
|
||||
{
|
||||
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||
// unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportCorruptThenImport)))
|
||||
{
|
||||
try
|
||||
@ -138,7 +298,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
[Test]
|
||||
public async Task TestRollbackOnFailure()
|
||||
{
|
||||
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||
// unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestRollbackOnFailure)))
|
||||
{
|
||||
try
|
||||
@ -156,8 +316,8 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
var manager = osu.Dependencies.Get<BeatmapManager>();
|
||||
|
||||
// ReSharper disable once AccessToModifiedClosure
|
||||
manager.ItemAdded += _ => Interlocked.Increment(ref itemAddRemoveFireCount);
|
||||
manager.ItemRemoved += _ => Interlocked.Increment(ref itemAddRemoveFireCount);
|
||||
manager.ItemUpdated.BindValueChanged(_ => Interlocked.Increment(ref itemAddRemoveFireCount));
|
||||
manager.ItemRemoved.BindValueChanged(_ => Interlocked.Increment(ref itemAddRemoveFireCount));
|
||||
|
||||
var imported = await LoadOszIntoOsu(osu);
|
||||
|
||||
@ -166,7 +326,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
imported.Hash += "-changed";
|
||||
manager.Update(imported);
|
||||
|
||||
Assert.AreEqual(0, itemAddRemoveFireCount -= 2);
|
||||
Assert.AreEqual(0, itemAddRemoveFireCount -= 1);
|
||||
|
||||
checkBeatmapSetCount(osu, 1);
|
||||
checkBeatmapCount(osu, 12);
|
||||
@ -175,7 +335,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
var breakTemp = TestResources.GetTestBeatmapForImport();
|
||||
|
||||
MemoryStream brokenOsu = new MemoryStream();
|
||||
MemoryStream brokenOsz = new MemoryStream(File.ReadAllBytes(breakTemp));
|
||||
MemoryStream brokenOsz = new MemoryStream(await File.ReadAllBytesAsync(breakTemp));
|
||||
|
||||
File.Delete(breakTemp);
|
||||
|
||||
@ -212,41 +372,10 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestImportThenImportDifferentHash()
|
||||
{
|
||||
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportThenImportDifferentHash)))
|
||||
{
|
||||
try
|
||||
{
|
||||
var osu = loadOsu(host);
|
||||
var manager = osu.Dependencies.Get<BeatmapManager>();
|
||||
|
||||
var imported = await LoadOszIntoOsu(osu);
|
||||
|
||||
imported.Hash += "-changed";
|
||||
manager.Update(imported);
|
||||
|
||||
var importedSecondTime = await LoadOszIntoOsu(osu);
|
||||
|
||||
Assert.IsTrue(imported.ID != importedSecondTime.ID);
|
||||
Assert.IsTrue(imported.Beatmaps.First().ID < importedSecondTime.Beatmaps.First().ID);
|
||||
|
||||
// only one beatmap will exist as the online set ID matched, causing purging of the first import.
|
||||
checkBeatmapSetCount(osu, 1);
|
||||
}
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestImportThenDeleteThenImport()
|
||||
{
|
||||
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||
// unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportThenDeleteThenImport)))
|
||||
{
|
||||
try
|
||||
@ -274,7 +403,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
[TestCase(false)]
|
||||
public async Task TestImportThenDeleteThenImportWithOnlineIDMismatch(bool set)
|
||||
{
|
||||
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||
// unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost($"{nameof(TestImportThenDeleteThenImportWithOnlineIDMismatch)}-{set}"))
|
||||
{
|
||||
try
|
||||
@ -308,7 +437,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
[Test]
|
||||
public async Task TestImportWithDuplicateBeatmapIDs()
|
||||
{
|
||||
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||
// unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestImportWithDuplicateBeatmapIDs)))
|
||||
{
|
||||
try
|
||||
@ -522,7 +651,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
|
||||
using (var resourceForkFile = File.CreateText(resourceForkFilePath))
|
||||
{
|
||||
resourceForkFile.WriteLine("adding content so that it's not empty");
|
||||
await resourceForkFile.WriteLineAsync("adding content so that it's not empty");
|
||||
}
|
||||
|
||||
try
|
||||
@ -599,23 +728,17 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
await osu.Dependencies.Get<BeatmapManager>().Import(temp);
|
||||
|
||||
BeatmapSetInfo setToUpdate = manager.GetAllUsableBeatmapSets()[0];
|
||||
|
||||
var beatmapInfo = setToUpdate.Beatmaps.First(b => b.RulesetID == 0);
|
||||
Beatmap beatmapToUpdate = (Beatmap)manager.GetWorkingBeatmap(setToUpdate.Beatmaps.First(b => b.RulesetID == 0)).Beatmap;
|
||||
BeatmapSetFileInfo fileToUpdate = setToUpdate.Files.First(f => beatmapToUpdate.BeatmapInfo.Path.Contains(f.Filename));
|
||||
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true))
|
||||
{
|
||||
beatmapToUpdate.HitObjects.Clear();
|
||||
beatmapToUpdate.HitObjects.Add(new HitCircle { StartTime = 5000 });
|
||||
string oldMd5Hash = beatmapToUpdate.BeatmapInfo.MD5Hash;
|
||||
|
||||
new LegacyBeatmapEncoder(beatmapToUpdate).Encode(writer);
|
||||
}
|
||||
beatmapToUpdate.HitObjects.Clear();
|
||||
beatmapToUpdate.HitObjects.Add(new HitCircle { StartTime = 5000 });
|
||||
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
manager.UpdateFile(setToUpdate, fileToUpdate, stream);
|
||||
}
|
||||
manager.Save(beatmapInfo, beatmapToUpdate);
|
||||
|
||||
// Check that the old file reference has been removed
|
||||
Assert.That(manager.QueryBeatmapSet(s => s.ID == setToUpdate.ID).Files.All(f => f.ID != fileToUpdate.ID));
|
||||
@ -624,6 +747,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
Beatmap updatedBeatmap = (Beatmap)manager.GetWorkingBeatmap(manager.QueryBeatmap(b => b.ID == beatmapToUpdate.BeatmapInfo.ID)).Beatmap;
|
||||
Assert.That(updatedBeatmap.HitObjects.Count, Is.EqualTo(1));
|
||||
Assert.That(updatedBeatmap.HitObjects[0].StartTime, Is.EqualTo(5000));
|
||||
Assert.That(updatedBeatmap.BeatmapInfo.MD5Hash, Is.Not.EqualTo(oldMd5Hash));
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -695,12 +819,12 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
waitForOrAssert(() => (resultSets = store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526)).Any(),
|
||||
@"BeatmapSet did not import to the database in allocated time.", timeout);
|
||||
|
||||
//ensure we were stored to beatmap database backing...
|
||||
// ensure we were stored to beatmap database backing...
|
||||
Assert.IsTrue(resultSets.Count() == 1, $@"Incorrect result count found ({resultSets.Count()} but should be 1).");
|
||||
IEnumerable<BeatmapInfo> queryBeatmaps() => store.QueryBeatmaps(s => s.BeatmapSet.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0);
|
||||
IEnumerable<BeatmapSetInfo> queryBeatmapSets() => store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526);
|
||||
|
||||
//if we don't re-check here, the set will be inserted but the beatmaps won't be present yet.
|
||||
// if we don't re-check here, the set will be inserted but the beatmaps won't be present yet.
|
||||
waitForOrAssert(() => queryBeatmaps().Count() == 12,
|
||||
@"Beatmaps did not import to the database in allocated time", timeout);
|
||||
waitForOrAssert(() => queryBeatmapSets().Count() == 1,
|
||||
|
@ -16,7 +16,7 @@ namespace osu.Game.Tests.Beatmaps
|
||||
[Test]
|
||||
public void TestSingleSpan()
|
||||
{
|
||||
var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 1, null).ToArray();
|
||||
var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 1, null, default).ToArray();
|
||||
|
||||
Assert.That(events[0].Type, Is.EqualTo(SliderEventType.Head));
|
||||
Assert.That(events[0].Time, Is.EqualTo(start_time));
|
||||
@ -31,7 +31,7 @@ namespace osu.Game.Tests.Beatmaps
|
||||
[Test]
|
||||
public void TestRepeat()
|
||||
{
|
||||
var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 2, null).ToArray();
|
||||
var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 2, null, default).ToArray();
|
||||
|
||||
Assert.That(events[0].Type, Is.EqualTo(SliderEventType.Head));
|
||||
Assert.That(events[0].Time, Is.EqualTo(start_time));
|
||||
@ -52,7 +52,7 @@ namespace osu.Game.Tests.Beatmaps
|
||||
[Test]
|
||||
public void TestNonEvenTicks()
|
||||
{
|
||||
var events = SliderEventGenerator.Generate(start_time, span_duration, 1, 300, span_duration, 2, null).ToArray();
|
||||
var events = SliderEventGenerator.Generate(start_time, span_duration, 1, 300, span_duration, 2, null, default).ToArray();
|
||||
|
||||
Assert.That(events[0].Type, Is.EqualTo(SliderEventType.Head));
|
||||
Assert.That(events[0].Time, Is.EqualTo(start_time));
|
||||
@ -85,7 +85,7 @@ namespace osu.Game.Tests.Beatmaps
|
||||
[Test]
|
||||
public void TestLegacyLastTickOffset()
|
||||
{
|
||||
var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 1, 100).ToArray();
|
||||
var events = SliderEventGenerator.Generate(start_time, span_duration, 1, span_duration / 2, span_duration, 1, 100, default).ToArray();
|
||||
|
||||
Assert.That(events[2].Type, Is.EqualTo(SliderEventType.LegacyLastTick));
|
||||
Assert.That(events[2].Time, Is.EqualTo(900));
|
||||
@ -97,7 +97,7 @@ namespace osu.Game.Tests.Beatmaps
|
||||
const double velocity = 5;
|
||||
const double min_distance = velocity * 10;
|
||||
|
||||
var events = SliderEventGenerator.Generate(start_time, span_duration, velocity, velocity, span_duration, 2, 0).ToArray();
|
||||
var events = SliderEventGenerator.Generate(start_time, span_duration, velocity, velocity, span_duration, 2, 0, default).ToArray();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
|
@ -1,9 +1,9 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
@ -137,7 +137,7 @@ namespace osu.Game.Tests.Beatmaps
|
||||
var hitCircle = new HitCircle { StartTime = 1000 };
|
||||
editorBeatmap.Add(hitCircle);
|
||||
Assert.That(editorBeatmap.HitObjects.Count(h => h == hitCircle), Is.EqualTo(1));
|
||||
Assert.That(editorBeatmap.HitObjects.IndexOf(hitCircle), Is.EqualTo(3));
|
||||
Assert.That(Array.IndexOf(editorBeatmap.HitObjects.ToArray(), hitCircle), Is.EqualTo(3));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -161,7 +161,7 @@ namespace osu.Game.Tests.Beatmaps
|
||||
|
||||
hitCircle.StartTime = 0;
|
||||
Assert.That(editorBeatmap.HitObjects.Count(h => h == hitCircle), Is.EqualTo(1));
|
||||
Assert.That(editorBeatmap.HitObjects.IndexOf(hitCircle), Is.EqualTo(1));
|
||||
Assert.That(Array.IndexOf(editorBeatmap.HitObjects.ToArray(), hitCircle), Is.EqualTo(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
61
osu.Game.Tests/Beatmaps/ToStringFormattingTest.cs
Normal file
61
osu.Game.Tests/Beatmaps/ToStringFormattingTest.cs
Normal file
@ -0,0 +1,61 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Beatmaps
|
||||
{
|
||||
[TestFixture]
|
||||
public class ToStringFormattingTest
|
||||
{
|
||||
[Test]
|
||||
public void TestArtistTitle()
|
||||
{
|
||||
var beatmap = new BeatmapInfo
|
||||
{
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Artist = "artist",
|
||||
Title = "title"
|
||||
}
|
||||
};
|
||||
|
||||
Assert.That(beatmap.ToString(), Is.EqualTo("artist - title"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestArtistTitleCreator()
|
||||
{
|
||||
var beatmap = new BeatmapInfo
|
||||
{
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Artist = "artist",
|
||||
Title = "title",
|
||||
Author = new User { Username = "creator" }
|
||||
}
|
||||
};
|
||||
|
||||
Assert.That(beatmap.ToString(), Is.EqualTo("artist - title (creator)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestArtistTitleCreatorDifficulty()
|
||||
{
|
||||
var beatmap = new BeatmapInfo
|
||||
{
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Artist = "artist",
|
||||
Title = "title",
|
||||
Author = new User { Username = "creator" }
|
||||
},
|
||||
Version = "difficulty"
|
||||
};
|
||||
|
||||
Assert.That(beatmap.ToString(), Is.EqualTo("artist - title (creator) [difficulty]"));
|
||||
}
|
||||
}
|
||||
}
|
@ -428,22 +428,27 @@ namespace osu.Game.Tests.Chat
|
||||
Assert.AreEqual(5, result.Links.Count);
|
||||
|
||||
Link f = result.Links.Find(l => l.Url == "https://osu.ppy.sh/wiki/wiki links");
|
||||
Assert.That(f, Is.Not.Null);
|
||||
Assert.AreEqual(44, f.Index);
|
||||
Assert.AreEqual(10, f.Length);
|
||||
|
||||
f = result.Links.Find(l => l.Url == "http://www.simple-test.com");
|
||||
Assert.That(f, Is.Not.Null);
|
||||
Assert.AreEqual(10, f.Index);
|
||||
Assert.AreEqual(11, f.Length);
|
||||
|
||||
f = result.Links.Find(l => l.Url == "http://google.com");
|
||||
Assert.That(f, Is.Not.Null);
|
||||
Assert.AreEqual(97, f.Index);
|
||||
Assert.AreEqual(4, f.Length);
|
||||
|
||||
f = result.Links.Find(l => l.Url == "https://osu.ppy.sh");
|
||||
Assert.That(f, Is.Not.Null);
|
||||
Assert.AreEqual(78, f.Index);
|
||||
Assert.AreEqual(18, f.Length);
|
||||
|
||||
f = result.Links.Find(l => l.Url == "\uD83D\uDE12");
|
||||
Assert.That(f, Is.Not.Null);
|
||||
Assert.AreEqual(101, f.Index);
|
||||
Assert.AreEqual(3, f.Length);
|
||||
}
|
||||
|
74
osu.Game.Tests/Editing/EditorChangeHandlerTest.cs
Normal file
74
osu.Game.Tests/Editing/EditorChangeHandlerTest.cs
Normal file
@ -0,0 +1,74 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Screens.Edit;
|
||||
|
||||
namespace osu.Game.Tests.Editing
|
||||
{
|
||||
[TestFixture]
|
||||
public class EditorChangeHandlerTest
|
||||
{
|
||||
[Test]
|
||||
public void TestSaveRestoreState()
|
||||
{
|
||||
var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap()));
|
||||
|
||||
Assert.That(handler.CanUndo.Value, Is.False);
|
||||
Assert.That(handler.CanRedo.Value, Is.False);
|
||||
|
||||
handler.SaveState();
|
||||
|
||||
Assert.That(handler.CanUndo.Value, Is.True);
|
||||
Assert.That(handler.CanRedo.Value, Is.False);
|
||||
|
||||
handler.RestoreState(-1);
|
||||
|
||||
Assert.That(handler.CanUndo.Value, Is.False);
|
||||
Assert.That(handler.CanRedo.Value, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMaxStatesSaved()
|
||||
{
|
||||
var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap()));
|
||||
|
||||
Assert.That(handler.CanUndo.Value, Is.False);
|
||||
|
||||
for (int i = 0; i < EditorChangeHandler.MAX_SAVED_STATES; i++)
|
||||
handler.SaveState();
|
||||
|
||||
Assert.That(handler.CanUndo.Value, Is.True);
|
||||
|
||||
for (int i = 0; i < EditorChangeHandler.MAX_SAVED_STATES; i++)
|
||||
{
|
||||
Assert.That(handler.CanUndo.Value, Is.True);
|
||||
handler.RestoreState(-1);
|
||||
}
|
||||
|
||||
Assert.That(handler.CanUndo.Value, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMaxStatesExceeded()
|
||||
{
|
||||
var handler = new EditorChangeHandler(new EditorBeatmap(new Beatmap()));
|
||||
|
||||
Assert.That(handler.CanUndo.Value, Is.False);
|
||||
|
||||
for (int i = 0; i < EditorChangeHandler.MAX_SAVED_STATES * 2; i++)
|
||||
handler.SaveState();
|
||||
|
||||
Assert.That(handler.CanUndo.Value, Is.True);
|
||||
|
||||
for (int i = 0; i < EditorChangeHandler.MAX_SAVED_STATES; i++)
|
||||
{
|
||||
Assert.That(handler.CanUndo.Value, Is.True);
|
||||
handler.RestoreState(-1);
|
||||
}
|
||||
|
||||
Assert.That(handler.CanUndo.Value, Is.False);
|
||||
}
|
||||
}
|
||||
}
|
367
osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs
Normal file
367
osu.Game.Tests/Editing/LegacyEditorBeatmapPatcherTest.cs
Normal file
@ -0,0 +1,367 @@
|
||||
// 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.IO;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Formats;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osuTK;
|
||||
using Decoder = osu.Game.Beatmaps.Formats.Decoder;
|
||||
|
||||
namespace osu.Game.Tests.Editing
|
||||
{
|
||||
[TestFixture]
|
||||
public class LegacyEditorBeatmapPatcherTest
|
||||
{
|
||||
private LegacyEditorBeatmapPatcher patcher;
|
||||
private EditorBeatmap current;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
patcher = new LegacyEditorBeatmapPatcher(current = new EditorBeatmap(new OsuBeatmap
|
||||
{
|
||||
BeatmapInfo =
|
||||
{
|
||||
Ruleset = new OsuRuleset().RulesetInfo
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddHitObject()
|
||||
{
|
||||
var patch = new OsuBeatmap
|
||||
{
|
||||
HitObjects =
|
||||
{
|
||||
new HitCircle { StartTime = 1000 }
|
||||
}
|
||||
};
|
||||
|
||||
runTest(patch);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestInsertHitObject()
|
||||
{
|
||||
current.AddRange(new[]
|
||||
{
|
||||
new HitCircle { StartTime = 1000 },
|
||||
new HitCircle { StartTime = 3000 },
|
||||
});
|
||||
|
||||
var patch = new OsuBeatmap
|
||||
{
|
||||
HitObjects =
|
||||
{
|
||||
(OsuHitObject)current.HitObjects[0],
|
||||
new HitCircle { StartTime = 2000 },
|
||||
(OsuHitObject)current.HitObjects[1],
|
||||
}
|
||||
};
|
||||
|
||||
runTest(patch);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDeleteHitObject()
|
||||
{
|
||||
current.AddRange(new[]
|
||||
{
|
||||
new HitCircle { StartTime = 1000 },
|
||||
new HitCircle { StartTime = 2000 },
|
||||
new HitCircle { StartTime = 3000 },
|
||||
});
|
||||
|
||||
var patch = new OsuBeatmap
|
||||
{
|
||||
HitObjects =
|
||||
{
|
||||
(OsuHitObject)current.HitObjects[0],
|
||||
(OsuHitObject)current.HitObjects[2],
|
||||
}
|
||||
};
|
||||
|
||||
runTest(patch);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestChangeStartTime()
|
||||
{
|
||||
current.AddRange(new[]
|
||||
{
|
||||
new HitCircle { StartTime = 1000 },
|
||||
new HitCircle { StartTime = 2000 },
|
||||
new HitCircle { StartTime = 3000 },
|
||||
});
|
||||
|
||||
var patch = new OsuBeatmap
|
||||
{
|
||||
HitObjects =
|
||||
{
|
||||
new HitCircle { StartTime = 500 },
|
||||
(OsuHitObject)current.HitObjects[1],
|
||||
(OsuHitObject)current.HitObjects[2],
|
||||
}
|
||||
};
|
||||
|
||||
runTest(patch);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestChangeSample()
|
||||
{
|
||||
current.AddRange(new[]
|
||||
{
|
||||
new HitCircle { StartTime = 1000 },
|
||||
new HitCircle { StartTime = 2000 },
|
||||
new HitCircle { StartTime = 3000 },
|
||||
});
|
||||
|
||||
var patch = new OsuBeatmap
|
||||
{
|
||||
HitObjects =
|
||||
{
|
||||
(OsuHitObject)current.HitObjects[0],
|
||||
new HitCircle { StartTime = 2000, Samples = { new HitSampleInfo { Name = HitSampleInfo.HIT_FINISH } } },
|
||||
(OsuHitObject)current.HitObjects[2],
|
||||
}
|
||||
};
|
||||
|
||||
runTest(patch);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestChangeSliderPath()
|
||||
{
|
||||
current.AddRange(new OsuHitObject[]
|
||||
{
|
||||
new HitCircle { StartTime = 1000 },
|
||||
new Slider
|
||||
{
|
||||
StartTime = 2000,
|
||||
Path = new SliderPath(new[]
|
||||
{
|
||||
new PathControlPoint(Vector2.Zero),
|
||||
new PathControlPoint(Vector2.One),
|
||||
new PathControlPoint(new Vector2(2), PathType.Bezier),
|
||||
new PathControlPoint(new Vector2(3)),
|
||||
}, 50)
|
||||
},
|
||||
new HitCircle { StartTime = 3000 },
|
||||
});
|
||||
|
||||
var patch = new OsuBeatmap
|
||||
{
|
||||
HitObjects =
|
||||
{
|
||||
(OsuHitObject)current.HitObjects[0],
|
||||
new Slider
|
||||
{
|
||||
StartTime = 2000,
|
||||
Path = new SliderPath(new[]
|
||||
{
|
||||
new PathControlPoint(Vector2.Zero, PathType.Bezier),
|
||||
new PathControlPoint(new Vector2(4)),
|
||||
new PathControlPoint(new Vector2(5)),
|
||||
}, 100)
|
||||
},
|
||||
(OsuHitObject)current.HitObjects[2],
|
||||
}
|
||||
};
|
||||
|
||||
runTest(patch);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddMultipleHitObjects()
|
||||
{
|
||||
current.AddRange(new[]
|
||||
{
|
||||
new HitCircle { StartTime = 1000 },
|
||||
new HitCircle { StartTime = 2000 },
|
||||
new HitCircle { StartTime = 3000 },
|
||||
});
|
||||
|
||||
var patch = new OsuBeatmap
|
||||
{
|
||||
HitObjects =
|
||||
{
|
||||
new HitCircle { StartTime = 500 },
|
||||
(OsuHitObject)current.HitObjects[0],
|
||||
new HitCircle { StartTime = 1500 },
|
||||
(OsuHitObject)current.HitObjects[1],
|
||||
new HitCircle { StartTime = 2250 },
|
||||
new HitCircle { StartTime = 2500 },
|
||||
(OsuHitObject)current.HitObjects[2],
|
||||
new HitCircle { StartTime = 3500 },
|
||||
}
|
||||
};
|
||||
|
||||
runTest(patch);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDeleteMultipleHitObjects()
|
||||
{
|
||||
current.AddRange(new[]
|
||||
{
|
||||
new HitCircle { StartTime = 500 },
|
||||
new HitCircle { StartTime = 1000 },
|
||||
new HitCircle { StartTime = 1500 },
|
||||
new HitCircle { StartTime = 2000 },
|
||||
new HitCircle { StartTime = 2250 },
|
||||
new HitCircle { StartTime = 2500 },
|
||||
new HitCircle { StartTime = 3000 },
|
||||
new HitCircle { StartTime = 3500 },
|
||||
});
|
||||
|
||||
var patch = new OsuBeatmap
|
||||
{
|
||||
HitObjects =
|
||||
{
|
||||
(OsuHitObject)current.HitObjects[1],
|
||||
(OsuHitObject)current.HitObjects[3],
|
||||
(OsuHitObject)current.HitObjects[6],
|
||||
}
|
||||
};
|
||||
|
||||
runTest(patch);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestChangeSamplesOfMultipleHitObjects()
|
||||
{
|
||||
current.AddRange(new[]
|
||||
{
|
||||
new HitCircle { StartTime = 500 },
|
||||
new HitCircle { StartTime = 1000 },
|
||||
new HitCircle { StartTime = 1500 },
|
||||
new HitCircle { StartTime = 2000 },
|
||||
new HitCircle { StartTime = 2250 },
|
||||
new HitCircle { StartTime = 2500 },
|
||||
new HitCircle { StartTime = 3000 },
|
||||
new HitCircle { StartTime = 3500 },
|
||||
});
|
||||
|
||||
var patch = new OsuBeatmap
|
||||
{
|
||||
HitObjects =
|
||||
{
|
||||
(OsuHitObject)current.HitObjects[0],
|
||||
new HitCircle { StartTime = 1000, Samples = { new HitSampleInfo { Name = HitSampleInfo.HIT_FINISH } } },
|
||||
(OsuHitObject)current.HitObjects[2],
|
||||
(OsuHitObject)current.HitObjects[3],
|
||||
new HitCircle { StartTime = 2250, Samples = { new HitSampleInfo { Name = HitSampleInfo.HIT_WHISTLE } } },
|
||||
(OsuHitObject)current.HitObjects[5],
|
||||
new HitCircle { StartTime = 3000, Samples = { new HitSampleInfo { Name = HitSampleInfo.HIT_CLAP } } },
|
||||
(OsuHitObject)current.HitObjects[7],
|
||||
}
|
||||
};
|
||||
|
||||
runTest(patch);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddAndDeleteHitObjects()
|
||||
{
|
||||
current.AddRange(new[]
|
||||
{
|
||||
new HitCircle { StartTime = 500 },
|
||||
new HitCircle { StartTime = 1000 },
|
||||
new HitCircle { StartTime = 1500 },
|
||||
new HitCircle { StartTime = 2000 },
|
||||
new HitCircle { StartTime = 2250 },
|
||||
new HitCircle { StartTime = 2500 },
|
||||
new HitCircle { StartTime = 3000 },
|
||||
new HitCircle { StartTime = 3500 },
|
||||
});
|
||||
|
||||
var patch = new OsuBeatmap
|
||||
{
|
||||
HitObjects =
|
||||
{
|
||||
new HitCircle { StartTime = 750 },
|
||||
(OsuHitObject)current.HitObjects[1],
|
||||
(OsuHitObject)current.HitObjects[4],
|
||||
(OsuHitObject)current.HitObjects[5],
|
||||
new HitCircle { StartTime = 2650 },
|
||||
new HitCircle { StartTime = 2750 },
|
||||
new HitCircle { StartTime = 4000 },
|
||||
}
|
||||
};
|
||||
|
||||
runTest(patch);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestChangeHitObjectAtSameTime()
|
||||
{
|
||||
current.AddRange(new[]
|
||||
{
|
||||
new HitCircle { StartTime = 500, Position = new Vector2(50) },
|
||||
new HitCircle { StartTime = 500, Position = new Vector2(100) },
|
||||
new HitCircle { StartTime = 500, Position = new Vector2(150) },
|
||||
new HitCircle { StartTime = 500, Position = new Vector2(200) },
|
||||
});
|
||||
|
||||
var patch = new OsuBeatmap
|
||||
{
|
||||
HitObjects =
|
||||
{
|
||||
new HitCircle { StartTime = 500, Position = new Vector2(150) },
|
||||
new HitCircle { StartTime = 500, Position = new Vector2(100) },
|
||||
new HitCircle { StartTime = 500, Position = new Vector2(50) },
|
||||
new HitCircle { StartTime = 500, Position = new Vector2(200) },
|
||||
}
|
||||
};
|
||||
|
||||
runTest(patch);
|
||||
}
|
||||
|
||||
private void runTest(IBeatmap patch)
|
||||
{
|
||||
// Due to the method of testing, "patch" comes in without having been decoded via a beatmap decoder.
|
||||
// This causes issues because the decoder adds various default properties (e.g. new combo on first object, default samples).
|
||||
// To resolve "patch" into a sane state it is encoded and then re-decoded.
|
||||
patch = decode(encode(patch));
|
||||
|
||||
// Apply the patch.
|
||||
patcher.Patch(encode(current), encode(patch));
|
||||
|
||||
// Convert beatmaps to strings for assertion purposes.
|
||||
string currentStr = Encoding.ASCII.GetString(encode(current));
|
||||
string patchStr = Encoding.ASCII.GetString(encode(patch));
|
||||
|
||||
Assert.That(currentStr, Is.EqualTo(patchStr));
|
||||
}
|
||||
|
||||
private byte[] encode(IBeatmap beatmap)
|
||||
{
|
||||
using (var encoded = new MemoryStream())
|
||||
{
|
||||
using (var sw = new StreamWriter(encoded))
|
||||
new LegacyBeatmapEncoder(beatmap).Encode(sw);
|
||||
|
||||
return encoded.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private IBeatmap decode(byte[] state)
|
||||
{
|
||||
using (var stream = new MemoryStream(state))
|
||||
using (var reader = new LineBufferedReader(stream))
|
||||
return Decoder.GetDecoder<Beatmap>(reader).Decode(reader);
|
||||
}
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ using osu.Game.Rulesets.Osu.Edit;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Tests.Visual;
|
||||
|
||||
namespace osu.Game.Tests.Editor
|
||||
namespace osu.Game.Tests.Editing
|
||||
{
|
||||
[HeadlessTest]
|
||||
public class TestSceneHitObjectComposerDistanceSnapping : EditorClockTestScene
|
@ -2,12 +2,12 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Timing;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
@ -18,7 +18,6 @@ namespace osu.Game.Tests.Gameplay
|
||||
[HeadlessTest]
|
||||
public class TestSceneDrainingHealthProcessor : OsuTestScene
|
||||
{
|
||||
private Bindable<bool> breakTime;
|
||||
private HealthProcessor processor;
|
||||
private ManualClock clock;
|
||||
|
||||
@ -41,6 +40,64 @@ namespace osu.Game.Tests.Gameplay
|
||||
assertHealthEqualTo(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHealthDrainBetweenBreakAndObjects()
|
||||
{
|
||||
createProcessor(createBeatmap(0, 2000, new BreakPeriod(325, 375)));
|
||||
|
||||
// 275 300 325 350 375 400 425
|
||||
// hitobjects o o
|
||||
// break [-------------]
|
||||
// no drain [---------------------------]
|
||||
|
||||
setTime(285);
|
||||
setHealth(1);
|
||||
|
||||
setTime(295);
|
||||
assertHealthNotEqualTo(1);
|
||||
|
||||
setTime(305);
|
||||
setHealth(1);
|
||||
|
||||
setTime(315);
|
||||
assertHealthEqualTo(1);
|
||||
|
||||
setTime(365);
|
||||
assertHealthEqualTo(1);
|
||||
|
||||
setTime(395);
|
||||
assertHealthEqualTo(1);
|
||||
|
||||
setTime(425);
|
||||
assertHealthNotEqualTo(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHealthDrainDuringMaximalBreak()
|
||||
{
|
||||
createProcessor(createBeatmap(0, 2000, new BreakPeriod(300, 400)));
|
||||
|
||||
// 275 300 325 350 375 400 425
|
||||
// hitobjects o o
|
||||
// break [---------------------------]
|
||||
// no drain [---------------------------]
|
||||
|
||||
setTime(285);
|
||||
setHealth(1);
|
||||
|
||||
setTime(295);
|
||||
assertHealthNotEqualTo(1);
|
||||
|
||||
setTime(305);
|
||||
setHealth(1);
|
||||
|
||||
setTime(395);
|
||||
assertHealthEqualTo(1);
|
||||
|
||||
setTime(425);
|
||||
assertHealthNotEqualTo(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHealthNotDrainedAfterGameplayEnd()
|
||||
{
|
||||
@ -54,18 +111,6 @@ namespace osu.Game.Tests.Gameplay
|
||||
assertHealthEqualTo(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHealthNotDrainedDuringBreak()
|
||||
{
|
||||
createProcessor(createBeatmap(0, 2000));
|
||||
setBreak(true);
|
||||
|
||||
setTime(700);
|
||||
assertHealthEqualTo(1);
|
||||
setTime(900);
|
||||
assertHealthEqualTo(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHealthDrainedDuringGameplay()
|
||||
{
|
||||
@ -112,30 +157,31 @@ namespace osu.Game.Tests.Gameplay
|
||||
assertHealthNotEqualTo(1);
|
||||
}
|
||||
|
||||
private Beatmap createBeatmap(double startTime, double endTime)
|
||||
private Beatmap createBeatmap(double startTime, double endTime, params BreakPeriod[] breaks)
|
||||
{
|
||||
var beatmap = new Beatmap
|
||||
{
|
||||
BeatmapInfo = { BaseDifficulty = { DrainRate = 5 } },
|
||||
BeatmapInfo = { BaseDifficulty = { DrainRate = 10 } },
|
||||
};
|
||||
|
||||
for (double time = startTime; time <= endTime; time += 100)
|
||||
{
|
||||
beatmap.HitObjects.Add(new JudgeableHitObject { StartTime = time });
|
||||
}
|
||||
|
||||
beatmap.Breaks.AddRange(breaks);
|
||||
|
||||
return beatmap;
|
||||
}
|
||||
|
||||
private void createProcessor(Beatmap beatmap) => AddStep("create processor", () =>
|
||||
{
|
||||
breakTime = new Bindable<bool>();
|
||||
|
||||
Child = processor = new DrainingHealthProcessor(beatmap.HitObjects[0].StartTime).With(d =>
|
||||
{
|
||||
d.RelativeSizeAxes = Axes.Both;
|
||||
d.Clock = new FramedClock(clock = new ManualClock());
|
||||
});
|
||||
|
||||
processor.IsBreakTime.BindTo(breakTime);
|
||||
processor.ApplyBeatmap(beatmap);
|
||||
});
|
||||
|
||||
@ -143,8 +189,6 @@ namespace osu.Game.Tests.Gameplay
|
||||
|
||||
private void setHealth(double health) => AddStep($"set health = {health}", () => processor.Health.Value = health);
|
||||
|
||||
private void setBreak(bool enabled) => AddStep($"{(enabled ? "enable" : "disable")} break", () => breakTime.Value = enabled);
|
||||
|
||||
private void assertHealthEqualTo(double value)
|
||||
=> AddAssert($"health = {value}", () => Precision.AlmostEquals(value, processor.Health.Value, 0.0001f));
|
||||
|
||||
|
25
osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs
Normal file
25
osu.Game.Tests/Gameplay/TestSceneGameplayClockContainer.cs
Normal file
@ -0,0 +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.
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Tests.Visual;
|
||||
|
||||
namespace osu.Game.Tests.Gameplay
|
||||
{
|
||||
public class TestSceneGameplayClockContainer : OsuTestScene
|
||||
{
|
||||
[Test]
|
||||
public void TestStartThenElapsedTime()
|
||||
{
|
||||
GameplayClockContainer gcc = null;
|
||||
|
||||
AddStep("create container", () => Add(gcc = new GameplayClockContainer(CreateWorkingBeatmap(new OsuRuleset().RulesetInfo), Array.Empty<Mod>(), 0)));
|
||||
AddStep("start track", () => gcc.Start());
|
||||
AddUntilStep("elapsed greater than zero", () => gcc.GameplayClock.ElapsedFrameTime > 0);
|
||||
}
|
||||
}
|
||||
}
|
340
osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs
Normal file
340
osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs
Normal file
@ -0,0 +1,340 @@
|
||||
// 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.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.IO.Stores;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Formats;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Storyboards;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osu.Game.Tests.Visual.Gameplay;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Gameplay
|
||||
{
|
||||
[HeadlessTest]
|
||||
public class TestSceneHitObjectSamples : OsuPlayerTestScene
|
||||
{
|
||||
private readonly SkinInfo userSkinInfo = new SkinInfo();
|
||||
|
||||
private readonly BeatmapInfo beatmapInfo = new BeatmapInfo
|
||||
{
|
||||
BeatmapSet = new BeatmapSetInfo(),
|
||||
Metadata = new BeatmapMetadata
|
||||
{
|
||||
Author = User.SYSTEM_USER
|
||||
}
|
||||
};
|
||||
|
||||
private readonly TestResourceStore userSkinResourceStore = new TestResourceStore();
|
||||
private readonly TestResourceStore beatmapSkinResourceStore = new TestResourceStore();
|
||||
|
||||
protected override bool HasCustomSteps => true;
|
||||
|
||||
private SkinSourceDependencyContainer dependencies;
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
=> new DependencyContainer(dependencies = new SkinSourceDependencyContainer(base.CreateChildDependencies(parent)));
|
||||
|
||||
/// <summary>
|
||||
/// Tests that a hitobject which provides no custom sample set retrieves samples from the user skin.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestDefaultSampleFromUserSkin()
|
||||
{
|
||||
const string expected_sample = "normal-hitnormal";
|
||||
|
||||
setupSkins(expected_sample, expected_sample);
|
||||
|
||||
createTestWithBeatmap("hitobject-skin-sample.osu");
|
||||
|
||||
assertUserLookup(expected_sample);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that a hitobject which provides a sample set of 1 retrieves samples from the beatmap skin.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestDefaultSampleFromBeatmap()
|
||||
{
|
||||
const string expected_sample = "normal-hitnormal";
|
||||
|
||||
setupSkins(expected_sample, expected_sample);
|
||||
|
||||
createTestWithBeatmap("hitobject-beatmap-sample.osu");
|
||||
|
||||
assertBeatmapLookup(expected_sample);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that a hitobject which provides a sample set of 1 retrieves samples from the user skin when the beatmap does not contain the sample.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestDefaultSampleFromUserSkinFallback()
|
||||
{
|
||||
const string expected_sample = "normal-hitnormal";
|
||||
|
||||
setupSkins(null, expected_sample);
|
||||
|
||||
createTestWithBeatmap("hitobject-beatmap-sample.osu");
|
||||
|
||||
assertUserLookup(expected_sample);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that a hitobject which provides a custom sample set of 2 retrieves the following samples from the beatmap skin:
|
||||
/// normal-hitnormal2
|
||||
/// normal-hitnormal
|
||||
/// </summary>
|
||||
[TestCase("normal-hitnormal2")]
|
||||
[TestCase("normal-hitnormal")]
|
||||
public void TestDefaultCustomSampleFromBeatmap(string expectedSample)
|
||||
{
|
||||
setupSkins(expectedSample, expectedSample);
|
||||
|
||||
createTestWithBeatmap("hitobject-beatmap-custom-sample.osu");
|
||||
|
||||
assertBeatmapLookup(expectedSample);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that a hitobject which provides a custom sample set of 2 retrieves the following samples from the user skin when the beatmap does not contain the sample:
|
||||
/// normal-hitnormal2
|
||||
/// normal-hitnormal
|
||||
/// </summary>
|
||||
[TestCase("normal-hitnormal2")]
|
||||
[TestCase("normal-hitnormal")]
|
||||
public void TestDefaultCustomSampleFromUserSkinFallback(string expectedSample)
|
||||
{
|
||||
setupSkins(string.Empty, expectedSample);
|
||||
|
||||
createTestWithBeatmap("hitobject-beatmap-custom-sample.osu");
|
||||
|
||||
assertUserLookup(expectedSample);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that a hitobject which provides a sample file retrieves the sample file from the beatmap skin.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestFileSampleFromBeatmap()
|
||||
{
|
||||
const string expected_sample = "hit_1.wav";
|
||||
|
||||
setupSkins(expected_sample, expected_sample);
|
||||
|
||||
createTestWithBeatmap("file-beatmap-sample.osu");
|
||||
|
||||
assertBeatmapLookup(expected_sample);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that a default hitobject and control point causes <see cref="TestDefaultSampleFromUserSkin"/>.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestControlPointSampleFromSkin()
|
||||
{
|
||||
const string expected_sample = "normal-hitnormal";
|
||||
|
||||
setupSkins(expected_sample, expected_sample);
|
||||
|
||||
createTestWithBeatmap("controlpoint-skin-sample.osu");
|
||||
|
||||
assertUserLookup(expected_sample);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that a control point that provides a custom sample set of 1 causes <see cref="TestDefaultSampleFromBeatmap"/>.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestControlPointSampleFromBeatmap()
|
||||
{
|
||||
const string expected_sample = "normal-hitnormal";
|
||||
|
||||
setupSkins(expected_sample, expected_sample);
|
||||
|
||||
createTestWithBeatmap("controlpoint-beatmap-sample.osu");
|
||||
|
||||
assertBeatmapLookup(expected_sample);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that a control point that provides a custom sample of 2 causes <see cref="TestDefaultCustomSampleFromBeatmap"/>.
|
||||
/// </summary>
|
||||
[TestCase("normal-hitnormal2")]
|
||||
[TestCase("normal-hitnormal")]
|
||||
public void TestControlPointCustomSampleFromBeatmap(string sampleName)
|
||||
{
|
||||
setupSkins(sampleName, sampleName);
|
||||
|
||||
createTestWithBeatmap("controlpoint-beatmap-custom-sample.osu");
|
||||
|
||||
assertBeatmapLookup(sampleName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that a hitobject's custom sample overrides the control point's.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestHitObjectCustomSampleOverride()
|
||||
{
|
||||
const string expected_sample = "normal-hitnormal3";
|
||||
|
||||
setupSkins(expected_sample, expected_sample);
|
||||
|
||||
createTestWithBeatmap("hitobject-beatmap-custom-sample-override.osu");
|
||||
|
||||
assertBeatmapLookup(expected_sample);
|
||||
}
|
||||
|
||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => currentTestBeatmap;
|
||||
|
||||
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null)
|
||||
=> new TestWorkingBeatmap(beatmapInfo, beatmapSkinResourceStore, beatmap, storyboard, Clock, Audio);
|
||||
|
||||
private IBeatmap currentTestBeatmap;
|
||||
|
||||
private void createTestWithBeatmap(string filename)
|
||||
{
|
||||
CreateTest(() =>
|
||||
{
|
||||
AddStep("clear performed lookups", () =>
|
||||
{
|
||||
userSkinResourceStore.PerformedLookups.Clear();
|
||||
beatmapSkinResourceStore.PerformedLookups.Clear();
|
||||
});
|
||||
|
||||
AddStep($"load {filename}", () =>
|
||||
{
|
||||
using (var reader = new LineBufferedReader(TestResources.OpenResource($"SampleLookups/{filename}")))
|
||||
currentTestBeatmap = Decoder.GetDecoder<Beatmap>(reader).Decode(reader);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void setupSkins(string beatmapFile, string userFile)
|
||||
{
|
||||
AddStep("setup skins", () =>
|
||||
{
|
||||
userSkinInfo.Files = new List<SkinFileInfo>
|
||||
{
|
||||
new SkinFileInfo
|
||||
{
|
||||
Filename = userFile,
|
||||
FileInfo = new IO.FileInfo { Hash = userFile }
|
||||
}
|
||||
};
|
||||
|
||||
beatmapInfo.BeatmapSet.Files = new List<BeatmapSetFileInfo>
|
||||
{
|
||||
new BeatmapSetFileInfo
|
||||
{
|
||||
Filename = beatmapFile,
|
||||
FileInfo = new IO.FileInfo { Hash = beatmapFile }
|
||||
}
|
||||
};
|
||||
|
||||
// Need to refresh the cached skin source to refresh the skin resource store.
|
||||
dependencies.SkinSource = new SkinProvidingContainer(new LegacySkin(userSkinInfo, userSkinResourceStore, Audio));
|
||||
});
|
||||
}
|
||||
|
||||
private void assertBeatmapLookup(string name) => AddAssert($"\"{name}\" looked up from beatmap skin",
|
||||
() => !userSkinResourceStore.PerformedLookups.Contains(name) && beatmapSkinResourceStore.PerformedLookups.Contains(name));
|
||||
|
||||
private void assertUserLookup(string name) => AddAssert($"\"{name}\" looked up from user skin",
|
||||
() => !beatmapSkinResourceStore.PerformedLookups.Contains(name) && userSkinResourceStore.PerformedLookups.Contains(name));
|
||||
|
||||
private class SkinSourceDependencyContainer : IReadOnlyDependencyContainer
|
||||
{
|
||||
public ISkinSource SkinSource;
|
||||
|
||||
private readonly IReadOnlyDependencyContainer fallback;
|
||||
|
||||
public SkinSourceDependencyContainer(IReadOnlyDependencyContainer fallback)
|
||||
{
|
||||
this.fallback = fallback;
|
||||
}
|
||||
|
||||
public object Get(Type type)
|
||||
{
|
||||
if (type == typeof(ISkinSource))
|
||||
return SkinSource;
|
||||
|
||||
return fallback.Get(type);
|
||||
}
|
||||
|
||||
public object Get(Type type, CacheInfo info)
|
||||
{
|
||||
if (type == typeof(ISkinSource))
|
||||
return SkinSource;
|
||||
|
||||
return fallback.Get(type, info);
|
||||
}
|
||||
|
||||
public void Inject<T>(T instance) where T : class
|
||||
{
|
||||
// Never used directly
|
||||
}
|
||||
}
|
||||
|
||||
private class TestResourceStore : IResourceStore<byte[]>
|
||||
{
|
||||
public readonly List<string> PerformedLookups = new List<string>();
|
||||
|
||||
public byte[] Get(string name)
|
||||
{
|
||||
markLookup(name);
|
||||
return Array.Empty<byte>();
|
||||
}
|
||||
|
||||
public Task<byte[]> GetAsync(string name)
|
||||
{
|
||||
markLookup(name);
|
||||
return Task.FromResult(Array.Empty<byte>());
|
||||
}
|
||||
|
||||
public Stream GetStream(string name)
|
||||
{
|
||||
markLookup(name);
|
||||
return new MemoryStream();
|
||||
}
|
||||
|
||||
private void markLookup(string name) => PerformedLookups.Add(name.Substring(name.LastIndexOf(Path.DirectorySeparatorChar) + 1));
|
||||
|
||||
public IEnumerable<string> GetAvailableResources() => Enumerable.Empty<string>();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private class TestWorkingBeatmap : ClockBackedTestWorkingBeatmap
|
||||
{
|
||||
private readonly BeatmapInfo skinBeatmapInfo;
|
||||
private readonly IResourceStore<byte[]> resourceStore;
|
||||
|
||||
public TestWorkingBeatmap(BeatmapInfo skinBeatmapInfo, IResourceStore<byte[]> resourceStore, IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock referenceClock, AudioManager audio,
|
||||
double length = 60000)
|
||||
: base(beatmap, storyboard, referenceClock, audio, length)
|
||||
{
|
||||
this.skinBeatmapInfo = skinBeatmapInfo;
|
||||
this.resourceStore = resourceStore;
|
||||
}
|
||||
|
||||
protected override ISkin GetSkin() => new LegacyBeatmapSkin(skinBeatmapInfo, resourceStore, AudioManager);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
@ -10,7 +11,12 @@ using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.IO.Stores;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Storyboards;
|
||||
using osu.Game.Storyboards.Drawables;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osu.Game.Tests.Visual;
|
||||
|
||||
@ -43,6 +49,27 @@ namespace osu.Game.Tests.Gameplay
|
||||
AddAssert("sample is non-null", () => channel != null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSamplePlaybackAtZero()
|
||||
{
|
||||
GameplayClockContainer gameplayContainer = null;
|
||||
DrawableStoryboardSample sample = null;
|
||||
|
||||
AddStep("create container", () =>
|
||||
{
|
||||
Add(gameplayContainer = new GameplayClockContainer(CreateWorkingBeatmap(new OsuRuleset().RulesetInfo), Array.Empty<Mod>(), 0));
|
||||
|
||||
gameplayContainer.Add(sample = new DrawableStoryboardSample(new StoryboardSampleInfo(string.Empty, 0, 1))
|
||||
{
|
||||
Clock = gameplayContainer.GameplayClock
|
||||
});
|
||||
});
|
||||
|
||||
AddStep("start time", () => gameplayContainer.Start());
|
||||
|
||||
AddUntilStep("sample playback succeeded", () => sample.LifetimeEnd < double.MaxValue);
|
||||
}
|
||||
|
||||
private class TestSkin : LegacySkin
|
||||
{
|
||||
public TestSkin(string resourceName, AudioManager audioManager)
|
||||
|
73
osu.Game.Tests/NonVisual/BarLineGeneratorTest.cs
Normal file
73
osu.Game.Tests/NonVisual/BarLineGeneratorTest.cs
Normal file
@ -0,0 +1,73 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Beatmaps.Timing;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
|
||||
namespace osu.Game.Tests.NonVisual
|
||||
{
|
||||
public class BarLineGeneratorTest
|
||||
{
|
||||
[Test]
|
||||
public void TestRoundingErrorCompensation()
|
||||
{
|
||||
// The aim of this test is to make sure bar line generation compensates for floating-point errors.
|
||||
// The premise of the test is that we have a single timing point that should result in bar lines
|
||||
// that start at a time point that is a whole number every seventh beat.
|
||||
|
||||
// The fact it's every seventh beat is important - it's a number indivisible by 2, which makes
|
||||
// it susceptible to rounding inaccuracies. In fact this was originally spotted in cases of maps
|
||||
// that met exactly this criteria.
|
||||
|
||||
const int beat_length_numerator = 2000;
|
||||
const int beat_length_denominator = 7;
|
||||
const TimeSignatures signature = TimeSignatures.SimpleQuadruple;
|
||||
|
||||
var beatmap = new Beatmap
|
||||
{
|
||||
HitObjects = new List<HitObject>
|
||||
{
|
||||
new HitObject { StartTime = 0 },
|
||||
new HitObject { StartTime = 120_000 }
|
||||
},
|
||||
ControlPointInfo = new ControlPointInfo()
|
||||
};
|
||||
|
||||
beatmap.ControlPointInfo.Add(0, new TimingControlPoint
|
||||
{
|
||||
BeatLength = (double)beat_length_numerator / beat_length_denominator,
|
||||
TimeSignature = signature
|
||||
});
|
||||
|
||||
var barLines = new BarLineGenerator<BarLine>(beatmap).BarLines;
|
||||
|
||||
for (int i = 0; i * beat_length_denominator < barLines.Count; i++)
|
||||
{
|
||||
var barLine = barLines[i * beat_length_denominator];
|
||||
var expectedTime = beat_length_numerator * (int)signature * i;
|
||||
|
||||
// every seventh bar's start time should be at least greater than the whole number we expect.
|
||||
// It cannot be less, as that can affect overlapping scroll algorithms
|
||||
// (the previous timing point might be chosen incorrectly if this is not the case)
|
||||
Assert.GreaterOrEqual(barLine.StartTime, expectedTime);
|
||||
|
||||
// on the other side, make sure we don't stray too far from the expected time either.
|
||||
Assert.IsTrue(Precision.AlmostEquals(barLine.StartTime, expectedTime));
|
||||
|
||||
// check major/minor lines for good measure too
|
||||
Assert.AreEqual(i % (int)signature == 0, barLine.Major);
|
||||
}
|
||||
}
|
||||
|
||||
private class BarLine : IBarLine
|
||||
{
|
||||
public double StartTime { get; set; }
|
||||
public bool Major { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
@ -29,11 +29,17 @@ namespace osu.Game.Tests.NonVisual
|
||||
var cpi = new ControlPointInfo();
|
||||
|
||||
cpi.Add(0, new TimingControlPoint()); // is *not* redundant, special exception for first timing point.
|
||||
cpi.Add(1000, new TimingControlPoint()); // is also not redundant, due to change of offset
|
||||
|
||||
Assert.That(cpi.Groups.Count, Is.EqualTo(2));
|
||||
Assert.That(cpi.TimingPoints.Count, Is.EqualTo(2));
|
||||
Assert.That(cpi.AllControlPoints.Count(), Is.EqualTo(2));
|
||||
|
||||
cpi.Add(1000, new TimingControlPoint()); // is redundant
|
||||
|
||||
Assert.That(cpi.Groups.Count, Is.EqualTo(1));
|
||||
Assert.That(cpi.TimingPoints.Count, Is.EqualTo(1));
|
||||
Assert.That(cpi.AllControlPoints.Count(), Is.EqualTo(1));
|
||||
Assert.That(cpi.Groups.Count, Is.EqualTo(2));
|
||||
Assert.That(cpi.TimingPoints.Count, Is.EqualTo(2));
|
||||
Assert.That(cpi.AllControlPoints.Count(), Is.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -86,11 +92,12 @@ namespace osu.Game.Tests.NonVisual
|
||||
Assert.That(cpi.EffectPoints.Count, Is.EqualTo(0));
|
||||
Assert.That(cpi.AllControlPoints.Count(), Is.EqualTo(0));
|
||||
|
||||
cpi.Add(1000, new EffectControlPoint { KiaiMode = true }); // is not redundant
|
||||
cpi.Add(1000, new EffectControlPoint { KiaiMode = true, OmitFirstBarLine = true }); // is not redundant
|
||||
cpi.Add(1400, new EffectControlPoint { KiaiMode = true, OmitFirstBarLine = true }); // same settings, but is not redundant
|
||||
|
||||
Assert.That(cpi.Groups.Count, Is.EqualTo(1));
|
||||
Assert.That(cpi.EffectPoints.Count, Is.EqualTo(1));
|
||||
Assert.That(cpi.AllControlPoints.Count(), Is.EqualTo(1));
|
||||
Assert.That(cpi.Groups.Count, Is.EqualTo(2));
|
||||
Assert.That(cpi.EffectPoints.Count, Is.EqualTo(2));
|
||||
Assert.That(cpi.AllControlPoints.Count(), Is.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
295
osu.Game.Tests/NonVisual/CustomDataDirectoryTest.cs
Normal file
295
osu.Game.Tests/NonVisual/CustomDataDirectoryTest.cs
Normal file
@ -0,0 +1,295 @@
|
||||
// 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.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.IO;
|
||||
|
||||
namespace osu.Game.Tests.NonVisual
|
||||
{
|
||||
[TestFixture]
|
||||
public class CustomDataDirectoryTest
|
||||
{
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
if (Directory.Exists(customPath))
|
||||
Directory.Delete(customPath, true);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDefaultDirectory()
|
||||
{
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestDefaultDirectory)))
|
||||
{
|
||||
try
|
||||
{
|
||||
var osu = loadOsu(host);
|
||||
var storage = osu.Dependencies.Get<Storage>();
|
||||
|
||||
string defaultStorageLocation = Path.Combine(RuntimeInfo.StartupDirectory, "headless", nameof(TestDefaultDirectory));
|
||||
Assert.That(storage.GetFullPath("."), Is.EqualTo(defaultStorageLocation));
|
||||
}
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string customPath => Path.Combine(RuntimeInfo.StartupDirectory, "custom-path");
|
||||
|
||||
[Test]
|
||||
public void TestCustomDirectory()
|
||||
{
|
||||
using (var host = new HeadlessGameHost(nameof(TestCustomDirectory)))
|
||||
{
|
||||
string defaultStorageLocation = Path.Combine(RuntimeInfo.StartupDirectory, "headless", nameof(TestCustomDirectory));
|
||||
|
||||
// need access before the game has constructed its own storage yet.
|
||||
Storage storage = new DesktopStorage(defaultStorageLocation, host);
|
||||
// manual cleaning so we can prepare a config file.
|
||||
storage.DeleteDirectory(string.Empty);
|
||||
|
||||
using (var storageConfig = new StorageConfigManager(storage))
|
||||
storageConfig.Set(StorageConfig.FullPath, customPath);
|
||||
|
||||
try
|
||||
{
|
||||
var osu = loadOsu(host);
|
||||
|
||||
// switch to DI'd storage
|
||||
storage = osu.Dependencies.Get<Storage>();
|
||||
|
||||
Assert.That(storage.GetFullPath("."), Is.EqualTo(customPath));
|
||||
}
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSubDirectoryLookup()
|
||||
{
|
||||
using (var host = new HeadlessGameHost(nameof(TestSubDirectoryLookup)))
|
||||
{
|
||||
string defaultStorageLocation = Path.Combine(RuntimeInfo.StartupDirectory, "headless", nameof(TestSubDirectoryLookup));
|
||||
|
||||
// need access before the game has constructed its own storage yet.
|
||||
Storage storage = new DesktopStorage(defaultStorageLocation, host);
|
||||
// manual cleaning so we can prepare a config file.
|
||||
storage.DeleteDirectory(string.Empty);
|
||||
|
||||
using (var storageConfig = new StorageConfigManager(storage))
|
||||
storageConfig.Set(StorageConfig.FullPath, customPath);
|
||||
|
||||
try
|
||||
{
|
||||
var osu = loadOsu(host);
|
||||
|
||||
// switch to DI'd storage
|
||||
storage = osu.Dependencies.Get<Storage>();
|
||||
|
||||
string actualTestFile = Path.Combine(customPath, "rulesets", "test");
|
||||
|
||||
File.WriteAllText(actualTestFile, "test");
|
||||
|
||||
var rulesetStorage = storage.GetStorageForDirectory("rulesets");
|
||||
var lookupPath = rulesetStorage.GetFiles(".").Single();
|
||||
|
||||
Assert.That(lookupPath, Is.EqualTo("test"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMigration()
|
||||
{
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestMigration)))
|
||||
{
|
||||
try
|
||||
{
|
||||
var osu = loadOsu(host);
|
||||
var storage = osu.Dependencies.Get<Storage>();
|
||||
|
||||
// ensure we perform a save
|
||||
host.Dependencies.Get<FrameworkConfigManager>().Save();
|
||||
|
||||
// ensure we "use" cache
|
||||
host.Storage.GetStorageForDirectory("cache");
|
||||
|
||||
// for testing nested files are not ignored (only top level)
|
||||
host.Storage.GetStorageForDirectory("test-nested").GetStorageForDirectory("cache");
|
||||
|
||||
string defaultStorageLocation = Path.Combine(RuntimeInfo.StartupDirectory, "headless", nameof(TestMigration));
|
||||
|
||||
Assert.That(storage.GetFullPath("."), Is.EqualTo(defaultStorageLocation));
|
||||
|
||||
osu.Migrate(customPath);
|
||||
|
||||
Assert.That(storage.GetFullPath("."), Is.EqualTo(customPath));
|
||||
|
||||
// ensure cache was not moved
|
||||
Assert.That(host.Storage.ExistsDirectory("cache"));
|
||||
|
||||
// ensure nested cache was moved
|
||||
Assert.That(!host.Storage.ExistsDirectory(Path.Combine("test-nested", "cache")));
|
||||
Assert.That(storage.ExistsDirectory(Path.Combine("test-nested", "cache")));
|
||||
|
||||
foreach (var file in OsuStorage.IGNORE_FILES)
|
||||
{
|
||||
Assert.That(host.Storage.Exists(file), Is.True);
|
||||
Assert.That(storage.Exists(file), Is.False);
|
||||
}
|
||||
|
||||
foreach (var dir in OsuStorage.IGNORE_DIRECTORIES)
|
||||
{
|
||||
Assert.That(host.Storage.ExistsDirectory(dir), Is.True);
|
||||
Assert.That(storage.ExistsDirectory(dir), Is.False);
|
||||
}
|
||||
|
||||
Assert.That(new StreamReader(host.Storage.GetStream("storage.ini")).ReadToEnd().Contains($"FullPath = {customPath}"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMigrationBetweenTwoTargets()
|
||||
{
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestMigrationBetweenTwoTargets)))
|
||||
{
|
||||
try
|
||||
{
|
||||
var osu = loadOsu(host);
|
||||
|
||||
string customPath2 = $"{customPath}-2";
|
||||
|
||||
const string database_filename = "client.db";
|
||||
|
||||
Assert.DoesNotThrow(() => osu.Migrate(customPath));
|
||||
Assert.That(File.Exists(Path.Combine(customPath, database_filename)));
|
||||
|
||||
Assert.DoesNotThrow(() => osu.Migrate(customPath2));
|
||||
Assert.That(File.Exists(Path.Combine(customPath2, database_filename)));
|
||||
|
||||
Assert.DoesNotThrow(() => osu.Migrate(customPath));
|
||||
Assert.That(File.Exists(Path.Combine(customPath, database_filename)));
|
||||
}
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMigrationToSameTargetFails()
|
||||
{
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestMigrationToSameTargetFails)))
|
||||
{
|
||||
try
|
||||
{
|
||||
var osu = loadOsu(host);
|
||||
|
||||
Assert.DoesNotThrow(() => osu.Migrate(customPath));
|
||||
Assert.Throws<ArgumentException>(() => osu.Migrate(customPath));
|
||||
}
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMigrationToNestedTargetFails()
|
||||
{
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestMigrationToNestedTargetFails)))
|
||||
{
|
||||
try
|
||||
{
|
||||
var osu = loadOsu(host);
|
||||
|
||||
Assert.DoesNotThrow(() => osu.Migrate(customPath));
|
||||
|
||||
string subFolder = Path.Combine(customPath, "sub");
|
||||
|
||||
if (Directory.Exists(subFolder))
|
||||
Directory.Delete(subFolder, true);
|
||||
|
||||
Directory.CreateDirectory(subFolder);
|
||||
|
||||
Assert.Throws<ArgumentException>(() => osu.Migrate(subFolder));
|
||||
}
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMigrationToSeeminglyNestedTarget()
|
||||
{
|
||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestMigrationToSeeminglyNestedTarget)))
|
||||
{
|
||||
try
|
||||
{
|
||||
var osu = loadOsu(host);
|
||||
|
||||
Assert.DoesNotThrow(() => osu.Migrate(customPath));
|
||||
|
||||
string seeminglySubFolder = customPath + "sub";
|
||||
|
||||
if (Directory.Exists(seeminglySubFolder))
|
||||
Directory.Delete(seeminglySubFolder, true);
|
||||
|
||||
Directory.CreateDirectory(seeminglySubFolder);
|
||||
|
||||
osu.Migrate(seeminglySubFolder);
|
||||
}
|
||||
finally
|
||||
{
|
||||
host.Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private OsuGameBase loadOsu(GameHost host)
|
||||
{
|
||||
var osu = new OsuGameBase();
|
||||
Task.Run(() => host.Run(osu));
|
||||
waitForOrAssert(() => osu.IsLoaded, @"osu! failed to start in a reasonable amount of time");
|
||||
return osu;
|
||||
}
|
||||
|
||||
private static void waitForOrAssert(Func<bool> result, string failureMessage, int timeout = 60000)
|
||||
{
|
||||
Task task = Task.Run(() =>
|
||||
{
|
||||
while (!result()) Thread.Sleep(200);
|
||||
});
|
||||
|
||||
Assert.IsTrue(task.Wait(timeout), failureMessage);
|
||||
}
|
||||
}
|
||||
}
|
@ -46,12 +46,12 @@ namespace osu.Game.Tests.NonVisual
|
||||
confirmCurrentFrame(0);
|
||||
confirmNextFrame(1);
|
||||
|
||||
//if we hit the first frame perfectly, time should progress to it.
|
||||
// if we hit the first frame perfectly, time should progress to it.
|
||||
setTime(1000, 1000);
|
||||
confirmCurrentFrame(1);
|
||||
confirmNextFrame(2);
|
||||
|
||||
//in between non-important frames should progress based on input.
|
||||
// in between non-important frames should progress based on input.
|
||||
setTime(1200, 1200);
|
||||
confirmCurrentFrame(1);
|
||||
|
||||
@ -144,7 +144,7 @@ namespace osu.Game.Tests.NonVisual
|
||||
confirmCurrentFrame(2);
|
||||
confirmNextFrame(1);
|
||||
|
||||
//ensure each frame plays out until start
|
||||
// ensure each frame plays out until start
|
||||
setTime(-500, 1000);
|
||||
confirmCurrentFrame(1);
|
||||
confirmNextFrame(0);
|
||||
|
85
osu.Game.Tests/NonVisual/PeriodTrackerTest.cs
Normal file
85
osu.Game.Tests/NonVisual/PeriodTrackerTest.cs
Normal file
@ -0,0 +1,85 @@
|
||||
// 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.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Utils;
|
||||
|
||||
namespace osu.Game.Tests.NonVisual
|
||||
{
|
||||
[TestFixture]
|
||||
public class PeriodTrackerTest
|
||||
{
|
||||
private static readonly Period[] single_period = { new Period(1.0, 2.0) };
|
||||
|
||||
private static readonly Period[] unordered_periods =
|
||||
{
|
||||
new Period(-9.1, -8.3),
|
||||
new Period(-3.4, 2.1),
|
||||
new Period(9.0, 50.0),
|
||||
new Period(5.25, 10.50)
|
||||
};
|
||||
|
||||
[Test]
|
||||
public void TestCheckValueInsideSinglePeriod()
|
||||
{
|
||||
var tracker = new PeriodTracker(single_period);
|
||||
|
||||
var period = single_period.Single();
|
||||
Assert.IsTrue(tracker.IsInAny(period.Start));
|
||||
Assert.IsTrue(tracker.IsInAny(getMidpoint(period)));
|
||||
Assert.IsTrue(tracker.IsInAny(period.End));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCheckValuesInsidePeriods()
|
||||
{
|
||||
var tracker = new PeriodTracker(unordered_periods);
|
||||
|
||||
foreach (var period in unordered_periods)
|
||||
Assert.IsTrue(tracker.IsInAny(getMidpoint(period)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCheckValuesInRandomOrder()
|
||||
{
|
||||
var tracker = new PeriodTracker(unordered_periods);
|
||||
|
||||
foreach (var period in unordered_periods.OrderBy(_ => RNG.Next()))
|
||||
Assert.IsTrue(tracker.IsInAny(getMidpoint(period)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCheckValuesOutOfPeriods()
|
||||
{
|
||||
var tracker = new PeriodTracker(new[]
|
||||
{
|
||||
new Period(1.0, 2.0),
|
||||
new Period(3.0, 4.0)
|
||||
});
|
||||
|
||||
Assert.IsFalse(tracker.IsInAny(0.9), "Time before first period is being considered inside");
|
||||
|
||||
Assert.IsFalse(tracker.IsInAny(2.1), "Time right after first period is being considered inside");
|
||||
Assert.IsFalse(tracker.IsInAny(2.9), "Time right before second period is being considered inside");
|
||||
|
||||
Assert.IsFalse(tracker.IsInAny(4.1), "Time after last period is being considered inside");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestReversedPeriodHandling()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
{
|
||||
_ = new PeriodTracker(new[]
|
||||
{
|
||||
new Period(2.0, 1.0)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private double getMidpoint(Period period) => period.Start + (period.End - period.Start) / 2;
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics.OpenGL.Textures;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
@ -103,7 +104,7 @@ namespace osu.Game.Tests.NonVisual.Skinning
|
||||
Textures = fileNames.ToDictionary(fileName => fileName, fileName => new Texture(1, 1));
|
||||
}
|
||||
|
||||
public override Texture Get(string name) => Textures.GetValueOrDefault(name);
|
||||
public override Texture Get(string name, WrapMode wrapModeS, WrapMode wrapModeT) => Textures.GetValueOrDefault(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
117
osu.Game.Tests/Online/TestDummyAPIRequestHandling.cs
Normal file
117
osu.Game.Tests/Online/TestDummyAPIRequestHandling.cs
Normal file
@ -0,0 +1,117 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Tests.Visual;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Online
|
||||
{
|
||||
[HeadlessTest]
|
||||
public class TestDummyAPIRequestHandling : OsuTestScene
|
||||
{
|
||||
[Test]
|
||||
public void TestGenericRequestHandling()
|
||||
{
|
||||
AddStep("register request handling", () => ((DummyAPIAccess)API).HandleRequest = req =>
|
||||
{
|
||||
switch (req)
|
||||
{
|
||||
case CommentVoteRequest cRequest:
|
||||
cRequest.TriggerSuccess(new CommentBundle());
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
CommentVoteRequest request = null;
|
||||
CommentBundle response = null;
|
||||
|
||||
AddStep("fire request", () =>
|
||||
{
|
||||
response = null;
|
||||
request = new CommentVoteRequest(1, CommentVoteAction.Vote);
|
||||
request.Success += res => response = res;
|
||||
API.Queue(request);
|
||||
});
|
||||
|
||||
AddAssert("response event fired", () => response != null);
|
||||
|
||||
AddAssert("request has response", () => request.Result == response);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestQueueRequestHandling()
|
||||
{
|
||||
registerHandler();
|
||||
|
||||
LeaveChannelRequest request;
|
||||
bool gotResponse = false;
|
||||
|
||||
AddStep("fire request", () =>
|
||||
{
|
||||
gotResponse = false;
|
||||
request = new LeaveChannelRequest(new Channel(), new User());
|
||||
request.Success += () => gotResponse = true;
|
||||
API.Queue(request);
|
||||
});
|
||||
|
||||
AddAssert("response event fired", () => gotResponse);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestPerformRequestHandling()
|
||||
{
|
||||
registerHandler();
|
||||
|
||||
LeaveChannelRequest request;
|
||||
bool gotResponse = false;
|
||||
|
||||
AddStep("fire request", () =>
|
||||
{
|
||||
gotResponse = false;
|
||||
request = new LeaveChannelRequest(new Channel(), new User());
|
||||
request.Success += () => gotResponse = true;
|
||||
API.Perform(request);
|
||||
});
|
||||
|
||||
AddAssert("response event fired", () => gotResponse);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestPerformAsyncRequestHandling()
|
||||
{
|
||||
registerHandler();
|
||||
|
||||
LeaveChannelRequest request;
|
||||
bool gotResponse = false;
|
||||
|
||||
AddStep("fire request", () =>
|
||||
{
|
||||
gotResponse = false;
|
||||
request = new LeaveChannelRequest(new Channel(), new User());
|
||||
request.Success += () => gotResponse = true;
|
||||
API.PerformAsync(request);
|
||||
});
|
||||
|
||||
AddAssert("response event fired", () => gotResponse);
|
||||
}
|
||||
|
||||
private void registerHandler()
|
||||
{
|
||||
AddStep("register request handling", () => ((DummyAPIAccess)API).HandleRequest = req =>
|
||||
{
|
||||
switch (req)
|
||||
{
|
||||
case LeaveChannelRequest cRequest:
|
||||
cRequest.TriggerSuccess();
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
osu file format v14
|
||||
|
||||
[TimingPoints]
|
||||
0,300,4,0,2,100,1,0
|
||||
|
||||
[HitObjects]
|
||||
444,320,1000,5,0,0:0:0:0:
|
@ -0,0 +1,7 @@
|
||||
osu file format v14
|
||||
|
||||
[TimingPoints]
|
||||
0,300,4,0,1,100,1,0
|
||||
|
||||
[HitObjects]
|
||||
444,320,1000,5,0,0:0:0:0:
|
@ -0,0 +1,7 @@
|
||||
osu file format v14
|
||||
|
||||
[TimingPoints]
|
||||
0,300,4,0,0,100,1,0
|
||||
|
||||
[HitObjects]
|
||||
444,320,1000,5,0,0:0:0:0:
|
@ -0,0 +1,4 @@
|
||||
osu file format v14
|
||||
|
||||
[HitObjects]
|
||||
255,193,2170,1,0,0:0:0:0:hit_1.wav
|
@ -0,0 +1,7 @@
|
||||
osu file format v14
|
||||
|
||||
[TimingPoints]
|
||||
0,300,4,0,2,100,1,0
|
||||
|
||||
[HitObjects]
|
||||
444,320,1000,5,0,0:0:3:0:
|
@ -0,0 +1,4 @@
|
||||
osu file format v14
|
||||
|
||||
[HitObjects]
|
||||
444,320,1000,5,0,0:0:2:0:
|
@ -0,0 +1,4 @@
|
||||
osu file format v14
|
||||
|
||||
[HitObjects]
|
||||
444,320,1000,5,0,0:0:1:0:
|
@ -0,0 +1,4 @@
|
||||
osu file format v14
|
||||
|
||||
[HitObjects]
|
||||
444,320,1000,5,0,0:0:0:0:
|
@ -17,14 +17,14 @@ namespace osu.Game.Tests.Resources
|
||||
|
||||
public static string GetTestBeatmapForImport(bool virtualTrack = false)
|
||||
{
|
||||
var temp = Path.GetTempFileName() + ".osz";
|
||||
var tempPath = Path.GetTempFileName() + ".osz";
|
||||
|
||||
using (var stream = GetTestBeatmapStream(virtualTrack))
|
||||
using (var newFile = File.Create(temp))
|
||||
using (var newFile = File.Create(tempPath))
|
||||
stream.CopyTo(newFile);
|
||||
|
||||
Assert.IsTrue(File.Exists(temp));
|
||||
return temp;
|
||||
Assert.IsTrue(File.Exists(tempPath));
|
||||
return tempPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,27 +5,27 @@ osu file format v14
|
||||
255,193,1000,49,0,0:0:0:0:
|
||||
// Combo index = 4
|
||||
|
||||
// Slider with new combo followed by circle with no new combo
|
||||
// Spinner with new combo followed by circle with no new combo
|
||||
256,192,2000,12,0,2000,0:0:0:0:
|
||||
255,193,3000,1,0,0:0:0:0:
|
||||
// Combo index = 5
|
||||
|
||||
// Slider without new combo followed by circle with no new combo
|
||||
// Spinner without new combo followed by circle with no new combo
|
||||
256,192,4000,8,0,5000,0:0:0:0:
|
||||
255,193,6000,1,0,0:0:0:0:
|
||||
// Combo index = 5
|
||||
|
||||
// Slider without new combo followed by circle with new combo
|
||||
// Spinner without new combo followed by circle with new combo
|
||||
256,192,7000,8,0,8000,0:0:0:0:
|
||||
255,193,9000,5,0,0:0:0:0:
|
||||
// Combo index = 6
|
||||
|
||||
// Slider with new combo and offset (1) followed by circle with new combo and offset (3)
|
||||
// Spinner with new combo and offset (1) followed by circle with new combo and offset (3)
|
||||
256,192,10000,28,0,11000,0:0:0:0:
|
||||
255,193,12000,53,0,0:0:0:0:
|
||||
// Combo index = 11
|
||||
|
||||
// Slider with new combo and offset (2) followed by slider with no new combo followed by circle with no new combo
|
||||
// Spinner with new combo and offset (2) followed by slider with no new combo followed by circle with no new combo
|
||||
256,192,13000,44,0,14000,0:0:0:0:
|
||||
256,192,15000,8,0,16000,0:0:0:0:
|
||||
255,193,17000,1,0,0:0:0:0:
|
||||
|
30
osu.Game.Tests/Resources/sample-beatmap-catch.osu
Normal file
30
osu.Game.Tests/Resources/sample-beatmap-catch.osu
Normal file
@ -0,0 +1,30 @@
|
||||
osu file format v14
|
||||
|
||||
[General]
|
||||
SampleSet: Normal
|
||||
StackLeniency: 0.7
|
||||
Mode: 2
|
||||
|
||||
[Difficulty]
|
||||
HPDrainRate:3
|
||||
CircleSize:5
|
||||
OverallDifficulty:8
|
||||
ApproachRate:8
|
||||
SliderMultiplier:3.59999990463257
|
||||
SliderTickRate:2
|
||||
|
||||
[TimingPoints]
|
||||
24,352.941176470588,4,1,1,100,1,0
|
||||
6376,-50,4,1,1,100,0,0
|
||||
|
||||
[HitObjects]
|
||||
32,183,24,5,0,0:0:0:0:
|
||||
106,123,200,1,10,0:0:0:0:
|
||||
199,108,376,1,2,0:0:0:0:
|
||||
305,105,553,5,4,0:0:0:0:
|
||||
386,112,729,1,14,0:0:0:0:
|
||||
486,197,906,5,12,0:0:0:0:
|
||||
14,199,1082,2,0,L|473:198,1,449.999988079071
|
||||
14,199,1700,6,6,P|248:33|490:222,1,629.9999833107,0|8,0:0|0:0,0:0:0:0:
|
||||
10,190,2494,2,8,B|252:29|254:335|468:167,1,449.999988079071,10|12,0:0|0:0,0:0:0:0:
|
||||
256,192,3112,12,0,3906,0:0:0:0:
|
39
osu.Game.Tests/Resources/sample-beatmap-mania.osu
Normal file
39
osu.Game.Tests/Resources/sample-beatmap-mania.osu
Normal file
@ -0,0 +1,39 @@
|
||||
osu file format v14
|
||||
|
||||
[General]
|
||||
SampleSet: Normal
|
||||
StackLeniency: 0.7
|
||||
Mode: 3
|
||||
|
||||
[Difficulty]
|
||||
HPDrainRate:3
|
||||
CircleSize:5
|
||||
OverallDifficulty:8
|
||||
ApproachRate:8
|
||||
SliderMultiplier:3.59999990463257
|
||||
SliderTickRate:2
|
||||
|
||||
[TimingPoints]
|
||||
24,352.941176470588,4,1,1,100,1,0
|
||||
6376,-50,4,1,1,100,0,0
|
||||
|
||||
[HitObjects]
|
||||
51,192,24,1,0,0:0:0:0:
|
||||
153,192,200,1,0,0:0:0:0:
|
||||
358,192,376,1,0,0:0:0:0:
|
||||
460,192,553,1,0,0:0:0:0:
|
||||
460,192,729,128,0,1435:0:0:0:0:
|
||||
358,192,906,128,0,1612:0:0:0:0:
|
||||
256,192,1082,128,0,1788:0:0:0:0:
|
||||
153,192,1259,128,0,1965:0:0:0:0:
|
||||
51,192,1435,128,0,2141:0:0:0:0:
|
||||
51,192,2318,1,12,0:0:0:0:
|
||||
153,192,2318,1,4,0:0:0:0:
|
||||
256,192,2318,1,6,0:0:0:0:
|
||||
358,192,2318,1,14,0:0:0:0:
|
||||
460,192,2318,1,0,0:0:0:0:
|
||||
51,192,2494,128,0,2582:0:0:0:0:
|
||||
153,192,2494,128,14,2582:0:0:0:0:
|
||||
256,192,2494,128,6,2582:0:0:0:0:
|
||||
358,192,2494,128,4,2582:0:0:0:0:
|
||||
460,192,2494,128,12,2582:0:0:0:0:
|
32
osu.Game.Tests/Resources/sample-beatmap-osu.osu
Normal file
32
osu.Game.Tests/Resources/sample-beatmap-osu.osu
Normal file
@ -0,0 +1,32 @@
|
||||
osu file format v14
|
||||
|
||||
[General]
|
||||
SampleSet: Normal
|
||||
StackLeniency: 0.7
|
||||
Mode: 0
|
||||
|
||||
[Difficulty]
|
||||
HPDrainRate:3
|
||||
CircleSize:5
|
||||
OverallDifficulty:8
|
||||
ApproachRate:8
|
||||
SliderMultiplier:3.59999990463257
|
||||
SliderTickRate:2
|
||||
|
||||
[TimingPoints]
|
||||
24,352.941176470588,4,1,1,100,1,0
|
||||
6376,-50,4,1,1,100,0,0
|
||||
|
||||
[HitObjects]
|
||||
98,69,24,1,0,0:0:0:0:
|
||||
419,72,200,1,2,0:0:0:0:
|
||||
81,314,376,1,6,0:0:0:0:
|
||||
423,321,553,1,12,0:0:0:0:
|
||||
86,192,729,2,0,P|459:193|460:193,1,359.999990463257
|
||||
86,192,1259,2,0,P|246:82|453:203,1,449.999988079071
|
||||
86,192,1876,2,0,B|256:30|257:313|464:177,1,359.999990463257
|
||||
86,55,2406,2,12,B|447:51|447:51|452:348|452:348|78:344,1,989.999973773957,14|2,0:0|0:0,0:0:0:0:
|
||||
256,192,3553,12,0,4259,0:0:0:0:
|
||||
67,57,4435,5,0,0:0:0:0:
|
||||
440,52,4612,5,0,0:0:0:0:
|
||||
86,181,4788,6,0,L|492:183,1,359.999990463257
|
42
osu.Game.Tests/Resources/sample-beatmap-taiko.osu
Normal file
42
osu.Game.Tests/Resources/sample-beatmap-taiko.osu
Normal file
@ -0,0 +1,42 @@
|
||||
osu file format v14
|
||||
|
||||
[General]
|
||||
SampleSet: Normal
|
||||
StackLeniency: 0.7
|
||||
Mode: 1
|
||||
|
||||
[Difficulty]
|
||||
HPDrainRate:3
|
||||
CircleSize:5
|
||||
OverallDifficulty:8
|
||||
ApproachRate:8
|
||||
SliderMultiplier:3.59999990463257
|
||||
SliderTickRate:2
|
||||
|
||||
[TimingPoints]
|
||||
24,352.941176470588,4,1,1,100,1,0
|
||||
6376,-50,4,1,1,100,0,0
|
||||
|
||||
[HitObjects]
|
||||
231,129,24,1,0,0:0:0:0:
|
||||
231,129,200,1,0,0:0:0:0:
|
||||
231,129,376,1,0,0:0:0:0:
|
||||
231,129,553,1,0,0:0:0:0:
|
||||
231,129,729,1,0,0:0:0:0:
|
||||
373,132,906,1,4,0:0:0:0:
|
||||
373,132,1082,1,4,0:0:0:0:
|
||||
373,132,1259,1,4,0:0:0:0:
|
||||
373,132,1435,1,4,0:0:0:0:
|
||||
231,129,1788,1,8,0:0:0:0:
|
||||
231,129,1964,1,8,0:0:0:0:
|
||||
231,129,2140,1,8,0:0:0:0:
|
||||
231,129,2317,1,8,0:0:0:0:
|
||||
231,129,2493,1,8,0:0:0:0:
|
||||
373,132,2670,1,12,0:0:0:0:
|
||||
373,132,2846,1,12,0:0:0:0:
|
||||
373,132,3023,1,12,0:0:0:0:
|
||||
373,132,3199,1,12,0:0:0:0:
|
||||
51,189,3553,2,0,L|150:188,1,89.9999976158143
|
||||
52,191,3906,2,0,L|512:189,1,449.999988079071
|
||||
26,196,4612,2,4,L|501:195,1,449.999988079071
|
||||
17,242,5318,2,10,P|250:69|495:243,1,629.9999833107,0|8,0:0|0:0,0:0:0:0:
|
57
osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs
Normal file
57
osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs
Normal 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu.Judgements;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
|
||||
namespace osu.Game.Tests.Rulesets.Scoring
|
||||
{
|
||||
public class ScoreProcessorTest
|
||||
{
|
||||
private ScoreProcessor scoreProcessor;
|
||||
private IBeatmap beatmap;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
scoreProcessor = new ScoreProcessor();
|
||||
beatmap = new TestBeatmap(new RulesetInfo())
|
||||
{
|
||||
HitObjects = new List<HitObject>
|
||||
{
|
||||
new HitCircle()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[TestCase(ScoringMode.Standardised, HitResult.Meh, 750_000)]
|
||||
[TestCase(ScoringMode.Standardised, HitResult.Good, 800_000)]
|
||||
[TestCase(ScoringMode.Standardised, HitResult.Great, 1_000_000)]
|
||||
[TestCase(ScoringMode.Classic, HitResult.Meh, 50)]
|
||||
[TestCase(ScoringMode.Classic, HitResult.Good, 100)]
|
||||
[TestCase(ScoringMode.Classic, HitResult.Great, 300)]
|
||||
public void TestSingleOsuHit(ScoringMode scoringMode, HitResult hitResult, int expectedScore)
|
||||
{
|
||||
scoreProcessor.Mode.Value = scoringMode;
|
||||
scoreProcessor.ApplyBeatmap(beatmap);
|
||||
|
||||
var judgementResult = new JudgementResult(beatmap.HitObjects.Single(), new OsuJudgement())
|
||||
{
|
||||
Type = hitResult
|
||||
};
|
||||
scoreProcessor.ApplyResult(judgementResult);
|
||||
|
||||
Assert.IsTrue(Precision.AlmostEquals(expectedScore, scoreProcessor.TotalScore.Value));
|
||||
}
|
||||
}
|
||||
}
|
@ -183,11 +183,8 @@ namespace osu.Game.Tests.Scores.IO
|
||||
{
|
||||
var beatmapManager = osu.Dependencies.Get<BeatmapManager>();
|
||||
|
||||
if (score.Beatmap == null)
|
||||
score.Beatmap = beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps.First();
|
||||
|
||||
if (score.Ruleset == null)
|
||||
score.Ruleset = new OsuRuleset().RulesetInfo;
|
||||
score.Beatmap ??= beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps.First();
|
||||
score.Ruleset ??= new OsuRuleset().RulesetInfo;
|
||||
|
||||
var scoreManager = osu.Dependencies.Get<ScoreManager>();
|
||||
await scoreManager.Import(score, archive);
|
||||
|
@ -29,8 +29,22 @@ namespace osu.Game.Tests.ScrollAlgorithms
|
||||
[Test]
|
||||
public void TestDisplayStartTime()
|
||||
{
|
||||
// Sequential scroll algorithm approximates the start time
|
||||
// This should be fixed in the future
|
||||
// easy cases - time range adjusted for velocity fits within control point duration
|
||||
Assert.AreEqual(2500, algorithm.GetDisplayStartTime(5000, 0, 2500, 1)); // 5000 - (2500 / 1)
|
||||
Assert.AreEqual(13750, algorithm.GetDisplayStartTime(15000, 0, 2500, 1)); // 15000 - (2500 / 2)
|
||||
Assert.AreEqual(20000, algorithm.GetDisplayStartTime(25000, 0, 2500, 1)); // 25000 - (2500 / 0.5)
|
||||
|
||||
// hard case - time range adjusted for velocity exceeds control point duration
|
||||
|
||||
// 1st multiplier point takes 10000 / 2500 = 4 scroll lengths
|
||||
// 2nd multiplier point takes 10000 / (2500 / 2) = 8 scroll lengths
|
||||
// 3rd multiplier point takes 2500 / (2500 * 2) = 0.5 scroll lengths up to hitobject start
|
||||
|
||||
// absolute position of the hitobject = 1000 * (4 + 8 + 0.5) = 12500
|
||||
// minus one scroll length allowance = 12500 - 1000 = 11500 = 11.5 [scroll lengths]
|
||||
// therefore the start time lies within the second multiplier point (because 11.5 < 4 + 8)
|
||||
// its exact time position is = 10000 + 7.5 * (2500 / 2) = 19375
|
||||
Assert.AreEqual(19375, algorithm.GetDisplayStartTime(22500, 0, 2500, 1000));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -152,11 +152,12 @@ namespace osu.Game.Tests.Skins
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSetBeatmapVersionNoFallback()
|
||||
public void TestSetBeatmapVersionFallsBackToUserSkin()
|
||||
{
|
||||
// completely ignoring beatmap versions for simplicity.
|
||||
AddStep("Set user skin version 2.3", () => userSource.Configuration.LegacyVersion = 2.3m);
|
||||
AddStep("Set beatmap skin version null", () => beatmapSource.Configuration.LegacyVersion = 1.7m);
|
||||
AddAssert("Check legacy version lookup", () => requester.GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version)?.Value == 1.7m);
|
||||
AddAssert("Check legacy version lookup", () => requester.GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version)?.Value == 2.3m);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -172,7 +173,6 @@ namespace osu.Game.Tests.Skins
|
||||
public void TestIniWithNoVersionFallsBackTo1()
|
||||
{
|
||||
AddStep("Parse skin with no version", () => userSource.Configuration = new LegacySkinDecoder().Decode(new LineBufferedReader(new MemoryStream())));
|
||||
AddStep("Set beatmap skin version null", () => beatmapSource.Configuration.LegacyVersion = null);
|
||||
AddAssert("Check legacy version lookup", () => requester.GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version)?.Value == 1.0m);
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using NUnit.Framework;
|
||||
@ -21,6 +19,7 @@ using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens;
|
||||
@ -29,6 +28,7 @@ using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Play.PlayerSettings;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
@ -39,15 +39,6 @@ namespace osu.Game.Tests.Visual.Background
|
||||
[TestFixture]
|
||||
public class TestSceneUserDimBackgrounds : OsuManualInputManagerTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(ScreenWithBeatmapBackground),
|
||||
typeof(PlayerLoader),
|
||||
typeof(Player),
|
||||
typeof(UserDimContainer),
|
||||
typeof(OsuScreen)
|
||||
};
|
||||
|
||||
private DummySongSelect songSelect;
|
||||
private TestPlayerLoader playerLoader;
|
||||
private LoadBlockingTestPlayer player;
|
||||
@ -79,7 +70,7 @@ namespace osu.Game.Tests.Visual.Background
|
||||
/// Check if <see cref="PlayerLoader"/> properly triggers the visual settings preview when a user hovers over the visual settings panel.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void PlayerLoaderSettingsHoverTest()
|
||||
public void TestPlayerLoaderSettingsHover()
|
||||
{
|
||||
setupUserSettings();
|
||||
AddStep("Start player loader", () => songSelect.Push(playerLoader = new TestPlayerLoader(player = new LoadBlockingTestPlayer { BlockLoad = true })));
|
||||
@ -90,11 +81,9 @@ namespace osu.Game.Tests.Visual.Background
|
||||
InputManager.MoveMouseTo(playerLoader.ScreenPos);
|
||||
InputManager.MoveMouseTo(playerLoader.VisualSettingsPos);
|
||||
});
|
||||
waitForDim();
|
||||
AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
|
||||
AddUntilStep("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
|
||||
AddStep("Stop background preview", () => InputManager.MoveMouseTo(playerLoader.ScreenPos));
|
||||
waitForDim();
|
||||
AddAssert("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && playerLoader.IsBlurCorrect());
|
||||
AddUntilStep("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && playerLoader.IsBlurCorrect());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -103,20 +92,19 @@ namespace osu.Game.Tests.Visual.Background
|
||||
/// We need to check that in this scenario, the dim and blur is still properly applied after entering player.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void PlayerLoaderTransitionTest()
|
||||
public void TestPlayerLoaderTransition()
|
||||
{
|
||||
performFullSetup();
|
||||
AddStep("Trigger hover event", () => playerLoader.TriggerOnHover());
|
||||
AddAssert("Background retained from song select", () => songSelect.IsBackgroundCurrent());
|
||||
waitForDim();
|
||||
AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
|
||||
AddUntilStep("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make sure the background is fully invisible (Alpha == 0) when the background should be disabled by the storyboard.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void StoryboardBackgroundVisibilityTest()
|
||||
public void TestStoryboardBackgroundVisibility()
|
||||
{
|
||||
performFullSetup();
|
||||
createFakeStoryboard();
|
||||
@ -125,52 +113,46 @@ namespace osu.Game.Tests.Visual.Background
|
||||
player.ReplacesBackground.Value = true;
|
||||
player.StoryboardEnabled.Value = true;
|
||||
});
|
||||
waitForDim();
|
||||
AddAssert("Background is invisible, storyboard is visible", () => songSelect.IsBackgroundInvisible() && player.IsStoryboardVisible);
|
||||
AddUntilStep("Background is invisible, storyboard is visible", () => songSelect.IsBackgroundInvisible() && player.IsStoryboardVisible);
|
||||
AddStep("Disable Storyboard", () =>
|
||||
{
|
||||
player.ReplacesBackground.Value = false;
|
||||
player.StoryboardEnabled.Value = false;
|
||||
});
|
||||
waitForDim();
|
||||
AddAssert("Background is visible, storyboard is invisible", () => songSelect.IsBackgroundVisible() && !player.IsStoryboardVisible);
|
||||
AddUntilStep("Background is visible, storyboard is invisible", () => songSelect.IsBackgroundVisible() && !player.IsStoryboardVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When exiting player, the screen that it suspends/exits to needs to have a fully visible (Alpha == 1) background.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void StoryboardTransitionTest()
|
||||
public void TestStoryboardTransition()
|
||||
{
|
||||
performFullSetup();
|
||||
createFakeStoryboard();
|
||||
AddStep("Exit to song select", () => player.Exit());
|
||||
waitForDim();
|
||||
AddAssert("Background is visible", () => songSelect.IsBackgroundVisible());
|
||||
AddUntilStep("Background is visible", () => songSelect.IsBackgroundVisible());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensure <see cref="UserDimContainer"/> is properly accepting user-defined visual changes for a background.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void DisableUserDimBackgroundTest()
|
||||
public void TestDisableUserDimBackground()
|
||||
{
|
||||
performFullSetup();
|
||||
waitForDim();
|
||||
AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
|
||||
AddUntilStep("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
|
||||
AddStep("Enable user dim", () => songSelect.DimEnabled.Value = false);
|
||||
waitForDim();
|
||||
AddAssert("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && songSelect.IsUserBlurDisabled());
|
||||
AddUntilStep("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && songSelect.IsUserBlurDisabled());
|
||||
AddStep("Disable user dim", () => songSelect.DimEnabled.Value = true);
|
||||
waitForDim();
|
||||
AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
|
||||
AddUntilStep("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensure <see cref="UserDimContainer"/> is properly accepting user-defined visual changes for a storyboard.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void DisableUserDimStoryboardTest()
|
||||
public void TestDisableUserDimStoryboard()
|
||||
{
|
||||
performFullSetup();
|
||||
createFakeStoryboard();
|
||||
@ -181,41 +163,42 @@ namespace osu.Game.Tests.Visual.Background
|
||||
});
|
||||
AddStep("Enable user dim", () => player.DimmableStoryboard.EnableUserDim.Value = true);
|
||||
AddStep("Set dim level to 1", () => songSelect.DimLevel.Value = 1f);
|
||||
waitForDim();
|
||||
AddAssert("Storyboard is invisible", () => !player.IsStoryboardVisible);
|
||||
AddUntilStep("Storyboard is invisible", () => !player.IsStoryboardVisible);
|
||||
AddStep("Disable user dim", () => player.DimmableStoryboard.EnableUserDim.Value = false);
|
||||
waitForDim();
|
||||
AddAssert("Storyboard is visible", () => player.IsStoryboardVisible);
|
||||
AddUntilStep("Storyboard is visible", () => player.IsStoryboardVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the visual settings container retains dim and blur when pausing
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void PauseTest()
|
||||
public void TestPause()
|
||||
{
|
||||
performFullSetup(true);
|
||||
AddStep("Pause", () => player.Pause());
|
||||
waitForDim();
|
||||
AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
|
||||
AddUntilStep("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
|
||||
AddStep("Unpause", () => player.Resume());
|
||||
waitForDim();
|
||||
AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
|
||||
AddUntilStep("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the visual settings container removes user dim when suspending <see cref="Player"/> for <see cref="ResultsScreen"/>
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TransitionTest()
|
||||
public void TestTransition()
|
||||
{
|
||||
performFullSetup();
|
||||
|
||||
FadeAccessibleResults results = null;
|
||||
AddStep("Transition to Results", () => player.Push(results =
|
||||
new FadeAccessibleResults(new ScoreInfo { User = new User { Username = "osu!" } })));
|
||||
|
||||
AddStep("Transition to Results", () => player.Push(results = new FadeAccessibleResults(new ScoreInfo
|
||||
{
|
||||
User = new User { Username = "osu!" },
|
||||
Beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo
|
||||
})));
|
||||
|
||||
AddUntilStep("Wait for results is current", () => results.IsCurrentScreen());
|
||||
waitForDim();
|
||||
AddAssert("Screen is undimmed, original background retained", () =>
|
||||
AddUntilStep("Screen is undimmed, original background retained", () =>
|
||||
songSelect.IsBackgroundUndimmed() && songSelect.IsBackgroundCurrent() && results.IsBlurCorrect());
|
||||
}
|
||||
|
||||
@ -223,32 +206,27 @@ namespace osu.Game.Tests.Visual.Background
|
||||
/// Check if background gets undimmed and unblurred when leaving <see cref="Player"/> for <see cref="PlaySongSelect"/>
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TransitionOutTest()
|
||||
public void TestTransitionOut()
|
||||
{
|
||||
performFullSetup();
|
||||
AddStep("Exit to song select", () => player.Exit());
|
||||
waitForDim();
|
||||
AddAssert("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && songSelect.IsBlurCorrect());
|
||||
AddUntilStep("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && songSelect.IsBlurCorrect());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if hovering on the visual settings dialogue after resuming from player still previews the background dim.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ResumeFromPlayerTest()
|
||||
public void TestResumeFromPlayer()
|
||||
{
|
||||
performFullSetup();
|
||||
AddStep("Move mouse to Visual Settings", () => InputManager.MoveMouseTo(playerLoader.VisualSettingsPos));
|
||||
AddStep("Resume PlayerLoader", () => player.Restart());
|
||||
waitForDim();
|
||||
AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
|
||||
AddUntilStep("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied());
|
||||
AddStep("Move mouse to center of screen", () => InputManager.MoveMouseTo(playerLoader.ScreenPos));
|
||||
waitForDim();
|
||||
AddAssert("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && playerLoader.IsBlurCorrect());
|
||||
AddUntilStep("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && playerLoader.IsBlurCorrect());
|
||||
}
|
||||
|
||||
private void waitForDim() => AddWaitStep("Wait for dim", 5);
|
||||
|
||||
private void createFakeStoryboard() => AddStep("Create storyboard", () =>
|
||||
{
|
||||
player.StoryboardEnabled.Value = false;
|
||||
|
@ -2,7 +2,6 @@
|
||||
// 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;
|
||||
@ -14,11 +13,10 @@ using osu.Game.Screens.Edit.Compose.Components;
|
||||
using osuTK;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
public class TestSceneBeatDivisorControl : OsuManualInputManagerTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(BindableBeatDivisor) };
|
||||
private BeatDivisorControl beatDivisorControl;
|
||||
private BindableBeatDivisor bindableBeatDivisor;
|
||||
|
@ -9,7 +9,7 @@ using osu.Game.Rulesets.Osu.Beatmaps;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.Edit.Compose;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneComposeScreen : EditorClockTestScene
|
@ -13,7 +13,7 @@ using osu.Game.Screens.Edit.Compose.Components;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
public class TestSceneDistanceSnapGrid : EditorClockTestScene
|
||||
{
|
||||
@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual.Editor
|
||||
[Cached(typeof(EditorBeatmap))]
|
||||
private readonly EditorBeatmap editorBeatmap;
|
||||
|
||||
[Cached(typeof(IDistanceSnapProvider))]
|
||||
[Cached(typeof(IPositionSnapProvider))]
|
||||
private readonly SnapProvider snapProvider = new SnapProvider();
|
||||
|
||||
public TestSceneDistanceSnapGrid()
|
||||
@ -151,9 +151,9 @@ namespace osu.Game.Tests.Visual.Editor
|
||||
=> (Vector2.Zero, 0);
|
||||
}
|
||||
|
||||
private class SnapProvider : IDistanceSnapProvider
|
||||
private class SnapProvider : IPositionSnapProvider
|
||||
{
|
||||
public (Vector2 position, double time) GetSnappedPosition(Vector2 position, double time) => (position, time);
|
||||
public SnapResult SnapScreenSpacePositionToValidTime(Vector2 screenSpacePosition) => new SnapResult(screenSpacePosition, 0);
|
||||
|
||||
public float GetBeatSnapDistanceAt(double referenceTime) => 10;
|
||||
|
166
osu.Game.Tests/Visual/Editing/TestSceneEditorChangeStates.cs
Normal file
166
osu.Game.Tests/Visual/Editing/TestSceneEditorChangeStates.cs
Normal file
@ -0,0 +1,166 @@
|
||||
// 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.Testing;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Screens.Edit;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
public class TestSceneEditorChangeStates : EditorTestScene
|
||||
{
|
||||
private EditorBeatmap editorBeatmap;
|
||||
|
||||
protected override Ruleset CreateEditorRuleset() => new OsuRuleset();
|
||||
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
base.SetUpSteps();
|
||||
|
||||
AddStep("get beatmap", () => editorBeatmap = Editor.ChildrenOfType<EditorBeatmap>().Single());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUndoFromInitialState()
|
||||
{
|
||||
int hitObjectCount = 0;
|
||||
|
||||
AddStep("get initial state", () => hitObjectCount = editorBeatmap.HitObjects.Count);
|
||||
|
||||
addUndoSteps();
|
||||
|
||||
AddAssert("no change occurred", () => hitObjectCount == editorBeatmap.HitObjects.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestRedoFromInitialState()
|
||||
{
|
||||
int hitObjectCount = 0;
|
||||
|
||||
AddStep("get initial state", () => hitObjectCount = editorBeatmap.HitObjects.Count);
|
||||
|
||||
addRedoSteps();
|
||||
|
||||
AddAssert("no change occurred", () => hitObjectCount == editorBeatmap.HitObjects.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddObjectAndUndo()
|
||||
{
|
||||
HitObject addedObject = null;
|
||||
HitObject removedObject = null;
|
||||
HitObject expectedObject = null;
|
||||
|
||||
AddStep("bind removal", () =>
|
||||
{
|
||||
editorBeatmap.HitObjectAdded += h => addedObject = h;
|
||||
editorBeatmap.HitObjectRemoved += h => removedObject = h;
|
||||
});
|
||||
|
||||
AddStep("add hitobject", () => editorBeatmap.Add(expectedObject = new HitCircle { StartTime = 1000 }));
|
||||
AddAssert("hitobject added", () => addedObject == expectedObject);
|
||||
|
||||
addUndoSteps();
|
||||
AddAssert("hitobject removed", () => removedObject == expectedObject);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddObjectThenUndoThenRedo()
|
||||
{
|
||||
HitObject addedObject = null;
|
||||
HitObject removedObject = null;
|
||||
HitObject expectedObject = null;
|
||||
|
||||
AddStep("bind removal", () =>
|
||||
{
|
||||
editorBeatmap.HitObjectAdded += h => addedObject = h;
|
||||
editorBeatmap.HitObjectRemoved += h => removedObject = h;
|
||||
});
|
||||
|
||||
AddStep("add hitobject", () => editorBeatmap.Add(expectedObject = new HitCircle { StartTime = 1000 }));
|
||||
addUndoSteps();
|
||||
|
||||
AddStep("reset variables", () =>
|
||||
{
|
||||
addedObject = null;
|
||||
removedObject = null;
|
||||
});
|
||||
|
||||
addRedoSteps();
|
||||
AddAssert("hitobject added", () => addedObject.StartTime == expectedObject.StartTime); // Can't compare via equality (new hitobject instance)
|
||||
AddAssert("no hitobject removed", () => removedObject == null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestRemoveObjectThenUndo()
|
||||
{
|
||||
HitObject addedObject = null;
|
||||
HitObject removedObject = null;
|
||||
HitObject expectedObject = null;
|
||||
|
||||
AddStep("bind removal", () =>
|
||||
{
|
||||
editorBeatmap.HitObjectAdded += h => addedObject = h;
|
||||
editorBeatmap.HitObjectRemoved += h => removedObject = h;
|
||||
});
|
||||
|
||||
AddStep("add hitobject", () => editorBeatmap.Add(expectedObject = new HitCircle { StartTime = 1000 }));
|
||||
AddStep("remove object", () => editorBeatmap.Remove(expectedObject));
|
||||
AddStep("reset variables", () =>
|
||||
{
|
||||
addedObject = null;
|
||||
removedObject = null;
|
||||
});
|
||||
|
||||
addUndoSteps();
|
||||
AddAssert("hitobject added", () => addedObject.StartTime == expectedObject.StartTime); // Can't compare via equality (new hitobject instance)
|
||||
AddAssert("no hitobject removed", () => removedObject == null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestRemoveObjectThenUndoThenRedo()
|
||||
{
|
||||
HitObject addedObject = null;
|
||||
HitObject removedObject = null;
|
||||
HitObject expectedObject = null;
|
||||
|
||||
AddStep("bind removal", () =>
|
||||
{
|
||||
editorBeatmap.HitObjectAdded += h => addedObject = h;
|
||||
editorBeatmap.HitObjectRemoved += h => removedObject = h;
|
||||
});
|
||||
|
||||
AddStep("add hitobject", () => editorBeatmap.Add(expectedObject = new HitCircle { StartTime = 1000 }));
|
||||
AddStep("remove object", () => editorBeatmap.Remove(expectedObject));
|
||||
addUndoSteps();
|
||||
|
||||
AddStep("reset variables", () =>
|
||||
{
|
||||
addedObject = null;
|
||||
removedObject = null;
|
||||
});
|
||||
|
||||
addRedoSteps();
|
||||
AddAssert("hitobject removed", () => removedObject.StartTime == expectedObject.StartTime); // Can't compare via equality (new hitobject instance after undo)
|
||||
AddAssert("no hitobject added", () => addedObject == null);
|
||||
}
|
||||
|
||||
private void addUndoSteps() => AddStep("undo", () => ((TestEditor)Editor).Undo());
|
||||
|
||||
private void addRedoSteps() => AddStep("redo", () => ((TestEditor)Editor).Redo());
|
||||
|
||||
protected override Editor CreateEditor() => new TestEditor();
|
||||
|
||||
private class TestEditor : Editor
|
||||
{
|
||||
public new void Undo() => base.Undo();
|
||||
|
||||
public new void Redo() => base.Redo();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,19 +1,15 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Screens.Edit.Components.RadioButtons;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneEditorComposeRadioButtons : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(DrawableRadioButton) };
|
||||
|
||||
public TestSceneEditorComposeRadioButtons()
|
||||
{
|
||||
RadioButtonCollection collection;
|
@ -1,8 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
@ -10,13 +8,11 @@ using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Screens.Edit.Components.Menus;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneEditorMenuBar : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(EditorMenuBar), typeof(ScreenSelectionTabControl) };
|
||||
|
||||
public TestSceneEditorMenuBar()
|
||||
{
|
||||
Add(new Container
|
@ -13,7 +13,7 @@ using osu.Game.Rulesets.Osu.Objects;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneEditorSeekSnapping : EditorClockTestScene
|
@ -1,8 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
@ -10,13 +8,11 @@ using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.Edit.Components.Timelines.Summary;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneEditorSummaryTimeline : EditorClockTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(SummaryTimeline) };
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
@ -1,9 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Timing;
|
||||
@ -13,31 +11,15 @@ using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Edit;
|
||||
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles;
|
||||
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.Edit.Compose.Components;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneHitObjectComposer : EditorClockTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(SelectionHandler),
|
||||
typeof(DragBox),
|
||||
typeof(HitObjectComposer),
|
||||
typeof(OsuHitObjectComposer),
|
||||
typeof(BlueprintContainer),
|
||||
typeof(NotNullAttribute),
|
||||
typeof(HitCirclePiece),
|
||||
typeof(HitCircleSelectionBlueprint),
|
||||
typeof(HitCirclePlacementBlueprint),
|
||||
};
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
@ -4,12 +4,12 @@
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.Edit.Components;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestScenePlaybackControl : OsuTestScene
|
||||
@ -17,9 +17,8 @@ namespace osu.Game.Tests.Visual.Editor
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
var clock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
|
||||
Dependencies.CacheAs<IAdjustableClock>(clock);
|
||||
Dependencies.CacheAs<IFrameBasedClock>(clock);
|
||||
var clock = new EditorClock { IsCoupled = false };
|
||||
Dependencies.CacheAs(clock);
|
||||
|
||||
var playback = new PlaybackControl
|
||||
{
|
@ -1,22 +1,15 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Screens.Edit.Compose.Components.Timeline;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneTimelineBlueprintContainer : TimelineTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(TimelineHitObjectBlueprint),
|
||||
};
|
||||
|
||||
public override Drawable CreateTestComponent() => new TimelineBlueprintContainer();
|
||||
|
||||
protected override void LoadComplete()
|
@ -8,7 +8,7 @@ using osu.Game.Screens.Edit.Compose.Components;
|
||||
using osu.Game.Screens.Edit.Compose.Components.Timeline;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneTimelineTickDisplay : TimelineTestScene
|
@ -1,31 +1,17 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.Edit.Timing;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneTimingScreen : EditorClockTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(ControlPointTable),
|
||||
typeof(ControlPointSettings),
|
||||
typeof(Section<>),
|
||||
typeof(TimingSection),
|
||||
typeof(EffectSection),
|
||||
typeof(SampleSection),
|
||||
typeof(DifficultySection),
|
||||
typeof(RowAttribute)
|
||||
};
|
||||
|
||||
[Cached(typeof(EditorBeatmap))]
|
||||
private readonly EditorBeatmap editorBeatmap;
|
||||
|
@ -14,7 +14,7 @@ using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneWaveform : OsuTestScene
|
@ -15,7 +15,7 @@ using osu.Game.Screens.Edit.Compose.Components.Timeline;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
public class TestSceneZoomableScrollContainer : OsuManualInputManagerTestScene
|
||||
{
|
@ -1,15 +1,12 @@
|
||||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
@ -18,18 +15,10 @@ using osu.Game.Screens.Edit.Compose.Components.Timeline;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
namespace osu.Game.Tests.Visual.Editing
|
||||
{
|
||||
public abstract class TimelineTestScene : EditorClockTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(TimelineArea),
|
||||
typeof(Timeline),
|
||||
typeof(TimelineButton),
|
||||
typeof(CentreMarker)
|
||||
};
|
||||
|
||||
protected TimelineArea TimelineArea { get; private set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -79,7 +68,7 @@ namespace osu.Game.Tests.Visual.Editor
|
||||
private IBindable<WorkingBeatmap> beatmap { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private IAdjustableClock adjustableClock { get; set; }
|
||||
private EditorClock editorClock { get; set; }
|
||||
|
||||
public AudioVisualiser()
|
||||
{
|
||||
@ -106,13 +95,15 @@ namespace osu.Game.Tests.Visual.Editor
|
||||
base.Update();
|
||||
|
||||
if (beatmap.Value.Track.IsLoaded)
|
||||
marker.X = (float)(adjustableClock.CurrentTime / beatmap.Value.Track.Length);
|
||||
marker.X = (float)(editorClock.CurrentTime / beatmap.Value.Track.Length);
|
||||
}
|
||||
}
|
||||
|
||||
private class StartStopButton : OsuButton
|
||||
{
|
||||
private IAdjustableClock adjustableClock;
|
||||
[Resolved]
|
||||
private EditorClock editorClock { get; set; }
|
||||
|
||||
private bool started;
|
||||
|
||||
public StartStopButton()
|
||||
@ -124,22 +115,16 @@ namespace osu.Game.Tests.Visual.Editor
|
||||
Action = onClick;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IAdjustableClock adjustableClock)
|
||||
{
|
||||
this.adjustableClock = adjustableClock;
|
||||
}
|
||||
|
||||
private void onClick()
|
||||
{
|
||||
if (started)
|
||||
{
|
||||
adjustableClock.Stop();
|
||||
editorClock.Stop();
|
||||
Text = "Start";
|
||||
}
|
||||
else
|
||||
{
|
||||
adjustableClock.Start();
|
||||
editorClock.Start();
|
||||
Text = "Stop";
|
||||
}
|
||||
|
16
osu.Game.Tests/Visual/Gameplay/OsuPlayerTestScene.cs
Normal file
16
osu.Game.Tests/Visual/Gameplay/OsuPlayerTestScene.cs
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="PlayerTestScene"/> with an arbitrary ruleset value to test with.
|
||||
/// </summary>
|
||||
public abstract class OsuPlayerTestScene : PlayerTestScene
|
||||
{
|
||||
protected override Ruleset CreatePlayerRuleset() => new OsuRuleset();
|
||||
}
|
||||
}
|
@ -52,7 +52,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
AddStep($"seek to break {breakIndex}", () => Player.GameplayClockContainer.Seek(destBreak().StartTime));
|
||||
AddUntilStep("wait for seek to complete", () => Player.HUDOverlay.Progress.ReferenceClock.CurrentTime >= destBreak().StartTime);
|
||||
|
||||
BreakPeriod destBreak() => Player.ChildrenOfType<BreakTracker>().First().Breaks.ElementAt(breakIndex);
|
||||
BreakPeriod destBreak() => Beatmap.Value.Beatmap.Breaks.ElementAt(breakIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
@ -15,11 +14,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[TestFixture]
|
||||
public class TestSceneBreakTracker : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(BreakOverlay),
|
||||
};
|
||||
|
||||
private readonly BreakOverlay breakOverlay;
|
||||
|
||||
private readonly TestBreakTracker breakTracker;
|
||||
@ -97,8 +91,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
loadBreaksStep("multiple breaks", testBreaks);
|
||||
|
||||
seekAndAssertBreak("seek to break start", testBreaks[1].StartTime, true);
|
||||
AddAssert("is skipped to break #2", () => breakTracker.CurrentBreakIndex == 1);
|
||||
|
||||
seekAndAssertBreak("seek to break middle", testBreaks[1].StartTime + testBreaks[1].Duration / 2, true);
|
||||
seekAndAssertBreak("seek to break end", testBreaks[1].EndTime, false);
|
||||
seekAndAssertBreak("seek to break after end", testBreaks[1].EndTime + 500, false);
|
||||
@ -174,8 +166,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
private readonly ManualClock manualClock;
|
||||
private IFrameBasedClock originalClock;
|
||||
|
||||
public new int CurrentBreakIndex => base.CurrentBreakIndex;
|
||||
|
||||
public double ManualClockTime
|
||||
{
|
||||
get => manualClock.CurrentTime;
|
||||
|
@ -0,0 +1,133 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Storyboards;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
public class TestSceneCompletionCancellation : OsuPlayerTestScene
|
||||
{
|
||||
private Track track;
|
||||
|
||||
[Resolved]
|
||||
private AudioManager audio { get; set; }
|
||||
|
||||
private int resultsDisplayWaitCount =>
|
||||
(int)((Screens.Play.Player.RESULTS_DISPLAY_DELAY / TimePerAction) * 2);
|
||||
|
||||
protected override bool AllowFail => false;
|
||||
|
||||
[SetUpSteps]
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
base.SetUpSteps();
|
||||
|
||||
// Ensure track has actually running before attempting to seek
|
||||
AddUntilStep("wait for track to start running", () => track.IsRunning);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCancelCompletionOnRewind()
|
||||
{
|
||||
complete();
|
||||
cancel();
|
||||
|
||||
checkNoRanking();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestReCompleteAfterCancellation()
|
||||
{
|
||||
complete();
|
||||
cancel();
|
||||
complete();
|
||||
|
||||
AddUntilStep("attempted to push ranking", () => ((FakeRankingPushPlayer)Player).GotoRankingInvoked);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests whether can still pause after cancelling completion by reverting <see cref="IScreen.ValidForResume"/> back to true.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCanPauseAfterCancellation()
|
||||
{
|
||||
complete();
|
||||
cancel();
|
||||
|
||||
AddStep("pause", () => Player.Pause());
|
||||
AddAssert("paused successfully", () => Player.GameplayClockContainer.IsPaused.Value);
|
||||
|
||||
checkNoRanking();
|
||||
}
|
||||
|
||||
private void complete()
|
||||
{
|
||||
AddStep("seek to completion", () => track.Seek(5000));
|
||||
AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value);
|
||||
}
|
||||
|
||||
private void cancel()
|
||||
{
|
||||
AddStep("rewind to cancel", () => track.Seek(4000));
|
||||
AddUntilStep("completion cleared by processor", () => !Player.ScoreProcessor.HasCompleted.Value);
|
||||
}
|
||||
|
||||
private void checkNoRanking()
|
||||
{
|
||||
// wait to ensure there was no attempt of pushing the results screen.
|
||||
AddWaitStep("wait", resultsDisplayWaitCount);
|
||||
AddAssert("no attempt to push ranking", () => !((FakeRankingPushPlayer)Player).GotoRankingInvoked);
|
||||
}
|
||||
|
||||
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null)
|
||||
{
|
||||
var working = new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audio);
|
||||
track = working.Track;
|
||||
return working;
|
||||
}
|
||||
|
||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
||||
{
|
||||
var beatmap = new Beatmap();
|
||||
|
||||
for (int i = 1; i <= 19; i++)
|
||||
{
|
||||
beatmap.HitObjects.Add(new HitCircle
|
||||
{
|
||||
Position = new Vector2(256, 192),
|
||||
StartTime = i * 250,
|
||||
});
|
||||
}
|
||||
|
||||
return beatmap;
|
||||
}
|
||||
|
||||
protected override TestPlayer CreatePlayer(Ruleset ruleset) => new FakeRankingPushPlayer();
|
||||
|
||||
public class FakeRankingPushPlayer : TestPlayer
|
||||
{
|
||||
public bool GotoRankingInvoked;
|
||||
|
||||
public FakeRankingPushPlayer()
|
||||
: base(true, true)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void GotoRanking()
|
||||
{
|
||||
GotoRankingInvoked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -281,7 +281,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
yield return new TestHitObject
|
||||
{
|
||||
StartTime = original.StartTime,
|
||||
EndTime = (original as IHasEndTime)?.EndTime ?? (original.StartTime + 100)
|
||||
Duration = (original as IHasDuration)?.Duration ?? 100
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -290,11 +290,11 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
#region HitObject
|
||||
|
||||
private class TestHitObject : ConvertHitObject, IHasEndTime
|
||||
private class TestHitObject : ConvertHitObject, IHasDuration
|
||||
{
|
||||
public double EndTime { get; set; }
|
||||
public double EndTime => StartTime + Duration;
|
||||
|
||||
public double Duration => EndTime - StartTime;
|
||||
public double Duration { get; set; }
|
||||
}
|
||||
|
||||
private class DrawableTestHitObject : DrawableHitObject<TestHitObject>
|
||||
|
@ -2,7 +2,6 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
@ -18,13 +17,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
return new FailPlayer();
|
||||
}
|
||||
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(TestSceneAllRulesetPlayers),
|
||||
typeof(TestPlayer),
|
||||
typeof(Player),
|
||||
};
|
||||
|
||||
protected override void AddCheckSteps()
|
||||
{
|
||||
AddUntilStep("wait for fail", () => Player.HasFailed);
|
||||
|
73
osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs
Normal file
73
osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs
Normal file
@ -0,0 +1,73 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
public class TestSceneFailingLayer : OsuTestScene
|
||||
{
|
||||
private FailingLayer layer;
|
||||
|
||||
[Resolved]
|
||||
private OsuConfigManager config { get; set; }
|
||||
|
||||
[SetUpSteps]
|
||||
public void SetUpSteps()
|
||||
{
|
||||
AddStep("create layer", () =>
|
||||
{
|
||||
Child = layer = new FailingLayer();
|
||||
layer.BindHealthProcessor(new DrainingHealthProcessor(1));
|
||||
});
|
||||
|
||||
AddStep("enable layer", () => config.Set(OsuSetting.FadePlayfieldWhenHealthLow, true));
|
||||
AddUntilStep("layer is visible", () => layer.IsPresent);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLayerFading()
|
||||
{
|
||||
AddSliderStep("current health", 0.0, 1.0, 1.0, val =>
|
||||
{
|
||||
if (layer != null)
|
||||
layer.Current.Value = val;
|
||||
});
|
||||
|
||||
AddStep("set health to 0.10", () => layer.Current.Value = 0.1);
|
||||
AddUntilStep("layer fade is visible", () => layer.Child.Alpha > 0.1f);
|
||||
AddStep("set health to 1", () => layer.Current.Value = 1f);
|
||||
AddUntilStep("layer fade is invisible", () => !layer.Child.IsPresent);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLayerDisabledViaConfig()
|
||||
{
|
||||
AddStep("disable layer", () => config.Set(OsuSetting.FadePlayfieldWhenHealthLow, false));
|
||||
AddStep("set health to 0.10", () => layer.Current.Value = 0.1);
|
||||
AddUntilStep("layer is not visible", () => !layer.IsPresent);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLayerVisibilityWithAccumulatingProcessor()
|
||||
{
|
||||
AddStep("bind accumulating processor", () => layer.BindHealthProcessor(new AccumulatingHealthProcessor(1)));
|
||||
AddStep("set health to 0.10", () => layer.Current.Value = 0.1);
|
||||
AddUntilStep("layer is not visible", () => !layer.IsPresent);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLayerVisibilityWithDrainingProcessor()
|
||||
{
|
||||
AddStep("bind accumulating processor", () => layer.BindHealthProcessor(new DrainingHealthProcessor(1)));
|
||||
AddStep("set health to 0.10", () => layer.Current.Value = 0.1);
|
||||
AddWaitStep("wait for potential fade", 10);
|
||||
AddAssert("layer is still visible", () => layer.IsPresent);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
// 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.Allocation;
|
||||
@ -20,8 +19,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[Description("player pause/fail screens")]
|
||||
public class TestSceneGameplayMenuOverlay : OsuManualInputManagerTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(FailOverlay), typeof(PauseOverlay) };
|
||||
|
||||
private FailOverlay failOverlay;
|
||||
private PauseOverlay pauseOverlay;
|
||||
|
||||
|
@ -10,23 +10,17 @@ using osu.Framework.Utils;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Storyboards;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
public class TestSceneGameplayRewinding : PlayerTestScene
|
||||
public class TestSceneGameplayRewinding : OsuPlayerTestScene
|
||||
{
|
||||
[Resolved]
|
||||
private AudioManager audioManager { get; set; }
|
||||
|
||||
public TestSceneGameplayRewinding()
|
||||
: base(new OsuRuleset())
|
||||
{
|
||||
}
|
||||
|
||||
private Track track;
|
||||
|
||||
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null)
|
||||
|
@ -2,8 +2,6 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Framework.Graphics;
|
||||
@ -22,13 +20,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
public class TestSceneHitErrorMeter : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(HitErrorMeter),
|
||||
typeof(BarHitErrorMeter),
|
||||
typeof(ColourHitErrorMeter)
|
||||
};
|
||||
|
||||
private BarHitErrorMeter barMeter;
|
||||
private BarHitErrorMeter barMeter2;
|
||||
private ColourHitErrorMeter colourMeter;
|
||||
|
98
osu.Game.Tests/Visual/Gameplay/TestSceneKeyBindings.cs
Normal file
98
osu.Game.Tests/Visual/Gameplay/TestSceneKeyBindings.cs
Normal file
@ -0,0 +1,98 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Difficulty;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
[HeadlessTest]
|
||||
public class TestSceneKeyBindings : OsuManualInputManagerTestScene
|
||||
{
|
||||
private readonly ActionReceiver receiver;
|
||||
|
||||
public TestSceneKeyBindings()
|
||||
{
|
||||
Add(new TestKeyBindingContainer
|
||||
{
|
||||
Child = receiver = new ActionReceiver()
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDefaultsWhenNotDatabased()
|
||||
{
|
||||
AddStep("fire key", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.A);
|
||||
InputManager.ReleaseKey(Key.A);
|
||||
});
|
||||
|
||||
AddAssert("received key", () => receiver.ReceivedAction);
|
||||
}
|
||||
|
||||
private class TestRuleset : Ruleset
|
||||
{
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type) =>
|
||||
throw new System.NotImplementedException();
|
||||
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) =>
|
||||
throw new System.NotImplementedException();
|
||||
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) =>
|
||||
throw new System.NotImplementedException();
|
||||
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) =>
|
||||
throw new System.NotImplementedException();
|
||||
|
||||
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0)
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new KeyBinding(InputKey.A, TestAction.Down),
|
||||
};
|
||||
}
|
||||
|
||||
public override string Description => "test";
|
||||
public override string ShortName => "test";
|
||||
}
|
||||
|
||||
private enum TestAction
|
||||
{
|
||||
Down,
|
||||
}
|
||||
|
||||
private class TestKeyBindingContainer : DatabasedKeyBindingContainer<TestAction>
|
||||
{
|
||||
public TestKeyBindingContainer()
|
||||
: base(new TestRuleset().RulesetInfo, 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private class ActionReceiver : CompositeDrawable, IKeyBindingHandler<TestAction>
|
||||
{
|
||||
public bool ReceivedAction;
|
||||
|
||||
public bool OnPressed(TestAction action)
|
||||
{
|
||||
ReceivedAction = action == TestAction.Down;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnReleased(TestAction action)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
@ -15,13 +13,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[TestFixture]
|
||||
public class TestSceneKeyCounter : OsuManualInputManagerTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(KeyCounterKeyboard),
|
||||
typeof(KeyCounterMouse),
|
||||
typeof(KeyCounterDisplay)
|
||||
};
|
||||
|
||||
public TestSceneKeyCounter()
|
||||
{
|
||||
KeyCounterKeyboard testCounter;
|
||||
|
@ -1,11 +1,8 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.MedalSplash;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
@ -13,12 +10,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[TestFixture]
|
||||
public class TestSceneMedalOverlay : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(MedalOverlay),
|
||||
typeof(DrawableMedal),
|
||||
};
|
||||
|
||||
public TestSceneMedalOverlay()
|
||||
{
|
||||
AddStep(@"display", () =>
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Game.Beatmaps.Timing;
|
||||
@ -15,11 +13,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
public class TestSceneNightcoreBeatContainer : TestSceneBeatSyncedContainer
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(ModNightcore<>)
|
||||
};
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
@ -10,14 +10,13 @@ using osu.Framework.Testing;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Cursor;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.Play;
|
||||
using osuTK;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
public class TestScenePause : PlayerTestScene
|
||||
public class TestScenePause : OsuPlayerTestScene
|
||||
{
|
||||
protected new PausePlayer Player => (PausePlayer)base.Player;
|
||||
|
||||
@ -26,7 +25,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
protected override Container<Drawable> Content => content;
|
||||
|
||||
public TestScenePause()
|
||||
: base(new OsuRuleset())
|
||||
{
|
||||
base.Content.Add(content = new MenuCursorContainer { RelativeSizeAxes = Axes.Both });
|
||||
}
|
||||
|
@ -8,12 +8,11 @@ using osu.Framework.Platform;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
[HeadlessTest] // we alter unsafe properties on the game host to test inactive window state.
|
||||
public class TestScenePauseWhenInactive : PlayerTestScene
|
||||
public class TestScenePauseWhenInactive : OsuPlayerTestScene
|
||||
{
|
||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
||||
{
|
||||
@ -27,11 +26,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[Resolved]
|
||||
private GameHost host { get; set; }
|
||||
|
||||
public TestScenePauseWhenInactive()
|
||||
: base(new OsuRuleset())
|
||||
{
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoesntPauseDuringIntro()
|
||||
{
|
||||
|
@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
var beatmap = Beatmap.Value.GetPlayableBeatmap(ruleset.RulesetInfo, Array.Empty<Mod>());
|
||||
|
||||
return new ScoreAccessibleReplayPlayer(ruleset.GetAutoplayMod().CreateReplayScore(beatmap));
|
||||
return new ScoreAccessibleReplayPlayer(ruleset.GetAutoplayMod()?.CreateReplayScore(beatmap));
|
||||
}
|
||||
|
||||
protected override void AddCheckSteps()
|
||||
@ -33,7 +33,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
||||
public new HUDOverlay HUDOverlay => base.HUDOverlay;
|
||||
public new bool AllowFail => base.AllowFail;
|
||||
|
||||
public bool AllowFail => base.CheckModsAllowFailure();
|
||||
|
||||
protected override bool PauseOnFocusLost => false;
|
||||
|
||||
|
@ -7,8 +7,6 @@ using osu.Game.Online;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.Ranking;
|
||||
@ -21,11 +19,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[Resolved]
|
||||
private RulesetStore rulesets { get; set; }
|
||||
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(ReplayDownloadButton)
|
||||
};
|
||||
|
||||
private TestReplayDownloadButton downloadButton;
|
||||
|
||||
public TestSceneReplayDownloadButton()
|
||||
@ -35,6 +28,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
AddStep(@"locally available state", () => downloadButton.SetDownloadState(DownloadState.LocallyAvailable));
|
||||
AddStep(@"not downloaded state", () => downloadButton.SetDownloadState(DownloadState.NotDownloaded));
|
||||
createButton(false);
|
||||
createButtonNoScore();
|
||||
}
|
||||
|
||||
private void createButton(bool withReplay)
|
||||
@ -47,6 +41,22 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
Origin = Anchor.Centre,
|
||||
};
|
||||
});
|
||||
|
||||
AddUntilStep("wait for load", () => downloadButton.IsLoaded);
|
||||
}
|
||||
|
||||
private void createButtonNoScore()
|
||||
{
|
||||
AddStep("create button with null score", () =>
|
||||
{
|
||||
Child = downloadButton = new TestReplayDownloadButton(null)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
};
|
||||
});
|
||||
|
||||
AddUntilStep("wait for load", () => downloadButton.IsLoaded);
|
||||
}
|
||||
|
||||
private ScoreInfo getScoreInfo(bool replayAvailable)
|
||||
|
@ -16,8 +16,8 @@ using osu.Game.Configuration;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.Timing;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
@ -27,8 +27,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[TestFixture]
|
||||
public class TestSceneScrollingHitObjects : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(Playfield) };
|
||||
|
||||
[Cached(typeof(IReadOnlyList<Mod>))]
|
||||
private IReadOnlyList<Mod> mods { get; set; } = Array.Empty<Mod>();
|
||||
|
||||
@ -80,19 +78,18 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
}
|
||||
};
|
||||
|
||||
setUpHitObjects();
|
||||
hitObjectSpawnDelegate?.Cancel();
|
||||
});
|
||||
|
||||
private void setUpHitObjects()
|
||||
private void setUpHitObjects() => AddStep("set up hit objects", () =>
|
||||
{
|
||||
scrollContainers.ForEach(c => c.ControlPoints.Add(new MultiplierControlPoint(0)));
|
||||
|
||||
for (int i = spawn_rate / 2; i <= time_range; i += spawn_rate)
|
||||
addHitObject(Time.Current + i);
|
||||
|
||||
hitObjectSpawnDelegate?.Cancel();
|
||||
hitObjectSpawnDelegate = Scheduler.AddDelayed(() => addHitObject(Time.Current + time_range), spawn_rate, true);
|
||||
}
|
||||
});
|
||||
|
||||
private IList<MultiplierControlPoint> testControlPoints => new List<MultiplierControlPoint>
|
||||
{
|
||||
@ -104,6 +101,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[Test]
|
||||
public void TestScrollAlgorithms()
|
||||
{
|
||||
setUpHitObjects();
|
||||
|
||||
AddStep("constant scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Constant));
|
||||
AddStep("overlapping scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Overlapping));
|
||||
AddStep("sequential scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Sequential));
|
||||
@ -116,6 +115,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[Test]
|
||||
public void TestConstantScrollLifetime()
|
||||
{
|
||||
setUpHitObjects();
|
||||
|
||||
AddStep("set constant scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Constant));
|
||||
// scroll container time range must be less than the rate of spawning hitobjects
|
||||
// otherwise the hitobjects will spawn already partly visible on screen and look wrong
|
||||
@ -125,14 +126,40 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[Test]
|
||||
public void TestSequentialScrollLifetime()
|
||||
{
|
||||
setUpHitObjects();
|
||||
|
||||
AddStep("set sequential scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Sequential));
|
||||
AddStep("set time range", () => scrollContainers.ForEach(c => c.TimeRange = time_range / 2.0));
|
||||
AddStep("add control points", () => addControlPoints(testControlPoints, Time.Current));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSlowSequentialScroll()
|
||||
{
|
||||
AddStep("set sequential scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Sequential));
|
||||
AddStep("set time range", () => scrollContainers.ForEach(c => c.TimeRange = time_range));
|
||||
AddStep("add control points", () => addControlPoints(
|
||||
new List<MultiplierControlPoint>
|
||||
{
|
||||
new MultiplierControlPoint { Velocity = 0.1 }
|
||||
},
|
||||
Time.Current + time_range));
|
||||
|
||||
// All of the hit objects added below should be immediately visible on screen
|
||||
AddStep("add hit objects", () =>
|
||||
{
|
||||
for (int i = 0; i < 20; ++i)
|
||||
{
|
||||
addHitObject(Time.Current + time_range * (2 + 0.1 * i));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestOverlappingScrollLifetime()
|
||||
{
|
||||
setUpHitObjects();
|
||||
|
||||
AddStep("set overlapping scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Overlapping));
|
||||
AddStep("set time range", () => scrollContainers.ForEach(c => c.TimeRange = time_range / 2.0));
|
||||
AddStep("add control points", () => addControlPoints(testControlPoints, Time.Current));
|
||||
@ -224,7 +251,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
private class TestDrawableControlPoint : DrawableHitObject<HitObject>
|
||||
{
|
||||
public TestDrawableControlPoint(ScrollingDirection direction, double time)
|
||||
: base(new HitObject { StartTime = time })
|
||||
: base(new HitObject { StartTime = time, HitWindows = HitWindows.Empty })
|
||||
{
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
@ -255,7 +282,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
private class TestDrawableHitObject : DrawableHitObject<HitObject>
|
||||
{
|
||||
public TestDrawableHitObject(double time)
|
||||
: base(new HitObject { StartTime = time })
|
||||
: base(new HitObject { StartTime = time, HitWindows = HitWindows.Empty })
|
||||
{
|
||||
Origin = Anchor.Custom;
|
||||
OriginPosition = new Vector2(75 / 4.0f);
|
||||
|
@ -2,9 +2,9 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.Play;
|
||||
@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[TestFixture]
|
||||
public class TestSceneSkipOverlay : OsuManualInputManagerTestScene
|
||||
{
|
||||
private SkipOverlay skip;
|
||||
private TestSkipOverlay skip;
|
||||
private int requestCount;
|
||||
|
||||
private double increment;
|
||||
@ -37,7 +37,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
skip = new SkipOverlay(skip_time)
|
||||
skip = new TestSkipOverlay(skip_time)
|
||||
{
|
||||
RequestSkip = () =>
|
||||
{
|
||||
@ -56,19 +56,19 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
public void TestFadeOnIdle()
|
||||
{
|
||||
AddStep("move mouse", () => InputManager.MoveMouseTo(Vector2.Zero));
|
||||
AddUntilStep("fully visible", () => skip.Children.First().Alpha == 1);
|
||||
AddUntilStep("wait for fade", () => skip.Children.First().Alpha < 1);
|
||||
AddUntilStep("fully visible", () => skip.FadingContent.Alpha == 1);
|
||||
AddUntilStep("wait for fade", () => skip.FadingContent.Alpha < 1);
|
||||
|
||||
AddStep("move mouse", () => InputManager.MoveMouseTo(skip.ScreenSpaceDrawQuad.Centre));
|
||||
AddUntilStep("fully visible", () => skip.Children.First().Alpha == 1);
|
||||
AddUntilStep("wait for fade", () => skip.Children.First().Alpha < 1);
|
||||
AddUntilStep("fully visible", () => skip.FadingContent.Alpha == 1);
|
||||
AddUntilStep("wait for fade", () => skip.FadingContent.Alpha < 1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestClickableAfterFade()
|
||||
{
|
||||
AddStep("move mouse", () => InputManager.MoveMouseTo(skip.ScreenSpaceDrawQuad.Centre));
|
||||
AddUntilStep("wait for fade", () => skip.Children.First().Alpha == 0);
|
||||
AddUntilStep("wait for fade", () => skip.FadingContent.Alpha == 0);
|
||||
AddStep("click", () => InputManager.Click(MouseButton.Left));
|
||||
checkRequestCount(1);
|
||||
}
|
||||
@ -105,13 +105,25 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
AddStep("move mouse", () => InputManager.MoveMouseTo(skip.ScreenSpaceDrawQuad.Centre));
|
||||
AddStep("button down", () => InputManager.PressButton(MouseButton.Left));
|
||||
AddUntilStep("wait for overlay disappear", () => !skip.IsPresent);
|
||||
AddAssert("ensure button didn't disappear", () => skip.Children.First().Alpha > 0);
|
||||
AddUntilStep("wait for overlay disappear", () => !skip.OverlayContent.IsPresent);
|
||||
AddAssert("ensure button didn't disappear", () => skip.FadingContent.Alpha > 0);
|
||||
AddStep("button up", () => InputManager.ReleaseButton(MouseButton.Left));
|
||||
checkRequestCount(0);
|
||||
}
|
||||
|
||||
private void checkRequestCount(int expected) =>
|
||||
AddAssert($"request count is {expected}", () => requestCount == expected);
|
||||
|
||||
private class TestSkipOverlay : SkipOverlay
|
||||
{
|
||||
public TestSkipOverlay(double startTime)
|
||||
: base(startTime)
|
||||
{
|
||||
}
|
||||
|
||||
public Drawable OverlayContent => InternalChild;
|
||||
|
||||
public Drawable FadingContent => (OverlayContent as Container)?.Child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
@ -20,11 +19,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[TestFixture]
|
||||
public class TestSceneSongProgress : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(SongProgressBar),
|
||||
};
|
||||
|
||||
private SongProgress progress;
|
||||
private TestSongProgressGraph graph;
|
||||
private readonly Container progressContainer;
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
@ -18,13 +16,6 @@ namespace osu.Game.Tests.Visual.Menus
|
||||
[TestFixture]
|
||||
public abstract class IntroTestScene : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(StartupScreen),
|
||||
typeof(IntroScreen),
|
||||
typeof(IntroTestScene),
|
||||
};
|
||||
|
||||
[Cached]
|
||||
private OsuLogo logo;
|
||||
|
||||
|
@ -1,44 +1,76 @@
|
||||
// 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.Allocation;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Overlays.Toolbar;
|
||||
using osu.Game.Rulesets;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Menus
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneToolbar : OsuTestScene
|
||||
public class TestSceneToolbar : OsuManualInputManagerTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(ToolbarButton),
|
||||
typeof(ToolbarRulesetSelector),
|
||||
typeof(ToolbarRulesetTabButton),
|
||||
typeof(ToolbarNotificationButton),
|
||||
};
|
||||
private Toolbar toolbar;
|
||||
|
||||
public TestSceneToolbar()
|
||||
[Resolved]
|
||||
private RulesetStore rulesets { get; set; }
|
||||
|
||||
[SetUp]
|
||||
public void SetUp() => Schedule(() =>
|
||||
{
|
||||
Child = toolbar = new Toolbar { State = { Value = Visibility.Visible } };
|
||||
});
|
||||
|
||||
[Test]
|
||||
public void TestNotificationCounter()
|
||||
{
|
||||
var toolbar = new Toolbar { State = { Value = Visibility.Visible } };
|
||||
ToolbarNotificationButton notificationButton = null;
|
||||
|
||||
AddStep("create toolbar", () =>
|
||||
{
|
||||
Add(toolbar);
|
||||
notificationButton = toolbar.Children.OfType<FillFlowContainer>().Last().Children.OfType<ToolbarNotificationButton>().First();
|
||||
});
|
||||
|
||||
void setNotifications(int count) => AddStep($"set notification count to {count}", () => notificationButton.NotificationCount.Value = count);
|
||||
AddStep("retrieve notification button", () => notificationButton = toolbar.ChildrenOfType<ToolbarNotificationButton>().Single());
|
||||
|
||||
setNotifications(1);
|
||||
setNotifications(2);
|
||||
setNotifications(3);
|
||||
setNotifications(0);
|
||||
setNotifications(144);
|
||||
|
||||
void setNotifications(int count)
|
||||
=> AddStep($"set notification count to {count}",
|
||||
() => notificationButton.NotificationCount.Value = count);
|
||||
}
|
||||
|
||||
[TestCase(false)]
|
||||
[TestCase(true)]
|
||||
public void TestRulesetSwitchingShortcut(bool toolbarHidden)
|
||||
{
|
||||
ToolbarRulesetSelector rulesetSelector = null;
|
||||
|
||||
if (toolbarHidden)
|
||||
AddStep("hide toolbar", () => toolbar.Hide());
|
||||
|
||||
AddStep("retrieve ruleset selector", () => rulesetSelector = toolbar.ChildrenOfType<ToolbarRulesetSelector>().Single());
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
var expected = rulesets.AvailableRulesets.ElementAt(i);
|
||||
var numberKey = Key.Number1 + i;
|
||||
|
||||
AddStep($"switch to ruleset {i} via shortcut", () =>
|
||||
{
|
||||
InputManager.PressKey(Key.ControlLeft);
|
||||
InputManager.PressKey(numberKey);
|
||||
|
||||
InputManager.ReleaseKey(Key.ControlLeft);
|
||||
InputManager.ReleaseKey(numberKey);
|
||||
});
|
||||
|
||||
AddUntilStep("ruleset switched", () => rulesetSelector.Current.Value.Equals(expected));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,21 @@
|
||||
// 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.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Screens.Multi;
|
||||
@ -22,14 +27,20 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public class TestSceneDrawableRoomPlaylist : OsuManualInputManagerTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(DrawableRoomPlaylist),
|
||||
typeof(DrawableRoomPlaylistItem)
|
||||
};
|
||||
|
||||
private TestPlaylist playlist;
|
||||
|
||||
private BeatmapManager manager;
|
||||
private RulesetStore rulesets;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(GameHost host, AudioManager audio)
|
||||
{
|
||||
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
||||
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, host, Beatmap.Default));
|
||||
|
||||
manager.Import(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo.BeatmapSet).Wait();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestNonEditableNonSelectable()
|
||||
{
|
||||
@ -189,6 +200,28 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddStep("click delete button", () => InputManager.Click(MouseButton.Left));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDownloadButtonHiddenInitiallyWhenBeatmapExists()
|
||||
{
|
||||
createPlaylist(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo);
|
||||
|
||||
AddAssert("download button hidden", () => !playlist.ChildrenOfType<BeatmapDownloadTrackingComposite>().Single().IsPresent);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDownloadButtonVisibleInitiallyWhenBeatmapDoesNotExist()
|
||||
{
|
||||
var byOnlineId = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo;
|
||||
byOnlineId.BeatmapSet.OnlineBeatmapSetID = 1337; // Some random ID that does not exist locally.
|
||||
|
||||
var byChecksum = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo;
|
||||
byChecksum.MD5Hash = "1337"; // Some random checksum that does not exist locally.
|
||||
|
||||
createPlaylist(byOnlineId, byChecksum);
|
||||
|
||||
AddAssert("download buttons shown", () => playlist.ChildrenOfType<BeatmapDownloadTrackingComposite>().All(d => d.IsPresent));
|
||||
}
|
||||
|
||||
private void moveToItem(int index, Vector2? offset = null)
|
||||
=> AddStep($"move mouse to item {index}", () => InputManager.MoveMouseTo(playlist.ChildrenOfType<OsuRearrangeableListItem<PlaylistItem>>().ElementAt(index), offset));
|
||||
|
||||
@ -242,6 +275,39 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddUntilStep("wait for items to load", () => playlist.ItemMap.Values.All(i => i.IsLoaded));
|
||||
}
|
||||
|
||||
private void createPlaylist(params BeatmapInfo[] beatmaps)
|
||||
{
|
||||
AddStep("create playlist", () =>
|
||||
{
|
||||
Child = playlist = new TestPlaylist(false, false)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(500, 300)
|
||||
};
|
||||
|
||||
int index = 0;
|
||||
|
||||
foreach (var b in beatmaps)
|
||||
{
|
||||
playlist.Items.Add(new PlaylistItem
|
||||
{
|
||||
ID = index++,
|
||||
Beatmap = { Value = b },
|
||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||
RequiredMods =
|
||||
{
|
||||
new OsuModHardRock(),
|
||||
new OsuModDoubleTime(),
|
||||
new OsuModAutoplay()
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
AddUntilStep("wait for items to load", () => playlist.ItemMap.Values.All(i => i.IsLoaded));
|
||||
}
|
||||
|
||||
private class TestPlaylist : DrawableRoomPlaylist
|
||||
{
|
||||
public new IReadOnlyDictionary<PlaylistItem, RearrangeableListItem<PlaylistItem>> ItemMap => base.ItemMap;
|
||||
|
@ -2,7 +2,6 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
@ -14,11 +13,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public class TestSceneLoungeRoomInfo : MultiplayerTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(RoomInfo)
|
||||
};
|
||||
|
||||
[SetUp]
|
||||
public void Setup() => Schedule(() =>
|
||||
{
|
||||
|
@ -2,7 +2,6 @@
|
||||
// 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.Allocation;
|
||||
@ -23,12 +22,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public class TestSceneLoungeRoomsContainer : MultiplayerTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(RoomsContainer),
|
||||
typeof(DrawableRoom)
|
||||
};
|
||||
|
||||
[Cached(Type = typeof(IRoomManager))]
|
||||
private TestRoomManager roomManager = new TestRoomManager();
|
||||
|
||||
@ -148,6 +141,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
}
|
||||
|
||||
public readonly BindableList<Room> Rooms = new BindableList<Room>();
|
||||
|
||||
public Bindable<bool> InitialRoomsReceived { get; } = new Bindable<bool>(true);
|
||||
|
||||
IBindableList<Room> IRoomManager.Rooms => Rooms;
|
||||
|
||||
public void CreateRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null) => Rooms.Add(room);
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
@ -14,11 +12,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public class TestSceneMatchHeader : MultiplayerTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(Header)
|
||||
};
|
||||
|
||||
public TestSceneMatchHeader()
|
||||
{
|
||||
Room.Playlist.Add(new PlaylistItem
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Screens.Multi.Match.Components;
|
||||
@ -12,11 +10,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public class TestSceneMatchLeaderboardChatDisplay : MultiplayerTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(LeaderboardChatDisplay)
|
||||
};
|
||||
|
||||
protected override bool UseOnlineAPI => true;
|
||||
|
||||
public TestSceneMatchLeaderboardChatDisplay()
|
||||
|
@ -2,7 +2,6 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
@ -18,11 +17,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public class TestSceneMatchSettingsOverlay : MultiplayerTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(MatchSettingsOverlay)
|
||||
};
|
||||
|
||||
[Cached(Type = typeof(IRoomManager))]
|
||||
private TestRoomManager roomManager = new TestRoomManager();
|
||||
|
||||
@ -75,6 +69,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
settings.NameField.Current.Value = expected_name;
|
||||
settings.DurationField.Current.Value = expectedDuration;
|
||||
Room.Playlist.Add(new PlaylistItem { Beatmap = { Value = CreateBeatmap(Ruleset.Value).BeatmapInfo } });
|
||||
|
||||
roomManager.CreateRequested = r =>
|
||||
{
|
||||
@ -95,6 +90,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
|
||||
AddStep("setup", () =>
|
||||
{
|
||||
Room.Name.Value = "Test Room";
|
||||
Room.Playlist.Add(new PlaylistItem { Beatmap = { Value = CreateBeatmap(Ruleset.Value).BeatmapInfo } });
|
||||
|
||||
fail = true;
|
||||
roomManager.CreateRequested = _ => !fail;
|
||||
});
|
||||
@ -135,6 +133,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
remove { }
|
||||
}
|
||||
|
||||
public Bindable<bool> InitialRoomsReceived { get; } = new Bindable<bool>(true);
|
||||
|
||||
public IBindableList<Room> Rooms { get; } = null;
|
||||
|
||||
public void CreateRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null)
|
||||
|
@ -23,12 +23,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public class TestSceneMatchSongSelect : MultiplayerTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(MatchSongSelect),
|
||||
typeof(MatchBeatmapDetailArea),
|
||||
};
|
||||
|
||||
[Resolved]
|
||||
private BeatmapManager beatmapManager { get; set; }
|
||||
|
||||
|
@ -2,11 +2,12 @@
|
||||
// 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.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
@ -20,7 +21,6 @@ using osu.Game.Screens.Multi.Match.Components;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osu.Game.Users;
|
||||
using osuTK.Input;
|
||||
using Header = osu.Game.Screens.Multi.Match.Components.Header;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
@ -28,25 +28,23 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
protected override bool UseOnlineAPI => true;
|
||||
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(Screens.Multi.Multiplayer),
|
||||
typeof(MatchSubScreen),
|
||||
typeof(Header),
|
||||
typeof(Footer)
|
||||
};
|
||||
|
||||
[Cached(typeof(IRoomManager))]
|
||||
private readonly TestRoomManager roomManager = new TestRoomManager();
|
||||
|
||||
[Resolved]
|
||||
private BeatmapManager beatmaps { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private RulesetStore rulesets { get; set; }
|
||||
private BeatmapManager manager;
|
||||
private RulesetStore rulesets;
|
||||
|
||||
private TestMatchSubScreen match;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(GameHost host, AudioManager audio)
|
||||
{
|
||||
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
||||
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, host, Beatmap.Default));
|
||||
|
||||
manager.Import(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo.BeatmapSet).Wait();
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void Setup() => Schedule(() =>
|
||||
{
|
||||
@ -85,10 +83,49 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddAssert("first playlist item selected", () => match.SelectedItem.Value == Room.Playlist[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBeatmapUpdatedOnReImport()
|
||||
{
|
||||
BeatmapSetInfo importedSet = null;
|
||||
|
||||
AddStep("import altered beatmap", () =>
|
||||
{
|
||||
var beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo);
|
||||
beatmap.BeatmapInfo.BaseDifficulty.CircleSize = 1;
|
||||
|
||||
importedSet = manager.Import(beatmap.BeatmapInfo.BeatmapSet).Result;
|
||||
});
|
||||
|
||||
AddStep("load room", () =>
|
||||
{
|
||||
Room.Name.Value = "my awesome room";
|
||||
Room.Host.Value = new User { Id = 2, Username = "peppy" };
|
||||
Room.Playlist.Add(new PlaylistItem
|
||||
{
|
||||
Beatmap = { Value = importedSet.Beatmaps[0] },
|
||||
Ruleset = { Value = new OsuRuleset().RulesetInfo }
|
||||
});
|
||||
});
|
||||
|
||||
AddStep("create room", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(match.ChildrenOfType<MatchSettingsOverlay.CreateRoomButton>().Single());
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
AddAssert("match has altered beatmap", () => match.Beatmap.Value.Beatmap.BeatmapInfo.BaseDifficulty.CircleSize == 1);
|
||||
|
||||
AddStep("re-import original beatmap", () => manager.Import(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo.BeatmapSet).Wait());
|
||||
|
||||
AddAssert("match has original beatmap", () => match.Beatmap.Value.Beatmap.BeatmapInfo.BaseDifficulty.CircleSize != 1);
|
||||
}
|
||||
|
||||
private class TestMatchSubScreen : MatchSubScreen
|
||||
{
|
||||
public new Bindable<PlaylistItem> SelectedItem => base.SelectedItem;
|
||||
|
||||
public new Bindable<WorkingBeatmap> Beatmap => base.Beatmap;
|
||||
|
||||
public TestMatchSubScreen(Room room)
|
||||
: base(room)
|
||||
{
|
||||
@ -103,6 +140,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
remove => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Bindable<bool> InitialRoomsReceived { get; } = new Bindable<bool>(true);
|
||||
|
||||
public IBindableList<Room> Rooms { get; } = new BindableList<Room>();
|
||||
|
||||
public void CreateRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null)
|
||||
|
@ -1,11 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Screens.Multi.Lounge;
|
||||
using osu.Game.Screens.Multi.Lounge.Components;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
@ -14,13 +10,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
protected override bool UseOnlineAPI => true;
|
||||
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(Screens.Multi.Multiplayer),
|
||||
typeof(LoungeSubScreen),
|
||||
typeof(FilterControl)
|
||||
};
|
||||
|
||||
public TestSceneMultiScreen()
|
||||
{
|
||||
Screens.Multi.Multiplayer multi = new Screens.Multi.Multiplayer();
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Screens.Multi.Components;
|
||||
@ -12,13 +10,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public class TestSceneOverlinedParticipants : MultiplayerTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(OverlinedParticipants),
|
||||
typeof(OverlinedDisplay),
|
||||
typeof(ParticipantsList)
|
||||
};
|
||||
|
||||
protected override bool UseOnlineAPI => true;
|
||||
|
||||
public TestSceneOverlinedParticipants()
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
@ -13,13 +11,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public class TestSceneRoomStatus : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(RoomStatusEnded),
|
||||
typeof(RoomStatusOpen),
|
||||
typeof(RoomStatusPlaying)
|
||||
};
|
||||
|
||||
public TestSceneRoomStatus()
|
||||
{
|
||||
Child = new FillFlowContainer
|
||||
|
@ -0,0 +1,124 @@
|
||||
// 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.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Multi.Ranking;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Multiplayer
|
||||
{
|
||||
public class TestSceneTimeshiftResultsScreen : ScreenTestScene
|
||||
{
|
||||
private bool roomsReceived;
|
||||
|
||||
[SetUp]
|
||||
public void Setup() => Schedule(() =>
|
||||
{
|
||||
roomsReceived = false;
|
||||
bindHandler();
|
||||
});
|
||||
|
||||
[Test]
|
||||
public void TestShowResultsWithScore()
|
||||
{
|
||||
createResults(new TestScoreInfo(new OsuRuleset().RulesetInfo));
|
||||
AddWaitStep("wait for display", 5);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestShowResultsNullScore()
|
||||
{
|
||||
createResults(null);
|
||||
AddWaitStep("wait for display", 5);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestShowResultsNullScoreWithDelay()
|
||||
{
|
||||
AddStep("bind delayed handler", () => bindHandler(3000));
|
||||
createResults(null);
|
||||
AddUntilStep("wait for rooms to be received", () => roomsReceived);
|
||||
AddWaitStep("wait for display", 5);
|
||||
}
|
||||
|
||||
private void createResults(ScoreInfo score)
|
||||
{
|
||||
AddStep("load results", () =>
|
||||
{
|
||||
LoadScreen(new TimeshiftResultsScreen(score, 1, new PlaylistItem
|
||||
{
|
||||
Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo },
|
||||
Ruleset = { Value = new OsuRuleset().RulesetInfo }
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
private void bindHandler(double delay = 0)
|
||||
{
|
||||
var roomScores = new List<RoomScore>();
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
roomScores.Add(new RoomScore
|
||||
{
|
||||
ID = i,
|
||||
Accuracy = 0.9 - 0.01 * i,
|
||||
EndedAt = DateTimeOffset.Now.Subtract(TimeSpan.FromHours(i)),
|
||||
Passed = true,
|
||||
Rank = ScoreRank.B,
|
||||
MaxCombo = 999,
|
||||
TotalScore = 999999 - i * 1000,
|
||||
User = new User
|
||||
{
|
||||
Id = 2,
|
||||
Username = $"peppy{i}",
|
||||
CoverUrl = "https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
|
||||
},
|
||||
Statistics =
|
||||
{
|
||||
{ HitResult.Miss, 1 },
|
||||
{ HitResult.Meh, 50 },
|
||||
{ HitResult.Good, 100 },
|
||||
{ HitResult.Great, 300 },
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
((DummyAPIAccess)API).HandleRequest = request =>
|
||||
{
|
||||
switch (request)
|
||||
{
|
||||
case GetRoomPlaylistScoresRequest r:
|
||||
if (delay == 0)
|
||||
success();
|
||||
else
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromMilliseconds(delay));
|
||||
Schedule(success);
|
||||
});
|
||||
}
|
||||
|
||||
void success()
|
||||
{
|
||||
r.TriggerSuccess(new RoomPlaylistScores { Scores = roomScores });
|
||||
roomsReceived = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -20,26 +20,30 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
public void TestFromMainMenu()
|
||||
{
|
||||
var firstImport = importBeatmap(1);
|
||||
var secondimport = importBeatmap(3);
|
||||
|
||||
presentAndConfirm(firstImport);
|
||||
|
||||
AddStep("return to menu", () => Game.ScreenStack.CurrentScreen.Exit());
|
||||
AddUntilStep("wait for menu", () => Game.ScreenStack.CurrentScreen is MainMenu);
|
||||
|
||||
var secondimport = importBeatmap(2);
|
||||
returnToMenu();
|
||||
presentAndConfirm(secondimport);
|
||||
returnToMenu();
|
||||
presentSecondDifficultyAndConfirm(firstImport, 1);
|
||||
returnToMenu();
|
||||
presentSecondDifficultyAndConfirm(secondimport, 3);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFromMainMenuDifferentRuleset()
|
||||
{
|
||||
var firstImport = importBeatmap(1);
|
||||
var secondimport = importBeatmap(3, new ManiaRuleset().RulesetInfo);
|
||||
|
||||
presentAndConfirm(firstImport);
|
||||
|
||||
AddStep("return to menu", () => Game.ScreenStack.CurrentScreen.Exit());
|
||||
AddUntilStep("wait for menu", () => Game.ScreenStack.CurrentScreen is MainMenu);
|
||||
|
||||
var secondimport = importBeatmap(2, new ManiaRuleset().RulesetInfo);
|
||||
returnToMenu();
|
||||
presentAndConfirm(secondimport);
|
||||
returnToMenu();
|
||||
presentSecondDifficultyAndConfirm(firstImport, 1);
|
||||
returnToMenu();
|
||||
presentSecondDifficultyAndConfirm(secondimport, 3);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -48,8 +52,11 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
var firstImport = importBeatmap(1);
|
||||
presentAndConfirm(firstImport);
|
||||
|
||||
var secondimport = importBeatmap(2);
|
||||
var secondimport = importBeatmap(3);
|
||||
presentAndConfirm(secondimport);
|
||||
|
||||
presentSecondDifficultyAndConfirm(firstImport, 1);
|
||||
presentSecondDifficultyAndConfirm(secondimport, 3);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -58,8 +65,17 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
var firstImport = importBeatmap(1);
|
||||
presentAndConfirm(firstImport);
|
||||
|
||||
var secondimport = importBeatmap(2, new ManiaRuleset().RulesetInfo);
|
||||
var secondimport = importBeatmap(3, new ManiaRuleset().RulesetInfo);
|
||||
presentAndConfirm(secondimport);
|
||||
|
||||
presentSecondDifficultyAndConfirm(firstImport, 1);
|
||||
presentSecondDifficultyAndConfirm(secondimport, 3);
|
||||
}
|
||||
|
||||
private void returnToMenu()
|
||||
{
|
||||
AddStep("return to menu", () => Game.ScreenStack.CurrentScreen.Exit());
|
||||
AddUntilStep("wait for menu", () => Game.ScreenStack.CurrentScreen is MainMenu);
|
||||
}
|
||||
|
||||
private Func<BeatmapSetInfo> importBeatmap(int i, RulesetInfo ruleset = null)
|
||||
@ -89,6 +105,13 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
BaseDifficulty = difficulty,
|
||||
Ruleset = ruleset ?? new OsuRuleset().RulesetInfo
|
||||
},
|
||||
new BeatmapInfo
|
||||
{
|
||||
OnlineBeatmapID = i * 2048,
|
||||
Metadata = metadata,
|
||||
BaseDifficulty = difficulty,
|
||||
Ruleset = ruleset ?? new OsuRuleset().RulesetInfo
|
||||
},
|
||||
}
|
||||
}).Result;
|
||||
});
|
||||
@ -106,5 +129,15 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
AddUntilStep("correct beatmap displayed", () => Game.Beatmap.Value.BeatmapSetInfo.ID == getImport().ID);
|
||||
AddAssert("correct ruleset selected", () => Game.Ruleset.Value.ID == getImport().Beatmaps.First().Ruleset.ID);
|
||||
}
|
||||
|
||||
private void presentSecondDifficultyAndConfirm(Func<BeatmapSetInfo> getImport, int importedID)
|
||||
{
|
||||
Predicate<BeatmapInfo> pred = b => b.OnlineBeatmapID == importedID * 2048;
|
||||
AddStep("present difficulty", () => Game.PresentBeatmap(getImport(), pred));
|
||||
|
||||
AddUntilStep("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect);
|
||||
AddUntilStep("correct beatmap displayed", () => Game.Beatmap.Value.BeatmapInfo.OnlineBeatmapID == importedID * 2048);
|
||||
AddAssert("correct ruleset selected", () => Game.Ruleset.Value.ID == getImport().Beatmaps.First().Ruleset.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,17 @@
|
||||
// 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 osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.AccountCreation;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Online
|
||||
{
|
||||
public class TestSceneAccountCreationOverlay : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(ErrorTextFlowContainer),
|
||||
typeof(AccountCreationBackground),
|
||||
typeof(ScreenEntry),
|
||||
typeof(ScreenWarning),
|
||||
typeof(ScreenWelcome),
|
||||
typeof(AccountCreationScreen),
|
||||
};
|
||||
|
||||
private readonly Container userPanelArea;
|
||||
|
||||
private Bindable<User> localUser;
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Overlays;
|
||||
using NUnit.Framework;
|
||||
|
||||
@ -10,11 +8,6 @@ namespace osu.Game.Tests.Visual.Online
|
||||
{
|
||||
public class TestSceneBeatmapListingOverlay : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(BeatmapListingOverlay),
|
||||
};
|
||||
|
||||
protected override bool UseOnlineAPI => true;
|
||||
|
||||
private readonly BeatmapListingOverlay overlay;
|
||||
|
@ -8,7 +8,6 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.BeatmapSet;
|
||||
using osu.Game.Rulesets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@ -16,12 +15,6 @@ namespace osu.Game.Tests.Visual.Online
|
||||
{
|
||||
public class TestSceneBeatmapRulesetSelector : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(BeatmapRulesetSelector),
|
||||
typeof(BeatmapRulesetTabItem),
|
||||
};
|
||||
|
||||
[Cached]
|
||||
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
|
||||
|
||||
|
@ -6,8 +6,6 @@ using osu.Framework.Allocation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.BeatmapSet;
|
||||
using osu.Game.Overlays.BeatmapSet.Buttons;
|
||||
using osu.Game.Overlays.BeatmapSet.Scores;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Users;
|
||||
using System;
|
||||
@ -21,30 +19,6 @@ namespace osu.Game.Tests.Visual.Online
|
||||
{
|
||||
private readonly TestBeatmapSetOverlay overlay;
|
||||
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(Header),
|
||||
typeof(ScoreTable),
|
||||
typeof(ScoreTableRowBackground),
|
||||
typeof(DrawableTopScore),
|
||||
typeof(ScoresContainer),
|
||||
typeof(AuthorInfo),
|
||||
typeof(BasicStats),
|
||||
typeof(BeatmapPicker),
|
||||
typeof(Details),
|
||||
typeof(HeaderDownloadButton),
|
||||
typeof(FavouriteButton),
|
||||
typeof(Header),
|
||||
typeof(HeaderButton),
|
||||
typeof(Info),
|
||||
typeof(PreviewButton),
|
||||
typeof(SuccessRate),
|
||||
typeof(BeatmapAvailability),
|
||||
typeof(BeatmapRulesetSelector),
|
||||
typeof(BeatmapRulesetTabItem),
|
||||
typeof(NotSupporterPlaceholder)
|
||||
};
|
||||
|
||||
protected override bool UseOnlineAPI => true;
|
||||
|
||||
public TestSceneBeatmapSetOverlay()
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
@ -17,11 +16,6 @@ namespace osu.Game.Tests.Visual.Online
|
||||
{
|
||||
public class TestSceneBeatmapSetOverlayDetails : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(Details)
|
||||
};
|
||||
|
||||
private RatingsExposingDetails details;
|
||||
|
||||
[Cached]
|
||||
|
@ -1,8 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
@ -21,11 +19,6 @@ namespace osu.Game.Tests.Visual.Online
|
||||
{
|
||||
public class TestSceneBeatmapSetOverlaySuccessRate : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(Details)
|
||||
};
|
||||
|
||||
private GraphExposingSuccessRate successRate;
|
||||
|
||||
[Cached]
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user