using NUnit.Framework; using UnityEngine; using LLM.Editor.Commands; using LLM.Editor.Data; using LLM.Editor.Core; using Newtonsoft.Json.Linq; namespace LLM.Editor.Tests.Unit { // A helper component with various data types to test against. public class TestComponent : MonoBehaviour { public string stringValue; public int intValue; public float floatValue; public bool boolValue; public Vector3 vector3Value; } [TestFixture] public class SetComponentValueCommandTests { private GameObject _testObject; private TestComponent _testComponent; private CommandContext _context; [SetUp] public void SetUp() { _testObject = new GameObject("TestObject"); _testComponent = _testObject.AddComponent(); _context = new CommandContext(); // The most direct way to identify a scene object for testing is its instance ID. // We will use this as the "logical name" for the scope of these tests. var instanceId = _testObject.GetInstanceID().ToString(); _context.IdentifierMap[instanceId] = instanceId; } [TearDown] public void TearDown() { if (_testObject != null) { Object.DestroyImmediate(_testObject); } } // A helper to create the command with proper JSON structure private SetComponentValueCommand CreateCommand(string memberName, JToken value) { var json = new JObject { ["subjectIdentifier"] = _testObject.GetInstanceID().ToString(), ["componentName"] = "LLM.Editor.Tests.Unit.TestComponent", ["memberName"] = memberName, ["value"] = value }.ToString(); return new SetComponentValueCommand(json); } [Test] public void Execute_SetsStringValue_Successfully() { // Arrange var command = CreateCommand("stringValue", "Hello World"); // Act var outcome = command.Execute(_context); // Assert Assert.AreEqual(CommandOutcome.Success, outcome); Assert.AreEqual("Hello World", _testComponent.stringValue); } [Test] public void Execute_SetsIntValue_Successfully() { // Arrange var command = CreateCommand("intValue", 42); // Act var outcome = command.Execute(_context); // Assert Assert.AreEqual(CommandOutcome.Success, outcome); Assert.AreEqual(42, _testComponent.intValue); } [Test] public void Execute_SetsFloatValue_Successfully() { // Arrange var command = CreateCommand("floatValue", 3.14f); // Act var outcome = command.Execute(_context); // Assert Assert.AreEqual(CommandOutcome.Success, outcome); Assert.AreEqual(3.14f, _testComponent.floatValue); } [Test] public void Execute_SetsBoolValue_Successfully() { // Arrange var command = CreateCommand("boolValue", true); // Act var outcome = command.Execute(_context); // Assert Assert.AreEqual(CommandOutcome.Success, outcome); Assert.IsTrue(_testComponent.boolValue); } [Test] public void Execute_SetsVector3Value_Successfully() { // Arrange var vec3Json = new JObject { ["x"] = 1, ["y"] = 2, ["z"] = 3 }; var command = CreateCommand("vector3Value", vec3Json); // Act var outcome = command.Execute(_context); // Assert Assert.AreEqual(CommandOutcome.Success, outcome); Assert.AreEqual(new Vector3(1, 2, 3), _testComponent.vector3Value); } [Test] public void Execute_WithInvalidMemberName_ReturnsError() { // Arrange var command = CreateCommand("invalidMember", "someValue"); // Act var outcome = command.Execute(_context); // Assert Assert.AreEqual(CommandOutcome.Error, outcome); Assert.IsNotNull(_context.ErrorMessage); Assert.IsTrue(_context.ErrorMessage.Contains("Could not find a writable serialized field or public property")); } } }