geometry-tower-defense/Assets/Tests/EditMode/RunStateTests.cs

289 lines
13 KiB
C#

using System.Collections.Generic;
using GeometryTD.CustomEvent;
using GeometryTD.Definition;
using GeometryTD.Procedure;
using NUnit.Framework;
namespace GeometryTD.Tests.EditMode
{
public sealed class RunStateTests
{
[Test]
public void Factory_Creates_RunState_With_First_Node_Available()
{
BackpackInventoryData sourceInventory = new BackpackInventoryData
{
Gold = 120
};
sourceInventory.ParticipantTowerInstanceIds.Add(11);
RunState runState = RunStateFactory.Create(
LevelThemeType.Plain,
sourceInventory,
new List<RunNodeSeed>
{
new RunNodeSeed { NodeType = RunNodeType.Combat, LinkedLevelId = 1 },
new RunNodeSeed { NodeType = RunNodeType.Event },
new RunNodeSeed { NodeType = RunNodeType.BossCombat, LinkedLevelId = 4 }
},
"run-test");
Assert.That(runState.RunId, Is.EqualTo("run-test"));
Assert.That(runState.RunSeed, Is.Not.EqualTo(0));
Assert.That(runState.ThemeType, Is.EqualTo(LevelThemeType.Plain));
Assert.That(runState.CurrentNodeIndex, Is.EqualTo(0));
Assert.That(runState.IsCompleted, Is.False);
Assert.That(runState.Nodes.Count, Is.EqualTo(3));
Assert.That(runState.Nodes[0].Status, Is.EqualTo(RunNodeStatus.Available));
Assert.That(runState.Nodes[1].Status, Is.EqualTo(RunNodeStatus.Locked));
Assert.That(runState.RunInventorySnapshot.Gold, Is.EqualTo(120));
sourceInventory.Gold = 1;
sourceInventory.ParticipantTowerInstanceIds[0] = 99;
Assert.That(runState.RunInventorySnapshot.Gold, Is.EqualTo(120));
Assert.That(runState.RunInventorySnapshot.ParticipantTowerInstanceIds[0], Is.EqualTo(11));
}
[Test]
public void AdvanceService_Completes_Run_And_Unlocks_Next_Node()
{
RunState runState = RunStateFactory.Create(
LevelThemeType.Plain,
new BackpackInventoryData { Gold = 50 },
new[]
{
new RunNodeSeed { NodeId = 101, NodeType = RunNodeType.Combat, LinkedLevelId = 1 },
new RunNodeSeed { NodeId = 102, NodeType = RunNodeType.Shop },
new RunNodeSeed { NodeId = 103, NodeType = RunNodeType.BossCombat, LinkedLevelId = 4 }
});
bool firstCompleted = RunStateAdvanceService.TryCompleteCurrentNode(
runState,
RunNodeCompletionStatus.Completed,
new BackpackInventoryData { Gold = 80 });
Assert.That(firstCompleted, Is.True);
Assert.That(runState.Nodes[0].Status, Is.EqualTo(RunNodeStatus.Completed));
Assert.That(runState.CurrentNodeIndex, Is.EqualTo(1));
Assert.That(runState.Nodes[1].Status, Is.EqualTo(RunNodeStatus.Available));
Assert.That(runState.RunInventorySnapshot.Gold, Is.EqualTo(80));
RunStateAdvanceService.TryCompleteCurrentNode(
runState,
RunNodeCompletionStatus.Completed,
new BackpackInventoryData { Gold = 95 });
RunStateAdvanceService.TryCompleteCurrentNode(
runState,
RunNodeCompletionStatus.Completed,
new BackpackInventoryData { Gold = 130 });
Assert.That(runState.IsCompleted, Is.True);
Assert.That(runState.CurrentNodeIndex, Is.EqualTo(3));
Assert.That(runState.CompletedNodeCount, Is.EqualTo(3));
Assert.That(runState.RunInventorySnapshot.Gold, Is.EqualTo(130));
}
[Test]
public void Factory_Preserves_Explicit_RunSeed_And_Generates_NonZero_Default_RunSeed()
{
RunState explicitSeedRun = RunStateFactory.Create(
LevelThemeType.Plain,
new BackpackInventoryData(),
new[]
{
new RunNodeSeed { NodeType = RunNodeType.Combat, LinkedLevelId = 1 }
},
"run-explicit",
123456);
RunState generatedSeedRun = RunStateFactory.Create(
LevelThemeType.Plain,
new BackpackInventoryData(),
new[]
{
new RunNodeSeed { NodeType = RunNodeType.Combat, LinkedLevelId = 1 }
},
"run-generated");
Assert.That(explicitSeedRun.RunSeed, Is.EqualTo(123456));
Assert.That(generatedSeedRun.RunSeed, Is.Not.EqualTo(0));
}
[Test]
public void AdvanceService_Exception_Marks_Current_Node_Exception_Without_Completing_Run()
{
RunState runState = RunStateFactory.Create(
LevelThemeType.Plain,
new BackpackInventoryData { Gold = 20 },
new[]
{
new RunNodeSeed { NodeType = RunNodeType.Combat }
});
bool result = RunStateAdvanceService.TryCompleteCurrentNode(
runState,
RunNodeCompletionStatus.Exception,
new BackpackInventoryData { Gold = 5 });
Assert.That(result, Is.True);
Assert.That(runState.IsCompleted, Is.False);
Assert.That(runState.CurrentNodeIndex, Is.EqualTo(0));
Assert.That(runState.CurrentNode.Status, Is.EqualTo(RunNodeStatus.Exception));
Assert.That(runState.RunInventorySnapshot.Gold, Is.EqualTo(5));
}
[Test]
public void NodeCompleteEventArgs_Completed_Win_Clones_Inventory_And_Clears_State()
{
BackpackInventoryData inventory = new BackpackInventoryData { Gold = 66 };
NodeCompleteEventArgs eventArgs = NodeCompleteEventArgs.Create(
"run-1",
7,
RunNodeType.Shop,
3,
RunNodeCompletionStatus.Completed,
true,
inventory);
inventory.Gold = 1;
Assert.That(eventArgs.RunId, Is.EqualTo("run-1"));
Assert.That(eventArgs.NodeId, Is.EqualTo(7));
Assert.That(eventArgs.NodeType, Is.EqualTo(RunNodeType.Shop));
Assert.That(eventArgs.SequenceIndex, Is.EqualTo(3));
Assert.That(eventArgs.CompletionStatus, Is.EqualTo(RunNodeCompletionStatus.Completed));
Assert.That(eventArgs.CombatWon, Is.True);
Assert.That(eventArgs.InventorySnapshotAfterNode.Gold, Is.EqualTo(66));
eventArgs.Clear();
Assert.That(eventArgs.RunId, Is.Null);
Assert.That(eventArgs.NodeId, Is.EqualTo(0));
Assert.That(eventArgs.NodeType, Is.EqualTo(RunNodeType.None));
Assert.That(eventArgs.SequenceIndex, Is.EqualTo(-1));
Assert.That(eventArgs.CompletionStatus, Is.EqualTo(RunNodeCompletionStatus.None));
Assert.That(eventArgs.CombatWon, Is.False);
Assert.That(eventArgs.InventorySnapshotAfterNode, Is.Null);
}
[Test]
public void NodeCompleteEventArgs_Completed_Loss_Preserves_NonWin_Semantics()
{
BackpackInventoryData inventory = new BackpackInventoryData { Gold = 12 };
NodeCompleteEventArgs eventArgs = NodeCompleteEventArgs.Create(
"run-2",
8,
RunNodeType.Combat,
4,
RunNodeCompletionStatus.Completed,
false,
inventory);
inventory.Gold = 99;
Assert.That(eventArgs.RunId, Is.EqualTo("run-2"));
Assert.That(eventArgs.NodeId, Is.EqualTo(8));
Assert.That(eventArgs.NodeType, Is.EqualTo(RunNodeType.Combat));
Assert.That(eventArgs.SequenceIndex, Is.EqualTo(4));
Assert.That(eventArgs.CompletionStatus, Is.EqualTo(RunNodeCompletionStatus.Completed));
Assert.That(eventArgs.CombatWon, Is.False);
Assert.That(eventArgs.InventorySnapshotAfterNode.Gold, Is.EqualTo(12));
}
[Test]
public void NodeCompleteEventArgs_Exception_Preserves_Exception_Semantics()
{
BackpackInventoryData inventory = new BackpackInventoryData { Gold = 7 };
NodeCompleteEventArgs eventArgs = NodeCompleteEventArgs.Create(
"run-3",
9,
RunNodeType.BossCombat,
5,
RunNodeCompletionStatus.Exception,
false,
inventory);
inventory.Gold = 100;
Assert.That(eventArgs.RunId, Is.EqualTo("run-3"));
Assert.That(eventArgs.NodeId, Is.EqualTo(9));
Assert.That(eventArgs.NodeType, Is.EqualTo(RunNodeType.BossCombat));
Assert.That(eventArgs.SequenceIndex, Is.EqualTo(5));
Assert.That(eventArgs.CompletionStatus, Is.EqualTo(RunNodeCompletionStatus.Exception));
Assert.That(eventArgs.CombatWon, Is.False);
Assert.That(eventArgs.InventorySnapshotAfterNode.Gold, Is.EqualTo(7));
}
[Test]
public void FixedRunNodeSequenceBuilder_Builds_Plain_Ten_Node_Sequence()
{
IReadOnlyList<RunNodeSeed> nodeSeeds = FixedRunNodeSequenceBuilder.Build(LevelThemeType.Plain);
Assert.That(nodeSeeds, Is.Not.Null);
Assert.That(nodeSeeds.Count, Is.EqualTo(10));
Assert.That(nodeSeeds[0].NodeType, Is.EqualTo(RunNodeType.Combat));
Assert.That(nodeSeeds[1].NodeType, Is.EqualTo(RunNodeType.Event));
Assert.That(nodeSeeds[2].NodeType, Is.EqualTo(RunNodeType.Combat));
Assert.That(nodeSeeds[3].NodeType, Is.EqualTo(RunNodeType.Shop));
Assert.That(nodeSeeds[4].NodeType, Is.EqualTo(RunNodeType.Combat));
Assert.That(nodeSeeds[5].NodeType, Is.EqualTo(RunNodeType.Event));
Assert.That(nodeSeeds[6].NodeType, Is.EqualTo(RunNodeType.Combat));
Assert.That(nodeSeeds[7].NodeType, Is.EqualTo(RunNodeType.Shop));
Assert.That(nodeSeeds[8].NodeType, Is.EqualTo(RunNodeType.Event));
Assert.That(nodeSeeds[9].NodeType, Is.EqualTo(RunNodeType.BossCombat));
Assert.That(nodeSeeds[0].LinkedLevelId, Is.EqualTo(1));
Assert.That(nodeSeeds[2].LinkedLevelId, Is.EqualTo(2));
Assert.That(nodeSeeds[4].LinkedLevelId, Is.EqualTo(3));
Assert.That(nodeSeeds[6].LinkedLevelId, Is.EqualTo(1));
Assert.That(nodeSeeds[9].LinkedLevelId, Is.EqualTo(4));
Assert.That(nodeSeeds[1].LinkedLevelId, Is.EqualTo(0));
Assert.That(nodeSeeds[3].LinkedLevelId, Is.EqualTo(0));
}
[Test]
public void FixedRunNodeSequenceBuilder_Returns_Empty_For_Unsupported_Theme()
{
IReadOnlyList<RunNodeSeed> nodeSeeds = FixedRunNodeSequenceBuilder.Build(LevelThemeType.Volcano);
Assert.That(nodeSeeds, Is.Not.Null);
Assert.That(nodeSeeds.Count, Is.EqualTo(0));
}
[Test]
public void CreateFixedRun_Creates_Ten_Node_Run_And_Completes_After_Ten_Advances()
{
RunState runState = RunStateFactory.CreateFixedRun(
LevelThemeType.Plain,
new BackpackInventoryData { Gold = 100 },
"fixed-run");
Assert.That(runState.RunId, Is.EqualTo("fixed-run"));
Assert.That(runState.RunSeed, Is.Not.EqualTo(0));
Assert.That(runState.NodeCount, Is.EqualTo(10));
Assert.That(runState.CurrentNodeIndex, Is.EqualTo(0));
Assert.That(runState.CurrentNode.NodeType, Is.EqualTo(RunNodeType.Combat));
Assert.That(runState.Nodes[0].Status, Is.EqualTo(RunNodeStatus.Available));
Assert.That(runState.Nodes[9].Status, Is.EqualTo(RunNodeStatus.Locked));
Assert.That(runState.GetNodeBySequenceIndex(9), Is.Not.Null);
Assert.That(RunState.IsBossNode(runState.GetNodeBySequenceIndex(9)), Is.True);
for (int i = 0; i < runState.NodeCount; i++)
{
bool advanced = RunStateAdvanceService.TryCompleteCurrentNode(
runState,
RunNodeCompletionStatus.Completed,
new BackpackInventoryData { Gold = 100 + i });
Assert.That(advanced, Is.True);
}
Assert.That(runState.IsCompleted, Is.True);
Assert.That(runState.CompletedNodeCount, Is.EqualTo(10));
Assert.That(runState.CurrentNodeIndex, Is.EqualTo(10));
Assert.That(runState.RunInventorySnapshot.Gold, Is.EqualTo(109));
}
}
}