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 { 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.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 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_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 FixedRunNodeSequenceBuilder_Builds_Plain_Ten_Node_Sequence() { IReadOnlyList 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 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.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)); } } }