Files
VOIDRPG/Assets/95 - Tests/EditMode/Prefabs/Generic/UnitObjectTest.cs
T
2026-07-09 21:33:33 +02:00

287 lines
13 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Sirenix.Utilities;
using Test.Util;
using UnityEditor;
using UnityEngine;
using UnityEngine.AI;
using VOID.Generic.Dict;
using VOID.Generic.Objects.Accessory;
using VOID.Generic.Objects.Armor;
using VOID.Generic.Objects.Item;
using VOID.Generic.Objects.Unit;
using VOID.Generic.Objects.Unit.Animations;
using VOID.Generic.Objects.Unit.Equipment;
using VOID.Generic.Objects.Weapon;
using VOID.Generic.Objects.Wearable;
namespace Test.EditMode.Prefabs.Generic
{
public class UnitObjectTest
{
private List<GameObject> _gameObjects = new();
[OneTimeSetUp]
public void Setup()
{
AssetDatabase.FindAssets($"t:{nameof(GameObject)}").ForEach(gameObjectGuid =>
{
var gameObjectPath = AssetDatabase.GUIDToAssetPath(gameObjectGuid);
var gameObject = AssetDatabase.LoadAssetAtPath<GameObject>(gameObjectPath);
var unitObjects = gameObject.GetComponentsInChildren<UnitObject>();
// If prefab have any ArmorObject - take it, we will test it
if (unitObjects.Length > 0) _gameObjects.Add(gameObject);
});
}
[OneTimeTearDown]
public void Cleanup()
{
_gameObjects?.Clear();
_gameObjects = null;
}
[Test]
public void UnitData_Portrait()
{
_gameObjects.ForEach(gameObject =>
{
var unitObject = gameObject.GetComponent<UnitObject>();
var prefabPath = AssetDatabase.GetAssetPath(gameObject.GetInstanceID());
var prefabPathHyperlink = DebugLogUtil.Hyperlink(prefabPath);
if (!unitObject.basicData.image)
Debug.LogError($"{nameof(UnitObject)}'s portrait is not selected: {prefabPathHyperlink}", unitObject);
if (unitObject.basicData.image.width > unitObject.basicData.image.height)
Debug.LogWarning($"{nameof(UnitObject)}'s portrait size proportions are invalid (width > height): {prefabPathHyperlink}");
});
}
[Test]
public void UnitData_Resources()
{
_gameObjects.ForEach(gameObject =>
{
var unitObject = gameObject.GetComponent<UnitObject>();
var prefabPath = AssetDatabase.GetAssetPath(gameObject.GetInstanceID());
var prefabPathHyperlink = DebugLogUtil.Hyperlink(prefabPath);
var currentResources = unitObject.unitData.currentResources;
var baseMaxResources = unitObject.unitData.baseMaxResources;
Enum.GetValues(typeof(UnitResourceType))
.Cast<UnitResourceType>()
.Where(resourceType => currentResources.Get(resourceType) > baseMaxResources.Get(resourceType))
.ForEach(resourceType => Debug.LogError($"{nameof(UnitObject)}'s {resourceType} current value is greater than base max: {prefabPathHyperlink}", unitObject));
});
}
[Test]
public void UnitData_MainAttributes()
{
_gameObjects.ForEach(gameObject =>
{
var unitObject = gameObject.GetComponent<UnitObject>();
var prefabPath = AssetDatabase.GetAssetPath(gameObject.GetInstanceID());
var prefabPathHyperlink = DebugLogUtil.Hyperlink(prefabPath);
var baseMainAttributes = unitObject.unitData.baseMainAttributes;
Enum.GetValues(typeof(MainAttributeType))
.Cast<MainAttributeType>()
.Where(mainAttributeType => baseMainAttributes.Get(mainAttributeType) < 1)
.ForEach(mainAttributeType => Debug.LogError($"{nameof(UnitObject)}'s {mainAttributeType} is lesser than 1: {prefabPathHyperlink}", unitObject));
});
}
[Test]
public void UnitData_SubAttributes()
{
// Nothing to test
}
[Test]
public void UnitData_Ranges()
{
_gameObjects.ForEach(gameObject =>
{
var unitObject = gameObject.GetComponent<UnitObject>();
var prefabPath = AssetDatabase.GetAssetPath(gameObject.GetInstanceID());
var prefabPathHyperlink = DebugLogUtil.Hyperlink(prefabPath);
var useRange = unitObject.unitData.useRange;
var talkRange = unitObject.unitData.talkRange;
var takeRange = unitObject.unitData.takeRange;
var inspectRange = unitObject.unitData.inspectRange;
if (useRange < 1)
Debug.LogError($"{nameof(UnitObject)}'s use range is lesser than 1: {prefabPathHyperlink}", unitObject);
if (talkRange < 1)
Debug.LogError($"{nameof(UnitObject)}'s talk range is lesser than 1: {prefabPathHyperlink}", unitObject);
if (takeRange < 1)
Debug.LogError($"{nameof(UnitObject)}'s take range is lesser than 1: {prefabPathHyperlink}", unitObject);
if (inspectRange < 1)
Debug.LogError($"{nameof(UnitObject)}'s inspect range is lesser than 1: {prefabPathHyperlink}", unitObject);
});
}
[Test]
public void UnitData_CastPosition()
{
_gameObjects.ForEach(gameObject =>
{
var unitObject = gameObject.GetComponent<UnitObject>();
var prefabPath = AssetDatabase.GetAssetPath(gameObject.GetInstanceID());
var prefabPathHyperlink = DebugLogUtil.Hyperlink(prefabPath);
var castPosition = unitObject.unitData.castPosition;
if (!castPosition)
Debug.LogError($"{nameof(UnitObject)}'s cast position is not selected: {prefabPathHyperlink}", unitObject);
});
}
[Test]
public void UnitAnimator_Events()
{
// Nothing to test
}
[Test]
public void UnitAnimator_ActionQueue()
{
// Nothing to test
}
[Test]
public void UnitAnimator_Animator()
{
_gameObjects.ForEach(gameObject =>
{
var unitObject = gameObject.GetComponent<UnitObject>();
var prefabPath = AssetDatabase.GetAssetPath(gameObject.GetInstanceID());
var prefabPathHyperlink = DebugLogUtil.Hyperlink(prefabPath);
var animator = SerializedUtil.GetProperty<Animator>(unitObject, "unitAnimator.animator");
if (!animator)
Debug.LogError($"{nameof(UnitObject)}'s {nameof(UnitObjectAnimator)} have missing {nameof(Animator)}: {prefabPathHyperlink}", unitObject);
var animatorCallbacks = SerializedUtil.GetProperty<UnitAnimatorCallbacks>(unitObject, "unitAnimator.unitAnimatorCallbacks");
if (!animatorCallbacks)
Debug.LogError($"{nameof(UnitObject)}'s {nameof(UnitObjectAnimator)} have missing {nameof(UnitAnimatorCallbacks)}: {prefabPathHyperlink}", unitObject);
});
}
[Test]
public void UnitNavMeshAgent_NavMeshAgent()
{
_gameObjects.ForEach(gameObject =>
{
var unitObject = gameObject.GetComponent<UnitObject>();
var prefabPath = AssetDatabase.GetAssetPath(gameObject.GetInstanceID());
var prefabPathHyperlink = DebugLogUtil.Hyperlink(prefabPath);
var navMeshAgent = SerializedUtil.GetProperty<NavMeshAgent>(unitObject, "unitNavMeshAgent.navMeshAgent");
if (navMeshAgent == null)
Debug.LogError($"{nameof(UnitObject)}'s {nameof(UnitObjectNavAgent)} have missing {nameof(NavMeshAgent)}: {prefabPathHyperlink}", unitObject);
});
}
[Test]
public void UnitDataCalculator_Formulas_TODO()
{
// TODO: dodać testy
Debug.LogWarning("TODO: zrobić weryfikacje formuł");
_gameObjects.ForEach(gameObject =>
{
});
}
[Test]
public void UnitBackpack_PredefinedItems()
{
_gameObjects.ForEach(gameObject =>
{
var unitObject = gameObject.GetComponent<UnitObject>();
var prefabPath = AssetDatabase.GetAssetPath(gameObject.GetInstanceID());
var prefabPathHyperlink = DebugLogUtil.Hyperlink(prefabPath);
var itemPrefabs =
SerializedUtil.GetPropertyArray<GameObject>(unitObject, "unitBackpack.gameObjectItems");
itemPrefabs.ForEach(prefab =>
{
if (!prefab) return;
var itemObject = prefab.GetComponent<ItemObject>();
if (!itemObject)
Debug.LogError(
$"{nameof(UnitObject)}'s backpack: prefab '{prefab.name}' is not an {nameof(ItemObject)}: {prefabPathHyperlink}",
unitObject);
});
});
}
[Test]
public void UnitEquipment_PredefinedWearables()
{
var canWearInSlot = new Dictionary<EquipmentSlotType, Func<WearableObject, bool>>
{
[EquipmentSlotType.MainHand] = wearable => wearable is WeaponObject,
[EquipmentSlotType.OffHand] = wearable => wearable is WeaponObject,
[EquipmentSlotType.Helmet] = wearable => wearable is ArmorObject helmet && helmet.armorData.armorType == ArmorType.Helmet,
[EquipmentSlotType.Armor] = wearable => wearable is ArmorObject armor && armor.armorData.armorType == ArmorType.Armor,
[EquipmentSlotType.Pants] = wearable => wearable is ArmorObject pants && pants.armorData.armorType == ArmorType.Pants,
[EquipmentSlotType.Belt] = wearable => wearable is ArmorObject belt && belt.armorData.armorType == ArmorType.Belt,
[EquipmentSlotType.Boots] = wearable => wearable is ArmorObject boots && boots.armorData.armorType == ArmorType.Boots,
[EquipmentSlotType.Gloves] = wearable => wearable is ArmorObject gloves && gloves.armorData.armorType == ArmorType.Gloves,
[EquipmentSlotType.Necklace] = wearable => wearable is AccessoryObject necklace && necklace.accessoryData.accessoryType == AccessoryType.Necklace,
[EquipmentSlotType.RingOne] = wearable => wearable is AccessoryObject ring && ring.accessoryData.accessoryType == AccessoryType.Ring,
[EquipmentSlotType.RingTwo] = wearable => wearable is AccessoryObject ring && ring.accessoryData.accessoryType == AccessoryType.Ring,
};
_gameObjects.ForEach(gameObject =>
{
var unitObject = gameObject.GetComponent<UnitObject>();
var prefabPath = AssetDatabase.GetAssetPath(gameObject.GetInstanceID());
var prefabPathHyperlink = DebugLogUtil.Hyperlink(prefabPath);
Enum.GetValues(typeof(EquipmentSlotType))
.Cast<EquipmentSlotType>()
.ForEach(equipmentSlotType =>
{
var equipmentSlotName = equipmentSlotType.ToString()[..1].ToLower() + equipmentSlotType.ToString()[1..];
var equippedItem = SerializedUtil.GetProperty<EquippedItem>(unitObject, $"unitEquipment.{equipmentSlotName}");
if (equippedItem == null || !equippedItem.gameObject) return;
var wearableObject = equippedItem.gameObject.GetComponent<WearableObject>();
var canBePlaced = canWearInSlot.GetValueOrDefault(equipmentSlotType).Invoke(wearableObject);
if (!wearableObject || !canBePlaced)
Debug.LogError(
$"{nameof(UnitObject)}'s equipment: prefab '{equippedItem.gameObject.name}' can't be placed in {equipmentSlotName}: {prefabPathHyperlink}",
unitObject);
});
});
}
[Test]
public void UnitAbilityBook_DefaultAttackAbility()
{
_gameObjects.ForEach(gameObject =>
{
var unitObject = gameObject.GetComponent<UnitObject>();
var prefabPath = AssetDatabase.GetAssetPath(gameObject.GetInstanceID());
var prefabPathHyperlink = DebugLogUtil.Hyperlink(prefabPath);
var defaultAttack = unitObject.unitAbilityBook.defaultAttackAbility;
if (defaultAttack == null)
Debug.LogError(
$"{nameof(UnitObject)}'s ability book: default attack ability is not selected: {prefabPathHyperlink}",
unitObject);
});
}
}
}