// Copyright (c) ppy Pty Ltd . 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.Text; using System.Threading; using NUnit.Framework; using osu.Framework.Extensions; using osu.Framework.IO.Stores; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; namespace osu.Game.Tests.Resources { public static class TestResources { public const double QUICK_BEATMAP_LENGTH = 10000; private static readonly TemporaryNativeStorage temp_storage = new TemporaryNativeStorage("TestResources"); public static DllResourceStore GetStore() => new DllResourceStore(typeof(TestResources).Assembly); public static Stream OpenResource(string name) => GetStore().GetStream($"Resources/{name}"); public static Stream GetTestBeatmapStream(bool virtualTrack = false) => OpenResource($"Archives/241526 Soleily - Renatus{(virtualTrack ? "_virtual" : "")}.osz"); /// /// Retrieve a path to a copy of a shortened (~10 second) beatmap archive with a virtual track. /// /// /// This is intended for use in tests which need to run to completion as soon as possible and don't need to test a full length beatmap. /// A path to a copy of a beatmap archive (osz). Should be deleted after use. public static string GetQuickTestBeatmapForImport() { string tempPath = getTempFilename(); using (var stream = OpenResource("Archives/241526 Soleily - Renatus_virtual_quick.osz")) using (var newFile = File.Create(tempPath)) stream.CopyTo(newFile); Assert.IsTrue(File.Exists(tempPath)); return tempPath; } /// /// Retrieve a path to a copy of a full-fledged beatmap archive. /// /// Whether the audio track should be virtual. /// A path to a copy of a beatmap archive (osz). Should be deleted after use. public static string GetTestBeatmapForImport(bool virtualTrack = false) { string tempPath = getTempFilename(); using (var stream = GetTestBeatmapStream(virtualTrack)) using (var newFile = File.Create(tempPath)) stream.CopyTo(newFile); Assert.IsTrue(File.Exists(tempPath)); return tempPath; } private static string getTempFilename() => temp_storage.GetFullPath(Guid.NewGuid() + ".osz"); private static int importId; /// /// Create a test beatmap set model. /// /// Number of difficulties. If null, a random number between 1 and 20 will be used. /// Rulesets to cycle through when creating difficulties. If null, osu! ruleset will be used. public static BeatmapSetInfo CreateTestBeatmapSetInfo(int? difficultyCount = null, RulesetInfo[] rulesets = null) { int j = 0; RulesetInfo getRuleset() => rulesets?[j++ % rulesets.Length] ?? new OsuRuleset().RulesetInfo; int setId = Interlocked.Increment(ref importId); var metadata = new BeatmapMetadata { // Create random metadata, then we can check if sorting works based on these Artist = "Some Artist " + RNG.Next(0, 9), Title = $"Some Song (set id {setId}) {Guid.NewGuid()}", AuthorString = "Some Guy " + RNG.Next(0, 9), }; var beatmapSet = new BeatmapSetInfo { OnlineID = setId, Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), DateAdded = DateTimeOffset.UtcNow, Metadata = metadata }; foreach (var b in getBeatmaps(difficultyCount ?? RNG.Next(1, 20))) beatmapSet.Beatmaps.Add(b); return beatmapSet; IEnumerable getBeatmaps(int count) { for (int i = 0; i < count; i++) { int beatmapId = setId * 1000 + i; int length = RNG.Next(30000, 200000); double bpm = RNG.NextSingle(80, 200); float diff = (float)i / count * 10; string version = "Normal"; if (diff > 6.6) version = "Insane"; else if (diff > 3.3) version = "Hard"; var rulesetInfo = getRuleset(); yield return new BeatmapInfo { OnlineID = beatmapId, DifficultyName = $"{version} {beatmapId} (length {TimeSpan.FromMilliseconds(length):m\\:ss}, bpm {bpm:0.#})", StarRating = diff, Length = length, BPM = bpm, Ruleset = rulesetInfo, RulesetID = rulesetInfo.ID ?? -1, Metadata = metadata, BaseDifficulty = new BeatmapDifficulty { OverallDifficulty = diff, } }; } } } } }