83 lines
6.7 KiB
C#
83 lines
6.7 KiB
C#
using System.Linq;
|
|
using MagnetismHeroes.Core;
|
|
using NUnit.Framework;
|
|
|
|
namespace MagnetismHeroes.Tests
|
|
{
|
|
public sealed class CompositionSessionTests
|
|
{
|
|
private sealed class SpyStore : IProgressStore
|
|
{
|
|
public ProgressSave Saved = new ProgressSave { completedStageIds = Enumerable.Range(1, 13).ToArray() };
|
|
public int Writes;
|
|
public bool TryLoad(out ProgressSave save, out string error) { save = Saved; error = null; return true; }
|
|
public bool TrySave(ProgressSave save, out string error) { Saved = save; Writes++; error = null; return true; }
|
|
}
|
|
[Test] public void MoveAndMergeCompleteWithOneWriteAndPreserveEveryIdentity()
|
|
{
|
|
var store = new SpyStore { Saved = new ProgressSave { completedStageIds = Enumerable.Range(1, 5).ToArray() } };
|
|
var session = new GameSession(new[] { new StageDefinition(6, StageKind.Composition, new[] { 1, 1 }, new[] { 2 }) }, store);
|
|
session.StartStage(6); var groups = session.Board.Groups; var ids = session.Board.Balls.Select(ball => ball.id).ToArray();
|
|
var writes = store.Writes;
|
|
var result = session.MoveAndMerge(groups[0].id, new Position3(0.4f, 0.2f, 1), groups[1].id);
|
|
Assert.That(result.Accepted, Is.True); Assert.That(store.Writes, Is.EqualTo(writes + 1));
|
|
Assert.That(session.Screen, Is.EqualTo(SessionScreen.FreePlay));
|
|
Assert.That(session.Board.Groups.Single().ballIds, Is.EquivalentTo(ids));
|
|
Assert.That(store.Saved.puzzleStates, Is.Empty); Assert.That(store.Saved.latestFreePlay, Is.Not.Null);
|
|
Assert.That(store.Saved.completedStageIds, Is.EqualTo(Enumerable.Range(1, 6).ToArray()));
|
|
}
|
|
[Test] public void UnknownMergeTargetDoesNotMoveOrWrite()
|
|
{
|
|
var store = new SpyStore(); var session = new GameSession(new[] { new StageDefinition(6, StageKind.Composition, new[] { 1, 1 }, new[] { 2 }) }, store);
|
|
session.StartStage(6); var original = session.Board.Balls; var writes = store.Writes;
|
|
Assert.That(session.MoveAndMerge(session.Board.Groups[0].id, new Position3(1, 0, 0), "missing").Accepted, Is.False);
|
|
Assert.That(session.Board.Balls.Select(ball => ball.position), Is.EqualTo(original.Select(ball => ball.position)));
|
|
Assert.That(store.Writes, Is.EqualTo(writes));
|
|
}
|
|
[TestCase(0)] [TestCase(3)] public void EmptyAndEntireSplitKeepStateAndSave(int count)
|
|
{
|
|
var store = new SpyStore(); var session = new GameSession(new[] { new StageDefinition(14, StageKind.Composition, new[] { 3, 1 }, new[] { 2, 2 }) }, store);
|
|
session.StartStage(14); var group = session.Board.Groups[0]; var writes = store.Writes; var original = session.Board.Balls;
|
|
Assert.That(session.SplitAndMove(group.id, group.ballIds.Take(count).ToArray(), "new", new Position3(1, 1, 0)).Accepted, Is.False);
|
|
Assert.That(store.Writes, Is.EqualTo(writes)); Assert.That(session.Board.Groups.Length, Is.EqualTo(2));
|
|
Assert.That(session.Board.Balls.Select(ball => ball.position), Is.EqualTo(original.Select(ball => ball.position)));
|
|
}
|
|
[Test] public void DistantSelectionProducesExactlyTwoFriendsAndFinalCompositionIgnoresHistory()
|
|
{
|
|
var store = new SpyStore(); var session = new GameSession(new[] { new StageDefinition(14, StageKind.Composition, new[] { 3, 1 }, new[] { 2, 2 }) }, store);
|
|
session.StartStage(14); var groups = session.Board.Groups;
|
|
session.MoveAndMerge(groups[0].id, new Position3(0.1f, 0, 0), groups[1].id);
|
|
var all = session.Board.Groups.Single(); var ids = all.ballIds.ToArray(); var writes = store.Writes;
|
|
Assert.That(session.SplitAndMove(all.id, new[] { ids[0], ids[3] }, "split-result", new Position3(3, 0, 0)).Accepted, Is.True);
|
|
Assert.That(store.Writes, Is.EqualTo(writes + 1)); Assert.That(session.Screen, Is.EqualTo(SessionScreen.FreePlay));
|
|
Assert.That(session.Board.Groups.Select(group => group.ballIds.Length), Is.EqualTo(new[] { 2, 2 }));
|
|
Assert.That(session.Board.Groups.SelectMany(group => group.ballIds), Is.EquivalentTo(ids));
|
|
}
|
|
[Test] public void SplitAndMergeKeepCollectedAndCountedIdsThroughPuzzleRestore()
|
|
{
|
|
var definition = new StageDefinition(1, StageKind.Counting, new[] { 1, 1, 1 }, new[] { 3 });
|
|
var store = new SpyStore(); var session = new GameSession(new[] { definition }, store); session.StartStage(1);
|
|
var groups = session.Board.Groups; var ids = session.Board.Balls.Select(ball => ball.id).ToArray();
|
|
foreach (var group in groups) session.MoveGroup(group.id, new Position3(0, 1, 0));
|
|
session.Merge(groups[0].id, groups[1].id); session.Merge(groups[0].id, groups[2].id); session.Count(ids[0]);
|
|
var writes = store.Writes;
|
|
Assert.That(session.SplitAndMove(groups[0].id, new[] { ids[0], ids[2] }, "detached", new Position3(2, 0, 0)).Accepted, Is.True);
|
|
Assert.That(store.Writes, Is.EqualTo(writes + 1)); Assert.That(session.Board.CountedBallIds, Is.EqualTo(new[] { ids[0] }));
|
|
var restored = new GameSession(new[] { definition }, store); restored.StartStage(1);
|
|
Assert.That(restored.Board.CollectedBallIds, Is.EquivalentTo(ids)); Assert.That(restored.Board.CountedBallIds, Is.EqualTo(new[] { ids[0] }));
|
|
Assert.That(restored.Board.Groups.Length, Is.EqualTo(2));
|
|
Assert.That(restored.MoveAndMerge("detached", new Position3(-1, 0, 0), groups[0].id).Accepted, Is.True);
|
|
Assert.That(restored.Board.CountedBallIds, Is.EqualTo(new[] { ids[0] })); Assert.That(restored.Board.BallCount, Is.EqualTo(3));
|
|
}
|
|
[Test] public void InvalidCoordinatesNeverPartiallySplitOrMerge()
|
|
{
|
|
var store = new SpyStore(); var session = new GameSession(new[] { new StageDefinition(14, StageKind.Composition, new[] { 3, 1 }, new[] { 2, 2 }) }, store);
|
|
session.StartStage(14); var groups = session.Board.Groups; var original = session.Board.Balls; var writes = store.Writes;
|
|
Assert.That(session.MoveAndMerge(groups[0].id, new Position3(float.NaN, 0, 0), groups[1].id).Accepted, Is.False);
|
|
Assert.That(session.SplitAndMove(groups[0].id, new[] { groups[0].ballIds[0] }, "invalid", new Position3(float.PositiveInfinity, 0, 0)).Accepted, Is.False);
|
|
Assert.That(store.Writes, Is.EqualTo(writes)); Assert.That(session.Board.Groups.Select(group => group.ballIds.Length), Is.EqualTo(new[] { 3, 1 }));
|
|
Assert.That(session.Board.Balls.Select(ball => ball.position), Is.EqualTo(original.Select(ball => ball.position)));
|
|
}
|
|
}
|
|
}
|