Merge pull request 'Introduce unit and integration tests' (#3) from integration_test into main
Reviewed-on: #3
This commit is contained in:
3
Assets/External/Pixelplacement/PixelplacementAssembly.asmdef
vendored
Normal file
3
Assets/External/Pixelplacement/PixelplacementAssembly.asmdef
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"name": "PixelplacementAssembly"
|
||||
}
|
||||
7
Assets/External/Pixelplacement/PixelplacementAssembly.asmdef.meta
vendored
Normal file
7
Assets/External/Pixelplacement/PixelplacementAssembly.asmdef.meta
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db4a9769b2b9c5a4788bcd189eea1f0b
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/External/Pixelplacement/Surge/Editor/PixelplacementEditor.asmdef
vendored
Normal file
18
Assets/External/Pixelplacement/Surge/Editor/PixelplacementEditor.asmdef
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "PixelplacementEditor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:db4a9769b2b9c5a4788bcd189eea1f0b"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
7
Assets/External/Pixelplacement/Surge/Editor/PixelplacementEditor.asmdef.meta
vendored
Normal file
7
Assets/External/Pixelplacement/Surge/Editor/PixelplacementEditor.asmdef.meta
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0547315a6b16c1a48bf1db2b83869a5a
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 274948d5adb104b28a8d42ee1308cee0
|
||||
folderAsset: yes
|
||||
timeCreated: 1500598980
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f588a5a76c3094128955cddb5540e896
|
||||
folderAsset: yes
|
||||
timeCreated: 1500598980
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
21
Assets/Scripts/AppleHillsScripts.asmdef
Normal file
21
Assets/Scripts/AppleHillsScripts.asmdef
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "AppleHillsScripts",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"PixelplacementAssembly",
|
||||
"Unity.Addressables",
|
||||
"AstarPathfindingProject",
|
||||
"Unity.ResourceManager",
|
||||
"Unity.InputSystem",
|
||||
"Unity.TextMeshPro"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
7
Assets/Scripts/AppleHillsScripts.asmdef.meta
Normal file
7
Assets/Scripts/AppleHillsScripts.asmdef.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d91d3f46515a6954caa674697afbf416
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -35,6 +35,14 @@ public class GameManager : MonoBehaviour
|
||||
void Awake()
|
||||
{
|
||||
_instance = this;
|
||||
if (gameSettings == null)
|
||||
{
|
||||
gameSettings = Resources.Load<GameSettings>("DefaultSettings");
|
||||
if (gameSettings == null)
|
||||
{
|
||||
Debug.LogError("GameSettings asset not found in Resources!");
|
||||
}
|
||||
}
|
||||
// DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
|
||||
@@ -69,7 +77,8 @@ public class GameManager : MonoBehaviour
|
||||
if (gameSettings == null || gameSettings.combinationRules == null) return null;
|
||||
foreach (var rule in gameSettings.combinationRules)
|
||||
{
|
||||
if ((rule.itemA == item1 && rule.itemB == item2) || (rule.itemA == item2 && rule.itemB == item1))
|
||||
if ((PickupItemData.AreEquivalent(rule.itemA, item1) && PickupItemData.AreEquivalent(rule.itemB, item2)) ||
|
||||
(PickupItemData.AreEquivalent(rule.itemA, item2) && PickupItemData.AreEquivalent(rule.itemB, item1)))
|
||||
{
|
||||
return rule;
|
||||
}
|
||||
@@ -85,7 +94,7 @@ public class GameManager : MonoBehaviour
|
||||
if (gameSettings == null || gameSettings.slotItemConfigs == null || slotItem == null) return null;
|
||||
foreach (var config in gameSettings.slotItemConfigs)
|
||||
{
|
||||
if (config.slotItem == slotItem)
|
||||
if (PickupItemData.AreEquivalent(slotItem, config.slotItem))
|
||||
return config;
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Interactions
|
||||
if (heldItemData != null && _currentlySlottedItemObject == null)
|
||||
{
|
||||
// First check for forbidden items at the very start so we don't continue unnecessarily
|
||||
if (forbidden.Contains(heldItemData))
|
||||
if (PickupItemData.ListContainsEquivalent(forbidden, heldItemData))
|
||||
{
|
||||
DebugUIMessage.Show("Can't place that here.", Color.red);
|
||||
onForbiddenItemSlotted?.Invoke();
|
||||
@@ -127,7 +127,7 @@ namespace Interactions
|
||||
// the correct item we're looking for
|
||||
var config = GameManager.Instance.GetSlotItemConfig(itemData);
|
||||
var allowed = config?.allowedItems ?? new List<PickupItemData>();
|
||||
if (allowed.Contains(itemToSlotData))
|
||||
if (PickupItemData.ListContainsEquivalent(allowed, itemToSlotData))
|
||||
{
|
||||
if (itemToSlot != null)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
[CreateAssetMenu(fileName = "PickupItemData", menuName = "Game/Pickup Item Data")]
|
||||
public class PickupItemData : ScriptableObject
|
||||
@@ -7,4 +8,22 @@ public class PickupItemData : ScriptableObject
|
||||
[TextArea]
|
||||
public string description;
|
||||
public Sprite mapSprite;
|
||||
|
||||
public static bool AreEquivalent(PickupItemData a, PickupItemData b)
|
||||
{
|
||||
if (ReferenceEquals(a, b)) return true;
|
||||
if (a is null || b is null) return false;
|
||||
// Compare by itemName as a fallback
|
||||
return a.itemName == b.itemName;
|
||||
}
|
||||
|
||||
public static bool ListContainsEquivalent(List<PickupItemData> list, PickupItemData item)
|
||||
{
|
||||
foreach (var entry in list)
|
||||
{
|
||||
if (AreEquivalent(entry, item))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Utils
|
||||
to.color = from.color;
|
||||
to.flipX = from.flipX;
|
||||
to.flipY = from.flipY;
|
||||
to.material = from.material;
|
||||
to.sharedMaterial = from.sharedMaterial; // Use sharedMaterial instead of material to avoid instantiation in edit mode
|
||||
to.drawMode = from.drawMode;
|
||||
to.size = from.size;
|
||||
to.maskInteraction = from.maskInteraction;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0d863bca9b2680743bd08a98ae378772
|
||||
guid: 69ae0bad39b0d4047b207ef833c6a8f2
|
||||
folderAsset: yes
|
||||
timeCreated: 1522266281
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,9 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53b6a515c1f2ee049862496c7b3cece4
|
||||
guid: cd088c42a70189a488a25c4c87093e47
|
||||
folderAsset: yes
|
||||
timeCreated: 1521850290
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
188
Assets/Tests/EditMode/AppleHillsUtilsTests.cs
Normal file
188
Assets/Tests/EditMode/AppleHillsUtilsTests.cs
Normal file
@@ -0,0 +1,188 @@
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using Utils;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace Tests.EditMode
|
||||
{
|
||||
public class AppleHillsUtilsTests
|
||||
{
|
||||
private GameObject sourceObject;
|
||||
private GameObject targetObject;
|
||||
private SpriteRenderer sourceRenderer;
|
||||
private SpriteRenderer targetRenderer;
|
||||
private Sprite testSprite1;
|
||||
private Sprite testSprite2;
|
||||
private Material testMaterial1;
|
||||
private Material testMaterial2;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
// Create test GameObjects with SpriteRenderer components
|
||||
sourceObject = new GameObject("SourceObject");
|
||||
targetObject = new GameObject("TargetObject");
|
||||
sourceRenderer = sourceObject.AddComponent<SpriteRenderer>();
|
||||
targetRenderer = targetObject.AddComponent<SpriteRenderer>();
|
||||
|
||||
// Create test sprites (1x1 pixel textures)
|
||||
Texture2D texture1 = new Texture2D(1, 1);
|
||||
texture1.SetPixel(0, 0, Color.red);
|
||||
texture1.Apply();
|
||||
testSprite1 = Sprite.Create(texture1, new Rect(0, 0, 1, 1), Vector2.zero);
|
||||
|
||||
Texture2D texture2 = new Texture2D(1, 1);
|
||||
texture2.SetPixel(0, 0, Color.blue);
|
||||
texture2.Apply();
|
||||
testSprite2 = Sprite.Create(texture2, new Rect(0, 0, 1, 1), Vector2.zero);
|
||||
|
||||
// Create test materials
|
||||
testMaterial1 = new Material(Shader.Find("Sprites/Default"));
|
||||
testMaterial1.name = "TestMaterial1";
|
||||
testMaterial2 = new Material(Shader.Find("Sprites/Default"));
|
||||
testMaterial2.name = "TestMaterial2";
|
||||
|
||||
// Initialize target with different values to ensure they change
|
||||
targetRenderer.sprite = testSprite2;
|
||||
targetRenderer.color = Color.blue;
|
||||
targetRenderer.flipX = true;
|
||||
targetRenderer.flipY = true;
|
||||
targetRenderer.sharedMaterial = testMaterial2;
|
||||
targetRenderer.drawMode = SpriteDrawMode.Tiled;
|
||||
targetRenderer.size = new Vector2(10, 10);
|
||||
targetRenderer.maskInteraction = SpriteMaskInteraction.VisibleInsideMask;
|
||||
targetRenderer.sortingOrder = 10;
|
||||
targetRenderer.enabled = false;
|
||||
targetObject.transform.localScale = new Vector3(2, 2, 2);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
// Clean up created objects
|
||||
Object.DestroyImmediate(sourceObject);
|
||||
Object.DestroyImmediate(targetObject);
|
||||
Object.DestroyImmediate(testSprite1);
|
||||
Object.DestroyImmediate(testSprite2);
|
||||
Object.DestroyImmediate(testMaterial1);
|
||||
Object.DestroyImmediate(testMaterial2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopySpriteRendererProperties_CopiesAllProperties()
|
||||
{
|
||||
// Arrange - Set source properties
|
||||
sourceRenderer.sprite = testSprite1;
|
||||
sourceRenderer.color = Color.red;
|
||||
sourceRenderer.flipX = false;
|
||||
sourceRenderer.flipY = false;
|
||||
sourceRenderer.sharedMaterial = testMaterial1;
|
||||
sourceRenderer.drawMode = SpriteDrawMode.Simple;
|
||||
sourceRenderer.size = new Vector2(5, 5);
|
||||
sourceRenderer.maskInteraction = SpriteMaskInteraction.VisibleOutsideMask;
|
||||
sourceRenderer.sortingOrder = 5;
|
||||
sourceRenderer.enabled = true;
|
||||
sourceObject.transform.localScale = new Vector3(1, 1, 1);
|
||||
|
||||
// Act
|
||||
AppleHillsUtils.CopySpriteRendererProperties(sourceRenderer, targetRenderer);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(sourceRenderer.sprite, targetRenderer.sprite, "Sprite should be copied");
|
||||
Assert.AreEqual(sourceRenderer.color, targetRenderer.color, "Color should be copied");
|
||||
Assert.AreEqual(sourceRenderer.flipX, targetRenderer.flipX, "FlipX should be copied");
|
||||
Assert.AreEqual(sourceRenderer.flipY, targetRenderer.flipY, "FlipY should be copied");
|
||||
Assert.AreEqual(sourceRenderer.sharedMaterial, targetRenderer.sharedMaterial, "Material should be copied");
|
||||
Assert.AreEqual(sourceRenderer.drawMode, targetRenderer.drawMode, "DrawMode should be copied");
|
||||
Assert.AreEqual(sourceRenderer.size, targetRenderer.size, "Size should be copied");
|
||||
Assert.AreEqual(sourceRenderer.maskInteraction, targetRenderer.maskInteraction, "MaskInteraction should be copied");
|
||||
Assert.AreEqual(sourceRenderer.sortingLayerID, targetRenderer.sortingLayerID, "SortingLayerID should be copied");
|
||||
Assert.AreEqual(sourceRenderer.sortingOrder, targetRenderer.sortingOrder, "SortingOrder should be copied");
|
||||
Assert.IsTrue(targetRenderer.enabled, "Enabled should be set to true");
|
||||
Assert.AreEqual(sourceRenderer.transform.localScale, targetRenderer.transform.localScale, "LocalScale should be copied");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopySpriteRendererProperties_NullSource_DoesNothing()
|
||||
{
|
||||
// Arrange - Store original values
|
||||
var originalSprite = targetRenderer.sprite;
|
||||
var originalColor = targetRenderer.color;
|
||||
var originalFlipX = targetRenderer.flipX;
|
||||
var originalFlipY = targetRenderer.flipY;
|
||||
var originalMaterial = targetRenderer.sharedMaterial;
|
||||
var originalDrawMode = targetRenderer.drawMode;
|
||||
var originalSize = targetRenderer.size;
|
||||
var originalMaskInteraction = targetRenderer.maskInteraction;
|
||||
var originalSortingLayerID = targetRenderer.sortingLayerID;
|
||||
var originalSortingOrder = targetRenderer.sortingOrder;
|
||||
var originalEnabled = targetRenderer.enabled;
|
||||
var originalScale = targetRenderer.transform.localScale;
|
||||
|
||||
// Act
|
||||
AppleHillsUtils.CopySpriteRendererProperties(null, targetRenderer);
|
||||
|
||||
// Assert - Nothing should change
|
||||
Assert.AreEqual(originalSprite, targetRenderer.sprite, "Sprite should not change");
|
||||
Assert.AreEqual(originalColor, targetRenderer.color, "Color should not change");
|
||||
Assert.AreEqual(originalFlipX, targetRenderer.flipX, "FlipX should not change");
|
||||
Assert.AreEqual(originalFlipY, targetRenderer.flipY, "FlipY should not change");
|
||||
Assert.AreEqual(originalMaterial, targetRenderer.sharedMaterial, "Material should not change");
|
||||
Assert.AreEqual(originalDrawMode, targetRenderer.drawMode, "DrawMode should not change");
|
||||
Assert.AreEqual(originalSize, targetRenderer.size, "Size should not change");
|
||||
Assert.AreEqual(originalMaskInteraction, targetRenderer.maskInteraction, "MaskInteraction should not change");
|
||||
Assert.AreEqual(originalSortingLayerID, targetRenderer.sortingLayerID, "SortingLayerID should not change");
|
||||
Assert.AreEqual(originalSortingOrder, targetRenderer.sortingOrder, "SortingOrder should not change");
|
||||
Assert.AreEqual(originalEnabled, targetRenderer.enabled, "Enabled should not change");
|
||||
Assert.AreEqual(originalScale, targetRenderer.transform.localScale, "LocalScale should not change");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopySpriteRendererProperties_NullTarget_DoesNotThrow()
|
||||
{
|
||||
// Arrange
|
||||
sourceRenderer.sprite = testSprite1;
|
||||
|
||||
// Act & Assert - Should not throw an exception
|
||||
Assert.DoesNotThrow(() => AppleHillsUtils.CopySpriteRendererProperties(sourceRenderer, null));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopySpriteRendererProperties_BothNull_DoesNotThrow()
|
||||
{
|
||||
// Act & Assert - Should not throw an exception
|
||||
Assert.DoesNotThrow(() => AppleHillsUtils.CopySpriteRendererProperties(null, null));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopySpriteRendererProperties_DifferentProperties_CorrectlyCopies()
|
||||
{
|
||||
// Arrange - Set source with mixed properties
|
||||
sourceRenderer.sprite = testSprite1;
|
||||
sourceRenderer.color = new Color(0.5f, 0.5f, 0.5f, 0.7f); // Semi-transparent gray
|
||||
sourceRenderer.flipX = true;
|
||||
sourceRenderer.flipY = false;
|
||||
sourceRenderer.sharedMaterial = testMaterial1;
|
||||
sourceRenderer.drawMode = SpriteDrawMode.Sliced;
|
||||
sourceRenderer.size = new Vector2(3.5f, 2.5f);
|
||||
sourceRenderer.sortingOrder = 42;
|
||||
sourceObject.transform.localScale = new Vector3(0.5f, 1.5f, 1f); // Non-uniform scale
|
||||
|
||||
// The exact warning message format matters - match it precisely
|
||||
LogAssert.Expect(LogType.Warning, "Sprite Tiling might not appear correctly because the Sprite used is not generated with Full Rect. To fix this, change the Mesh Type in the Sprite's import setting to Full Rect");
|
||||
|
||||
// Act
|
||||
AppleHillsUtils.CopySpriteRendererProperties(sourceRenderer, targetRenderer);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(testSprite1, targetRenderer.sprite, "Sprite should match");
|
||||
Assert.AreEqual(new Color(0.5f, 0.5f, 0.5f, 0.7f), targetRenderer.color, "Color should match including alpha");
|
||||
Assert.IsTrue(targetRenderer.flipX, "FlipX should be true");
|
||||
Assert.IsFalse(targetRenderer.flipY, "FlipY should be false");
|
||||
Assert.AreEqual(SpriteDrawMode.Sliced, targetRenderer.drawMode, "DrawMode should be Sliced");
|
||||
Assert.AreEqual(new Vector2(3.5f, 2.5f), targetRenderer.size, "Size should match exactly");
|
||||
Assert.AreEqual(42, targetRenderer.sortingOrder, "SortingOrder should be 42");
|
||||
Assert.AreEqual(new Vector3(0.5f, 1.5f, 1f), targetRenderer.transform.localScale, "Non-uniform scale should match");
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Tests/EditMode/AppleHillsUtilsTests.cs.meta
Normal file
3
Assets/Tests/EditMode/AppleHillsUtilsTests.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0c2768f91f9f4455a4d7480f6ee8ef43
|
||||
timeCreated: 1757849036
|
||||
144
Assets/Tests/EditMode/BootstrapTests.cs
Normal file
144
Assets/Tests/EditMode/BootstrapTests.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace Tests.EditMode
|
||||
{
|
||||
public class BootstrapTests
|
||||
{
|
||||
private Bootstrap.CustomBootSettings settings;
|
||||
private GameObject prefab1;
|
||||
private GameObject prefab2;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
settings = ScriptableObject.CreateInstance<Bootstrap.CustomBootSettings>();
|
||||
settings.name = "TestSettings";
|
||||
prefab1 = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
prefab1.name = "Prefab1";
|
||||
prefab2 = GameObject.CreatePrimitive(PrimitiveType.Sphere);
|
||||
prefab2.name = "Prefab2";
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
// Settings will clean up the container and instantiated prefabs
|
||||
settings.Cleanup();
|
||||
|
||||
// Clean up the prefab templates
|
||||
if (prefab1 != null) Object.DestroyImmediate(prefab1);
|
||||
if (prefab2 != null) Object.DestroyImmediate(prefab2);
|
||||
if (settings != null) Object.DestroyImmediate(settings);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InitialiseSync_CreatesContainerWithCorrectName()
|
||||
{
|
||||
// Arrange
|
||||
settings.BootPrefabs = new[] { prefab1 };
|
||||
|
||||
// Act
|
||||
settings.InitialiseSync();
|
||||
|
||||
// Access the RuntimeContainer through reflection since it's private
|
||||
var containerField = typeof(Bootstrap.CustomBootSettings).GetField("RuntimeContainer",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
var container = containerField.GetValue(settings) as GameObject;
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(container, "RuntimeContainer should not be null");
|
||||
Assert.AreEqual($"{settings.name}_Container", container.name,
|
||||
"Container should be named with the pattern {settings.name}_Container");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InitialiseSync_InstantiatesAllPrefabs()
|
||||
{
|
||||
// Arrange
|
||||
settings.BootPrefabs = new[] { prefab1, prefab2 };
|
||||
|
||||
// Act
|
||||
settings.InitialiseSync();
|
||||
|
||||
// Access the RuntimeContainer and Instances through reflection
|
||||
var containerField = typeof(Bootstrap.CustomBootSettings).GetField("RuntimeContainer",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
var container = containerField.GetValue(settings) as GameObject;
|
||||
|
||||
var instancesField = typeof(Bootstrap.CustomBootSettings).GetField("Instances",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
var instances = instancesField.GetValue(settings) as GameObject[];
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(container, "RuntimeContainer should not be null");
|
||||
Assert.AreEqual(2, container.transform.childCount, "Container should have 2 child objects");
|
||||
Assert.IsNotNull(instances, "Instances array should not be null");
|
||||
Assert.AreEqual(2, instances.Length, "Instances array should have 2 elements");
|
||||
|
||||
Assert.IsNotNull(instances[0], "First instance should not be null");
|
||||
Assert.IsTrue(instances[0].name.StartsWith(prefab1.name),
|
||||
$"First instance name '{instances[0].name}' should start with prefab name '{prefab1.name}'");
|
||||
Assert.AreEqual(container.transform, instances[0].transform.parent, "First instance should be a child of the container");
|
||||
|
||||
Assert.IsNotNull(instances[1], "Second instance should not be null");
|
||||
Assert.IsTrue(instances[1].name.StartsWith(prefab2.name),
|
||||
$"Second instance name '{instances[1].name}' should start with prefab name '{prefab2.name}'");
|
||||
Assert.AreEqual(container.transform, instances[1].transform.parent, "Second instance should be a child of the container");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InitialiseSync_HandlesNullPrefabs()
|
||||
{
|
||||
// Arrange
|
||||
settings.BootPrefabs = new GameObject[] { prefab1, null, prefab2 };
|
||||
|
||||
// Act
|
||||
settings.InitialiseSync();
|
||||
|
||||
// Access the RuntimeContainer and Instances through reflection
|
||||
var containerField = typeof(Bootstrap.CustomBootSettings).GetField("RuntimeContainer",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
var container = containerField.GetValue(settings) as GameObject;
|
||||
|
||||
var instancesField = typeof(Bootstrap.CustomBootSettings).GetField("Instances",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
var instances = instancesField.GetValue(settings) as GameObject[];
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(container, "RuntimeContainer should not be null");
|
||||
Assert.AreEqual(2, container.transform.childCount, "Container should have 2 child objects (skipping the null prefab)");
|
||||
Assert.AreEqual(3, instances.Length, "Instances array should have 3 elements (including null)");
|
||||
|
||||
Assert.IsNotNull(instances[0], "First instance should not be null");
|
||||
Assert.IsNull(instances[1], "Second instance should be null");
|
||||
Assert.IsNotNull(instances[2], "Third instance should not be null");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InitialiseSync_EmptyPrefabsArray_CreatesContainerOnly()
|
||||
{
|
||||
// Arrange
|
||||
settings.BootPrefabs = new GameObject[0];
|
||||
|
||||
// Act
|
||||
settings.InitialiseSync();
|
||||
|
||||
// Access the RuntimeContainer through reflection
|
||||
var containerField = typeof(Bootstrap.CustomBootSettings).GetField("RuntimeContainer",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
var container = containerField.GetValue(settings) as GameObject;
|
||||
|
||||
var instancesField = typeof(Bootstrap.CustomBootSettings).GetField("Instances",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
var instances = instancesField.GetValue(settings) as GameObject[];
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(container, "RuntimeContainer should be created even with empty prefabs array");
|
||||
Assert.AreEqual(0, container.transform.childCount, "Container should have no children");
|
||||
Assert.AreEqual(0, instances.Length, "Instances array should be empty");
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Tests/EditMode/BootstrapTests.cs.meta
Normal file
3
Assets/Tests/EditMode/BootstrapTests.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8750f59e7251412a844c51012839ec20
|
||||
timeCreated: 1757845616
|
||||
26
Assets/Tests/EditMode/EditModeTests.asmdef
Normal file
26
Assets/Tests/EditMode/EditModeTests.asmdef
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "Tests",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"UnityEngine.TestRunner",
|
||||
"UnityEditor.TestRunner",
|
||||
"Unity.InputSystem",
|
||||
"Unity.InputSystem.TestFramework",
|
||||
"AppleHillsScripts"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": [
|
||||
"nunit.framework.dll"
|
||||
],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [
|
||||
"UNITY_INCLUDE_TESTS"
|
||||
],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
7
Assets/Tests/EditMode/EditModeTests.asmdef.meta
Normal file
7
Assets/Tests/EditMode/EditModeTests.asmdef.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 66b3a4fff1b1a544b9381e41a3e2d334
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
198
Assets/Tests/EditMode/PickupItemDataTests.cs
Normal file
198
Assets/Tests/EditMode/PickupItemDataTests.cs
Normal file
@@ -0,0 +1,198 @@
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Tests.EditMode
|
||||
{
|
||||
public class PickupItemDataTests
|
||||
{
|
||||
private PickupItemData item1;
|
||||
private PickupItemData item2;
|
||||
private PickupItemData item3;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
// Create test instances using ScriptableObject.CreateInstance
|
||||
item1 = ScriptableObject.CreateInstance<PickupItemData>();
|
||||
item1.itemName = "Apple";
|
||||
item1.description = "A red fruit";
|
||||
|
||||
item2 = ScriptableObject.CreateInstance<PickupItemData>();
|
||||
item2.itemName = "Apple";
|
||||
item2.description = "A different description"; // Different description but same name
|
||||
|
||||
item3 = ScriptableObject.CreateInstance<PickupItemData>();
|
||||
item3.itemName = "Orange";
|
||||
item3.description = "A citrus fruit";
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
// Clean up created ScriptableObjects
|
||||
if (item1 != null) Object.DestroyImmediate(item1);
|
||||
if (item2 != null) Object.DestroyImmediate(item2);
|
||||
if (item3 != null) Object.DestroyImmediate(item3);
|
||||
}
|
||||
|
||||
#region AreEquivalent Tests
|
||||
|
||||
[Test]
|
||||
public void AreEquivalent_SameReference_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var item = item1;
|
||||
|
||||
// Act
|
||||
bool result = PickupItemData.AreEquivalent(item, item);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(result, "Same reference should be equivalent");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AreEquivalent_SameItemName_ReturnsTrue()
|
||||
{
|
||||
// Arrange - item1 and item2 have the same itemName but different descriptions
|
||||
|
||||
// Act
|
||||
bool result = PickupItemData.AreEquivalent(item1, item2);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(result, "Items with the same itemName should be equivalent");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AreEquivalent_DifferentItemName_ReturnsFalse()
|
||||
{
|
||||
// Arrange - item1 and item3 have different itemNames
|
||||
|
||||
// Act
|
||||
bool result = PickupItemData.AreEquivalent(item1, item3);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(result, "Items with different itemName should not be equivalent");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AreEquivalent_FirstItemNull_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
// Act
|
||||
bool result = PickupItemData.AreEquivalent(null, item1);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(result, "Null item should not be equivalent to a non-null item");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AreEquivalent_SecondItemNull_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
// Act
|
||||
bool result = PickupItemData.AreEquivalent(item1, null);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(result, "Non-null item should not be equivalent to a null item");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AreEquivalent_BothItemsNull_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
// Act
|
||||
bool result = PickupItemData.AreEquivalent(null, null);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(result, "Two null items should be equivalent (ReferenceEquals)");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ListContainsEquivalent Tests
|
||||
|
||||
[Test]
|
||||
public void ListContainsEquivalent_EmptyList_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var list = new List<PickupItemData>();
|
||||
|
||||
// Act
|
||||
bool result = PickupItemData.ListContainsEquivalent(list, item1);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(result, "Empty list should not contain any item");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ListContainsEquivalent_ListContainsSameReference_ReturnsTrue()
|
||||
{
|
||||
// Arrange
|
||||
var list = new List<PickupItemData> { item1 };
|
||||
|
||||
// Act
|
||||
bool result = PickupItemData.ListContainsEquivalent(list, item1);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(result, "List should contain the same reference");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ListContainsEquivalent_ListContainsEquivalentItem_ReturnsTrue()
|
||||
{
|
||||
// Arrange - item1 and item2 have the same itemName but are different instances
|
||||
var list = new List<PickupItemData> { item1 };
|
||||
|
||||
// Act
|
||||
bool result = PickupItemData.ListContainsEquivalent(list, item2);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(result, "List should contain an equivalent item with the same itemName");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ListContainsEquivalent_ListDoesNotContainEquivalentItem_ReturnsFalse()
|
||||
{
|
||||
// Arrange - item1 and item3 have different itemNames
|
||||
var list = new List<PickupItemData> { item1 };
|
||||
|
||||
// Act
|
||||
bool result = PickupItemData.ListContainsEquivalent(list, item3);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(result, "List should not contain an item with a different itemName");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ListContainsEquivalent_SearchForNullInNonEmptyList_ReturnsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var list = new List<PickupItemData> { item1, item2 };
|
||||
|
||||
// Act
|
||||
bool result = PickupItemData.ListContainsEquivalent(list, null);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(result, "List should not contain a null item");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ListContainsEquivalent_SearchInListWithNull_HandlesNullGracefully()
|
||||
{
|
||||
// Arrange
|
||||
var list = new List<PickupItemData> { item1, null, item3 };
|
||||
|
||||
// Act
|
||||
bool result = PickupItemData.ListContainsEquivalent(list, item2);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(result, "List with null element should still find equivalent item");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
3
Assets/Tests/EditMode/PickupItemDataTests.cs.meta
Normal file
3
Assets/Tests/EditMode/PickupItemDataTests.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d448a09499f4498894619f2ce2a31cb
|
||||
timeCreated: 1757848750
|
||||
315
Assets/Tests/EditMode/PuzzleGraphUtilityTests.cs
Normal file
315
Assets/Tests/EditMode/PuzzleGraphUtilityTests.cs
Normal file
@@ -0,0 +1,315 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
3
Assets/Tests/EditMode/PuzzleGraphUtilityTests.cs.meta
Normal file
3
Assets/Tests/EditMode/PuzzleGraphUtilityTests.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cfcbd9adec324e99b2753f04bd3fad89
|
||||
timeCreated: 1757848874
|
||||
@@ -1,9 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76df9d89226c52547a1d901d663c2ae9
|
||||
guid: bfbde68285b34924e83405679c86742a
|
||||
folderAsset: yes
|
||||
timeCreated: 1500598980
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -46,5 +46,8 @@
|
||||
"com.unity.modules.vr": "1.0.0",
|
||||
"com.unity.modules.wind": "1.0.0",
|
||||
"com.unity.modules.xr": "1.0.0"
|
||||
}
|
||||
},
|
||||
"testables": [
|
||||
"com.unity.inputsystem"
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user