osu/osu.Game.Tests/Editing/BeatmapEditorChangeHandlerT...

227 lines
6.8 KiB
C#

// 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.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Beatmaps;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Screens.Edit;
namespace osu.Game.Tests.Editing
{
[TestFixture]
public class BeatmapEditorChangeHandlerTest
{
private int stateChangedFired;
[SetUp]
public void SetUp()
{
stateChangedFired = 0;
}
[Test]
public void TestSaveRestoreStateUsingTransaction()
{
var (handler, beatmap) = createChangeHandler();
Assert.That(handler.CanUndo.Value, Is.False);
Assert.That(handler.CanRedo.Value, Is.False);
handler.BeginChange();
// Initial state will be saved on BeginChange
Assert.That(stateChangedFired, Is.EqualTo(1));
addArbitraryChange(beatmap);
handler.EndChange();
Assert.That(stateChangedFired, Is.EqualTo(2));
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);
Assert.That(stateChangedFired, Is.EqualTo(3));
}
[Test]
public void TestSaveRestoreState()
{
var (handler, beatmap) = createChangeHandler();
Assert.That(handler.CanUndo.Value, Is.False);
Assert.That(handler.CanRedo.Value, Is.False);
// Save initial state
handler.SaveState();
Assert.That(stateChangedFired, Is.EqualTo(1));
addArbitraryChange(beatmap);
handler.SaveState();
Assert.That(stateChangedFired, Is.EqualTo(2));
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);
Assert.That(stateChangedFired, Is.EqualTo(3));
}
[Test]
public void TestApplyThenUndoThenApplySameChange()
{
var (handler, beatmap) = createChangeHandler();
Assert.That(handler.CanUndo.Value, Is.False);
Assert.That(handler.CanRedo.Value, Is.False);
// Save initial state
handler.SaveState();
Assert.That(stateChangedFired, Is.EqualTo(1));
string originalHash = handler.CurrentStateHash;
addArbitraryChange(beatmap);
handler.SaveState();
Assert.That(handler.CanUndo.Value, Is.True);
Assert.That(handler.CanRedo.Value, Is.False);
Assert.That(stateChangedFired, Is.EqualTo(2));
string hash = handler.CurrentStateHash;
// undo a change without saving
handler.RestoreState(-1);
Assert.That(originalHash, Is.EqualTo(handler.CurrentStateHash));
Assert.That(stateChangedFired, Is.EqualTo(3));
addArbitraryChange(beatmap);
handler.SaveState();
Assert.That(hash, Is.EqualTo(handler.CurrentStateHash));
}
[Test]
public void TestSaveSameStateDoesNotSave()
{
var (handler, beatmap) = createChangeHandler();
Assert.That(handler.CanUndo.Value, Is.False);
Assert.That(handler.CanRedo.Value, Is.False);
// Save initial state
handler.SaveState();
Assert.That(stateChangedFired, Is.EqualTo(1));
addArbitraryChange(beatmap);
handler.SaveState();
Assert.That(handler.CanUndo.Value, Is.True);
Assert.That(handler.CanRedo.Value, Is.False);
Assert.That(stateChangedFired, Is.EqualTo(2));
string hash = handler.CurrentStateHash;
// save a save without making any changes
handler.SaveState();
Assert.That(hash, Is.EqualTo(handler.CurrentStateHash));
Assert.That(stateChangedFired, Is.EqualTo(2));
handler.RestoreState(-1);
Assert.That(hash, Is.Not.EqualTo(handler.CurrentStateHash));
// we should only be able to restore once even though we saved twice.
Assert.That(handler.CanUndo.Value, Is.False);
Assert.That(handler.CanRedo.Value, Is.True);
Assert.That(stateChangedFired, Is.EqualTo(3));
}
[Test]
public void TestMaxStatesSaved()
{
var (handler, beatmap) = createChangeHandler();
// Save initial state
handler.SaveState();
Assert.That(stateChangedFired, Is.EqualTo(1));
Assert.That(handler.CanUndo.Value, Is.False);
for (int i = 0; i < EditorChangeHandler.MAX_SAVED_STATES; i++)
{
Assert.That(stateChangedFired, Is.EqualTo(i + 1));
addArbitraryChange(beatmap);
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, beatmap) = createChangeHandler();
Assert.That(handler.CanUndo.Value, Is.False);
for (int i = 0; i < EditorChangeHandler.MAX_SAVED_STATES * 2; i++)
{
addArbitraryChange(beatmap);
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);
}
private (EditorChangeHandler, EditorBeatmap) createChangeHandler()
{
var beatmap = new EditorBeatmap(new OsuBeatmap
{
BeatmapInfo =
{
Ruleset = new OsuRuleset().RulesetInfo,
},
});
var changeHandler = new BeatmapEditorChangeHandler(beatmap);
changeHandler.OnStateChange += () => stateChangedFired++;
return (changeHandler, beatmap);
}
private void addArbitraryChange(EditorBeatmap beatmap)
{
beatmap.Add(new HitCircle { StartTime = 2760 });
}
}
}