using NUnit.Framework; using UnityEngine; using UnityEngine.TestTools; using UnityEditor; using LLM.Editor.Commands; using LLM.Editor.Data; using LLM.Editor.Helper; namespace LLM.Editor.Tests.Unit { [TestFixture] public class DeleteGameObjectCommandTests { private GameObject _testObject; private CommandContext _context; [SetUp] public void SetUp() { _testObject = new GameObject("ObjectToDelete"); _context = new CommandContext(); } [TearDown] public void TearDown() { if (_testObject != null) { Object.DestroyImmediate(_testObject); } } [Test] public void Execute_WithValidTarget_DeletesGameObject() { // Arrange var parameters = new DeleteGameObjectParams { targetIdentifier = _testObject.GetInstanceID() }; var command = new DeleteGameObjectCommand(parameters.ToJson()); // Act var outcome = command.Execute(_context); // Assert // The '==' operator is overloaded by Unity to check for "faked null" after destruction. Assert.IsTrue(_testObject == null, "The test object should be null after destruction."); Assert.AreEqual(CommandOutcome.Success, outcome); Assert.IsNull(_context.ErrorMessage); } [Test] public void Execute_WithInvalidTargetId_ReturnsError() { // Arrange var invalidId = -1; var parameters = new DeleteGameObjectParams { targetIdentifier = invalidId }; var command = new DeleteGameObjectCommand(parameters.ToJson()); LogAssert.Expect(LogType.Error, $"[DeleteGameObjectCommand] Could not find GameObject with ID: {invalidId}"); // Act var outcome = command.Execute(_context); // Assert Assert.AreEqual(CommandOutcome.Error, outcome); Assert.IsNotNull(_context.ErrorMessage); } [Test] public void Execute_WithZeroTargetId_ReturnsError() { // Arrange var parameters = new DeleteGameObjectParams { targetIdentifier = 0 }; var command = new DeleteGameObjectCommand(parameters.ToJson()); LogAssert.Expect(LogType.Error, "[DeleteGameObjectCommand] Invalid parameters: targetIdentifier is required."); // Act var outcome = command.Execute(_context); // Assert Assert.AreEqual(CommandOutcome.Error, outcome); Assert.IsNotNull(_context.ErrorMessage); } [Test] public void Execute_OnAssetObject_FailsSafetyCheckAndReturnsError() { // Arrange // Use a real asset, like the settings file for the analyzer, to test the safety check. var guids = AssetDatabase.FindAssets("t:ScriptableObject AnalyzerSettings"); Assume.That(guids, Is.Not.Empty, "Required 'AnalyzerSettings.asset' not found for test."); var path = AssetDatabase.GUIDToAssetPath(guids[0]); var assetObject = AssetDatabase.LoadAssetAtPath(path); var assetInstanceId = assetObject.GetInstanceID(); var parameters = new DeleteGameObjectParams { targetIdentifier = assetInstanceId }; var command = new DeleteGameObjectCommand(parameters.ToJson()); LogAssert.Expect(LogType.Error, $"[DeleteGameObjectCommand] Safety check failed: Attempted to delete an asset, not a scene object. Path: {path}"); // Act var outcome = command.Execute(_context); // Assert Assert.AreEqual(CommandOutcome.Error, outcome); Assert.IsNotNull(_context.ErrorMessage); } } }