using NUnit.Framework; using UnityEngine; using UnityEditor; using System.IO; using LLM.Editor.Commands; using LLM.Editor.Data; using LLM.Editor.Helper; namespace LLM.Editor.Tests.Unit { public class MyTestCustomComponent : MonoBehaviour {} [TestFixture] public class AddComponentToAssetCommandTests { private const string TestPrefabPath = "Assets/LLM/Editor/Tests/Prefabs/TempTestPrefab.prefab"; private GameObject _testSceneObject; private CommandContext _context; private string _sceneObjectLogicalName; private string _prefabLogicalName; [SetUp] public void SetUp() { // Create a scene object for scene-based tests, with a child _testSceneObject = new GameObject("TestSceneObject"); var sceneChild = new GameObject("SceneChild"); sceneChild.transform.SetParent(_testSceneObject.transform); // Create a prefab asset for prefab-based tests var prefabSourceObject = new GameObject("TestPrefab"); var prefabChild = new GameObject("PrefabChild"); prefabChild.transform.SetParent(prefabSourceObject.transform); Directory.CreateDirectory(Path.GetDirectoryName(TestPrefabPath)); PrefabUtility.SaveAsPrefabAsset(prefabSourceObject, TestPrefabPath); Object.DestroyImmediate(prefabSourceObject); // Set up the context with identifiers for both the scene object and the prefab asset _context = new CommandContext(); _sceneObjectLogicalName = "scene_object_1"; _prefabLogicalName = "prefab_asset_1"; var scenePid = new PersistentIdentifier { logicalName = _sceneObjectLogicalName, instanceID = _testSceneObject.GetInstanceID(), path = CommandUtility.GetGameObjectPath(_testSceneObject) }; _context.IdentifierMap[_sceneObjectLogicalName] = scenePid; var prefabGuid = AssetDatabase.AssetPathToGUID(TestPrefabPath); var prefabPid = new PersistentIdentifier { logicalName = _prefabLogicalName, guid = prefabGuid }; _context.IdentifierMap[_prefabLogicalName] = prefabPid; } [TearDown] public void TearDown() { if (_testSceneObject != null) Object.DestroyImmediate(_testSceneObject); AssetDatabase.DeleteAsset(TestPrefabPath); } private static AddComponentToAssetCommand CreateCommand(string targetId, string scriptName, string childPath = null) { var parameters = new AddComponentParams { targetIdentifier = targetId, scriptName = scriptName, childPath = childPath }; return new AddComponentToAssetCommand(parameters.ToJson()); } [Test] public void Execute_OnSceneObjectRoot_AddsComponentSuccessfully() { // Arrange var command = CreateCommand(_sceneObjectLogicalName, "UnityEngine.Rigidbody"); // Act var outcome = command.Execute(_context); // Assert Assert.AreEqual(CommandOutcome.Success, outcome); Assert.IsNotNull(_testSceneObject.GetComponent()); } [Test] public void Execute_OnSceneObjectWithValidChildPath_AddsComponentToChild() { // Arrange var command = CreateCommand(_sceneObjectLogicalName, "UnityEngine.BoxCollider", "SceneChild"); // Act var outcome = command.Execute(_context); // Assert var childObject = _testSceneObject.transform.Find("SceneChild"); Assert.AreEqual(CommandOutcome.Success, outcome); Assert.IsNotNull(childObject.GetComponent()); Assert.IsNull(_testSceneObject.GetComponent()); // Ensure it wasn't added to the parent } [Test] public void Execute_OnPrefabRoot_AddsComponentToRootInAsset() { // Arrange var command = CreateCommand(_prefabLogicalName, "UnityEngine.SphereCollider"); // Act var outcome = command.Execute(_context); // Assert Assert.AreEqual(CommandOutcome.Success, outcome); var loadedPrefab = AssetDatabase.LoadAssetAtPath(TestPrefabPath); Assert.IsNotNull(loadedPrefab.GetComponent(), "Component should be added to the prefab asset's root."); } [Test] public void Execute_OnPrefabWithValidChildPath_AddsComponentToChildInAsset() { // Arrange var command = CreateCommand(_prefabLogicalName, "UnityEngine.CapsuleCollider", "PrefabChild"); // Act var outcome = command.Execute(_context); // Assert Assert.AreEqual(CommandOutcome.Success, outcome); var loadedPrefab = AssetDatabase.LoadAssetAtPath(TestPrefabPath); var childInPrefab = loadedPrefab.transform.Find("PrefabChild"); Assert.IsNotNull(childInPrefab, "Child object should exist in prefab."); Assert.IsNotNull(childInPrefab.GetComponent(), "Component should be added to the child within the prefab asset."); } [Test] public void Execute_WithInvalidScriptName_ReturnsError() { // Arrange var command = CreateCommand(_sceneObjectLogicalName, "Invalid.NonExistent.Component"); // Act var outcome = command.Execute(_context); // Assert Assert.AreEqual(CommandOutcome.Error, outcome); Assert.IsNotNull(_context.ErrorMessage); Assert.IsTrue(_context.ErrorMessage.Contains("Could not find script type")); } [Test] public void Execute_AddRigidbodyToSceneObject_Successfully() { // Arrange var command = CreateCommand(_sceneObjectLogicalName, "UnityEngine.Rigidbody"); // Act var outcome = command.Execute(_context); // Assert Assert.AreEqual(CommandOutcome.Success, outcome); Assert.IsNotNull(_testSceneObject.GetComponent()); } [Test] public void Execute_AddRigidbodyToSceneObjectWithExistingRigidbody_ReturnsError() { // Arrange _testSceneObject.AddComponent(); var command = CreateCommand(_sceneObjectLogicalName, "UnityEngine.Rigidbody"); // Act var outcome = command.Execute(_context); // Assert Assert.AreEqual(CommandOutcome.Error, outcome); Assert.IsNotNull(_context.ErrorMessage); Assert.IsTrue(_context.ErrorMessage.Contains("Failed to add component 'UnityEngine.Rigidbody'")); } } }