316 lines
12 KiB
C#
316 lines
12 KiB
C#
|
|
using NUnit.Framework;
|
|||
|
|
using UnityEngine;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
|
|||
|
|
namespace Tests.EditMode
|
|||
|
|
{
|
|||
|
|
public class PuzzleGraphUtilityTests
|
|||
|
|
{
|
|||
|
|
private PuzzleStepSO step1;
|
|||
|
|
private PuzzleStepSO step2;
|
|||
|
|
private PuzzleStepSO step3;
|
|||
|
|
private PuzzleStepSO step4;
|
|||
|
|
private PuzzleStepSO step5;
|
|||
|
|
|
|||
|
|
[SetUp]
|
|||
|
|
public void SetUp()
|
|||
|
|
{
|
|||
|
|
// Create test PuzzleStepSO instances using ScriptableObject.CreateInstance
|
|||
|
|
step1 = ScriptableObject.CreateInstance<PuzzleStepSO>();
|
|||
|
|
step1.stepId = "step1";
|
|||
|
|
step1.displayName = "Step 1";
|
|||
|
|
step1.unlocks = new List<PuzzleStepSO>();
|
|||
|
|
|
|||
|
|
step2 = ScriptableObject.CreateInstance<PuzzleStepSO>();
|
|||
|
|
step2.stepId = "step2";
|
|||
|
|
step2.displayName = "Step 2";
|
|||
|
|
step2.unlocks = new List<PuzzleStepSO>();
|
|||
|
|
|
|||
|
|
step3 = ScriptableObject.CreateInstance<PuzzleStepSO>();
|
|||
|
|
step3.stepId = "step3";
|
|||
|
|
step3.displayName = "Step 3";
|
|||
|
|
step3.unlocks = new List<PuzzleStepSO>();
|
|||
|
|
|
|||
|
|
step4 = ScriptableObject.CreateInstance<PuzzleStepSO>();
|
|||
|
|
step4.stepId = "step4";
|
|||
|
|
step4.displayName = "Step 4";
|
|||
|
|
step4.unlocks = new List<PuzzleStepSO>();
|
|||
|
|
|
|||
|
|
step5 = ScriptableObject.CreateInstance<PuzzleStepSO>();
|
|||
|
|
step5.stepId = "step5";
|
|||
|
|
step5.displayName = "Step 5";
|
|||
|
|
step5.unlocks = new List<PuzzleStepSO>();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[TearDown]
|
|||
|
|
public void TearDown()
|
|||
|
|
{
|
|||
|
|
// Clean up created ScriptableObjects
|
|||
|
|
if (step1 != null) Object.DestroyImmediate(step1);
|
|||
|
|
if (step2 != null) Object.DestroyImmediate(step2);
|
|||
|
|
if (step3 != null) Object.DestroyImmediate(step3);
|
|||
|
|
if (step4 != null) Object.DestroyImmediate(step4);
|
|||
|
|
if (step5 != null) Object.DestroyImmediate(step5);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#region BuildDependencyGraph Tests
|
|||
|
|
|
|||
|
|
[Test]
|
|||
|
|
public void BuildDependencyGraph_EmptyList_ReturnsEmptyDictionary()
|
|||
|
|
{
|
|||
|
|
// Arrange
|
|||
|
|
var steps = new List<PuzzleStepSO>();
|
|||
|
|
|
|||
|
|
// Act
|
|||
|
|
var graph = PuzzleGraphUtility.BuildDependencyGraph(steps);
|
|||
|
|
|
|||
|
|
// Assert
|
|||
|
|
Assert.IsNotNull(graph, "Graph should not be null");
|
|||
|
|
Assert.AreEqual(0, graph.Count, "Graph should be empty");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[Test]
|
|||
|
|
public void BuildDependencyGraph_NoUnlocks_ReturnsGraphWithEmptyDependencyLists()
|
|||
|
|
{
|
|||
|
|
// Arrange
|
|||
|
|
var steps = new List<PuzzleStepSO> { step1, step2, step3 };
|
|||
|
|
// No unlocks set up
|
|||
|
|
|
|||
|
|
// Act
|
|||
|
|
var graph = PuzzleGraphUtility.BuildDependencyGraph(steps);
|
|||
|
|
|
|||
|
|
// Assert
|
|||
|
|
Assert.AreEqual(3, graph.Count, "Graph should have 3 entries");
|
|||
|
|
Assert.IsTrue(graph.ContainsKey(step1), "Graph should contain step1");
|
|||
|
|
Assert.IsTrue(graph.ContainsKey(step2), "Graph should contain step2");
|
|||
|
|
Assert.IsTrue(graph.ContainsKey(step3), "Graph should contain step3");
|
|||
|
|
Assert.AreEqual(0, graph[step1].Count, "step1 should have no dependencies");
|
|||
|
|
Assert.AreEqual(0, graph[step2].Count, "step2 should have no dependencies");
|
|||
|
|
Assert.AreEqual(0, graph[step3].Count, "step3 should have no dependencies");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[Test]
|
|||
|
|
public void BuildDependencyGraph_WithUnlocks_BuildsCorrectDependencyGraph()
|
|||
|
|
{
|
|||
|
|
// Arrange
|
|||
|
|
// Set up unlock relationships:
|
|||
|
|
// step1 unlocks step3 and step4
|
|||
|
|
// step2 unlocks step3
|
|||
|
|
// step3 unlocks step5
|
|||
|
|
// step4 has no unlocks
|
|||
|
|
// step5 has no unlocks
|
|||
|
|
step1.unlocks.Add(step3);
|
|||
|
|
step1.unlocks.Add(step4);
|
|||
|
|
step2.unlocks.Add(step3);
|
|||
|
|
step3.unlocks.Add(step5);
|
|||
|
|
|
|||
|
|
var steps = new List<PuzzleStepSO> { step1, step2, step3, step4, step5 };
|
|||
|
|
|
|||
|
|
// Act
|
|||
|
|
var graph = PuzzleGraphUtility.BuildDependencyGraph(steps);
|
|||
|
|
|
|||
|
|
// Assert
|
|||
|
|
Assert.AreEqual(5, graph.Count, "Graph should have 5 entries");
|
|||
|
|
|
|||
|
|
// Check dependencies (reverse of unlocks)
|
|||
|
|
Assert.AreEqual(0, graph[step1].Count, "step1 should have no dependencies");
|
|||
|
|
Assert.AreEqual(0, graph[step2].Count, "step2 should have no dependencies");
|
|||
|
|
|
|||
|
|
Assert.AreEqual(2, graph[step3].Count, "step3 should have 2 dependencies");
|
|||
|
|
Assert.IsTrue(graph[step3].Contains(step1), "step3 should depend on step1");
|
|||
|
|
Assert.IsTrue(graph[step3].Contains(step2), "step3 should depend on step2");
|
|||
|
|
|
|||
|
|
Assert.AreEqual(1, graph[step4].Count, "step4 should have 1 dependency");
|
|||
|
|
Assert.IsTrue(graph[step4].Contains(step1), "step4 should depend on step1");
|
|||
|
|
|
|||
|
|
Assert.AreEqual(1, graph[step5].Count, "step5 should have 1 dependency");
|
|||
|
|
Assert.IsTrue(graph[step5].Contains(step3), "step5 should depend on step3");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[Test]
|
|||
|
|
public void BuildDependencyGraph_WithCyclicUnlocks_BuildsCorrectDependencyGraph()
|
|||
|
|
{
|
|||
|
|
// Arrange
|
|||
|
|
// Set up cyclic unlock relationships:
|
|||
|
|
// step1 unlocks step2
|
|||
|
|
// step2 unlocks step3
|
|||
|
|
// step3 unlocks step1
|
|||
|
|
step1.unlocks.Add(step2);
|
|||
|
|
step2.unlocks.Add(step3);
|
|||
|
|
step3.unlocks.Add(step1);
|
|||
|
|
|
|||
|
|
var steps = new List<PuzzleStepSO> { step1, step2, step3 };
|
|||
|
|
|
|||
|
|
// Act
|
|||
|
|
var graph = PuzzleGraphUtility.BuildDependencyGraph(steps);
|
|||
|
|
|
|||
|
|
// Assert
|
|||
|
|
Assert.AreEqual(3, graph.Count, "Graph should have 3 entries");
|
|||
|
|
|
|||
|
|
// Check dependencies (reverse of unlocks)
|
|||
|
|
Assert.AreEqual(1, graph[step1].Count, "step1 should have 1 dependency");
|
|||
|
|
Assert.IsTrue(graph[step1].Contains(step3), "step1 should depend on step3");
|
|||
|
|
|
|||
|
|
Assert.AreEqual(1, graph[step2].Count, "step2 should have 1 dependency");
|
|||
|
|
Assert.IsTrue(graph[step2].Contains(step1), "step2 should depend on step1");
|
|||
|
|
|
|||
|
|
Assert.AreEqual(1, graph[step3].Count, "step3 should have 1 dependency");
|
|||
|
|
Assert.IsTrue(graph[step3].Contains(step2), "step3 should depend on step2");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region FindInitialSteps Tests
|
|||
|
|
|
|||
|
|
[Test]
|
|||
|
|
public void FindInitialSteps_EmptyGraph_ReturnsEmptyList()
|
|||
|
|
{
|
|||
|
|
// Arrange
|
|||
|
|
var graph = new Dictionary<PuzzleStepSO, List<PuzzleStepSO>>();
|
|||
|
|
|
|||
|
|
// Act
|
|||
|
|
var initialSteps = PuzzleGraphUtility.FindInitialSteps(graph);
|
|||
|
|
|
|||
|
|
// Assert
|
|||
|
|
Assert.IsNotNull(initialSteps, "Initial steps should not be null");
|
|||
|
|
Assert.AreEqual(0, initialSteps.Count, "Initial steps should be empty");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[Test]
|
|||
|
|
public void FindInitialSteps_AllInitial_ReturnsAllSteps()
|
|||
|
|
{
|
|||
|
|
// Arrange
|
|||
|
|
var graph = new Dictionary<PuzzleStepSO, List<PuzzleStepSO>>
|
|||
|
|
{
|
|||
|
|
{ step1, new List<PuzzleStepSO>() },
|
|||
|
|
{ step2, new List<PuzzleStepSO>() },
|
|||
|
|
{ step3, new List<PuzzleStepSO>() }
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// Act
|
|||
|
|
var initialSteps = PuzzleGraphUtility.FindInitialSteps(graph);
|
|||
|
|
|
|||
|
|
// Assert
|
|||
|
|
Assert.AreEqual(3, initialSteps.Count, "All steps should be initial");
|
|||
|
|
Assert.IsTrue(initialSteps.Contains(step1), "Initial steps should contain step1");
|
|||
|
|
Assert.IsTrue(initialSteps.Contains(step2), "Initial steps should contain step2");
|
|||
|
|
Assert.IsTrue(initialSteps.Contains(step3), "Initial steps should contain step3");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[Test]
|
|||
|
|
public void FindInitialSteps_SomeInitial_ReturnsOnlyInitialSteps()
|
|||
|
|
{
|
|||
|
|
// Arrange
|
|||
|
|
// Create a graph where step1 and step2 are initial, but step3 depends on step1
|
|||
|
|
var graph = new Dictionary<PuzzleStepSO, List<PuzzleStepSO>>
|
|||
|
|
{
|
|||
|
|
{ step1, new List<PuzzleStepSO>() },
|
|||
|
|
{ step2, new List<PuzzleStepSO>() },
|
|||
|
|
{ step3, new List<PuzzleStepSO> { step1 } }
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// Act
|
|||
|
|
var initialSteps = PuzzleGraphUtility.FindInitialSteps(graph);
|
|||
|
|
|
|||
|
|
// Assert
|
|||
|
|
Assert.AreEqual(2, initialSteps.Count, "There should be 2 initial steps");
|
|||
|
|
Assert.IsTrue(initialSteps.Contains(step1), "Initial steps should contain step1");
|
|||
|
|
Assert.IsTrue(initialSteps.Contains(step2), "Initial steps should contain step2");
|
|||
|
|
Assert.IsFalse(initialSteps.Contains(step3), "Initial steps should not contain step3");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[Test]
|
|||
|
|
public void FindInitialSteps_NoInitial_ReturnsEmptyList()
|
|||
|
|
{
|
|||
|
|
// Arrange
|
|||
|
|
// Create a cyclic dependency graph with no initial steps
|
|||
|
|
var graph = new Dictionary<PuzzleStepSO, List<PuzzleStepSO>>
|
|||
|
|
{
|
|||
|
|
{ step1, new List<PuzzleStepSO> { step3 } },
|
|||
|
|
{ step2, new List<PuzzleStepSO> { step1 } },
|
|||
|
|
{ step3, new List<PuzzleStepSO> { step2 } }
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// Act
|
|||
|
|
var initialSteps = PuzzleGraphUtility.FindInitialSteps(graph);
|
|||
|
|
|
|||
|
|
// Assert
|
|||
|
|
Assert.AreEqual(0, initialSteps.Count, "There should be no initial steps");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region FindUnlocks Tests
|
|||
|
|
|
|||
|
|
[Test]
|
|||
|
|
public void FindUnlocks_EmptyList_ReturnsEmptyList()
|
|||
|
|
{
|
|||
|
|
// Arrange
|
|||
|
|
var allSteps = new List<PuzzleStepSO>();
|
|||
|
|
|
|||
|
|
// Act
|
|||
|
|
var unlocks = PuzzleGraphUtility.FindUnlocks(step1, allSteps);
|
|||
|
|
|
|||
|
|
// Assert
|
|||
|
|
Assert.IsNotNull(unlocks, "Unlocks should not be null");
|
|||
|
|
Assert.AreEqual(0, unlocks.Count, "Unlocks should be empty");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[Test]
|
|||
|
|
public void FindUnlocks_NoUnlocks_ReturnsEmptyList()
|
|||
|
|
{
|
|||
|
|
// Arrange
|
|||
|
|
var allSteps = new List<PuzzleStepSO> { step1, step2, step3 };
|
|||
|
|
// No unlocks set up
|
|||
|
|
|
|||
|
|
// Act
|
|||
|
|
var unlocks = PuzzleGraphUtility.FindUnlocks(step1, allSteps);
|
|||
|
|
|
|||
|
|
// Assert
|
|||
|
|
Assert.AreEqual(0, unlocks.Count, "No steps should unlock step1");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[Test]
|
|||
|
|
public void FindUnlocks_WithUnlocks_ReturnsCorrectUnlocks()
|
|||
|
|
{
|
|||
|
|
// Arrange
|
|||
|
|
// Set up unlock relationships:
|
|||
|
|
// step1 unlocks step3
|
|||
|
|
// step2 unlocks step3
|
|||
|
|
step1.unlocks.Add(step3);
|
|||
|
|
step2.unlocks.Add(step3);
|
|||
|
|
|
|||
|
|
var allSteps = new List<PuzzleStepSO> { step1, step2, step3 };
|
|||
|
|
|
|||
|
|
// Act
|
|||
|
|
var unlocks = PuzzleGraphUtility.FindUnlocks(step3, allSteps);
|
|||
|
|
|
|||
|
|
// Assert
|
|||
|
|
Assert.AreEqual(2, unlocks.Count, "2 steps should unlock step3");
|
|||
|
|
Assert.IsTrue(unlocks.Contains(step1), "step1 should unlock step3");
|
|||
|
|
Assert.IsTrue(unlocks.Contains(step2), "step2 should unlock step3");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[Test]
|
|||
|
|
public void FindUnlocks_StepUnlocksItself_ReturnsCorrectUnlocks()
|
|||
|
|
{
|
|||
|
|
// Arrange
|
|||
|
|
// Set up self-unlock relationship:
|
|||
|
|
// step1 unlocks itself and step2
|
|||
|
|
step1.unlocks.Add(step1);
|
|||
|
|
step1.unlocks.Add(step2);
|
|||
|
|
|
|||
|
|
var allSteps = new List<PuzzleStepSO> { step1, step2 };
|
|||
|
|
|
|||
|
|
// Act
|
|||
|
|
var unlocks = PuzzleGraphUtility.FindUnlocks(step1, allSteps);
|
|||
|
|
|
|||
|
|
// Assert
|
|||
|
|
Assert.AreEqual(1, unlocks.Count, "1 step should unlock step1");
|
|||
|
|
Assert.IsTrue(unlocks.Contains(step1), "step1 should unlock itself");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
}
|
|||
|
|
}
|