234 lines
9.6 KiB
C#
234 lines
9.6 KiB
C#
using NUnit.Framework;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
using UnityEditor;
|
|
using Newtonsoft.Json.Linq;
|
|
using MCPForUnity.Editor.Helpers;
|
|
using MCPForUnity.Editor.Tools;
|
|
using TestNamespace;
|
|
|
|
namespace MCPForUnityTests.Editor.Tools
|
|
{
|
|
public class ComponentOpsUnityEventTests
|
|
{
|
|
private GameObject testGo;
|
|
|
|
[SetUp]
|
|
public void SetUp()
|
|
{
|
|
testGo = new GameObject("UnityEventTestGO");
|
|
}
|
|
|
|
[TearDown]
|
|
public void TearDown()
|
|
{
|
|
if (testGo != null)
|
|
Object.DestroyImmediate(testGo);
|
|
}
|
|
|
|
[Test]
|
|
public void SetProperty_UnityEvent_SinglePersistentCall_PersistsViaSerialization()
|
|
{
|
|
var comp = testGo.AddComponent<UnityEventTestComponent>();
|
|
int targetId = testGo.GetInstanceID();
|
|
|
|
var value = JObject.Parse(@"{
|
|
""m_PersistentCalls"": {
|
|
""m_Calls"": [
|
|
{
|
|
""m_Target"": { ""instanceID"": " + targetId + @" },
|
|
""m_TargetAssemblyTypeName"": ""UnityEngine.GameObject, UnityEngine"",
|
|
""m_MethodName"": ""SetActive"",
|
|
""m_Mode"": 6,
|
|
""m_Arguments"": {
|
|
""m_BoolArgument"": true
|
|
},
|
|
""m_CallState"": 2
|
|
}
|
|
]
|
|
}
|
|
}");
|
|
|
|
bool ok = ComponentOps.SetProperty(comp, "onSimpleEvent", value, out string error);
|
|
|
|
Assert.IsTrue(ok, $"SetProperty should succeed, got error: {error}");
|
|
|
|
// Verify via SerializedObject readback
|
|
var so = new SerializedObject(comp);
|
|
var callsProp = so.FindProperty("onSimpleEvent.m_PersistentCalls.m_Calls");
|
|
Assert.IsNotNull(callsProp, "m_Calls property should exist");
|
|
Assert.AreEqual(1, callsProp.arraySize, "Should have 1 persistent call");
|
|
|
|
var call0 = callsProp.GetArrayElementAtIndex(0);
|
|
Assert.AreEqual("SetActive", call0.FindPropertyRelative("m_MethodName").stringValue);
|
|
Assert.AreEqual(testGo, call0.FindPropertyRelative("m_Target").objectReferenceValue);
|
|
Assert.AreEqual(6, call0.FindPropertyRelative("m_Mode").enumValueIndex);
|
|
Assert.AreEqual(2, call0.FindPropertyRelative("m_CallState").enumValueIndex);
|
|
}
|
|
|
|
[Test]
|
|
public void SetProperty_UnityEvent_MultiplePersistentCalls_AllPersist()
|
|
{
|
|
var comp = testGo.AddComponent<UnityEventTestComponent>();
|
|
int targetId = testGo.GetInstanceID();
|
|
|
|
var value = JObject.Parse(@"{
|
|
""m_PersistentCalls"": {
|
|
""m_Calls"": [
|
|
{
|
|
""m_Target"": { ""instanceID"": " + targetId + @" },
|
|
""m_TargetAssemblyTypeName"": ""UnityEngine.GameObject, UnityEngine"",
|
|
""m_MethodName"": ""SetActive"",
|
|
""m_Mode"": 6,
|
|
""m_Arguments"": { ""m_BoolArgument"": true },
|
|
""m_CallState"": 2
|
|
},
|
|
{
|
|
""m_Target"": { ""instanceID"": " + targetId + @" },
|
|
""m_TargetAssemblyTypeName"": ""UnityEngine.GameObject, UnityEngine"",
|
|
""m_MethodName"": ""SetActive"",
|
|
""m_Mode"": 6,
|
|
""m_Arguments"": { ""m_BoolArgument"": false },
|
|
""m_CallState"": 2
|
|
}
|
|
]
|
|
}
|
|
}");
|
|
|
|
bool ok = ComponentOps.SetProperty(comp, "onSimpleEvent", value, out string error);
|
|
|
|
Assert.IsTrue(ok, $"SetProperty should succeed, got error: {error}");
|
|
|
|
var so = new SerializedObject(comp);
|
|
var callsProp = so.FindProperty("onSimpleEvent.m_PersistentCalls.m_Calls");
|
|
Assert.AreEqual(2, callsProp.arraySize, "Should have 2 persistent calls");
|
|
|
|
Assert.AreEqual("SetActive", callsProp.GetArrayElementAtIndex(0).FindPropertyRelative("m_MethodName").stringValue);
|
|
Assert.AreEqual("SetActive", callsProp.GetArrayElementAtIndex(1).FindPropertyRelative("m_MethodName").stringValue);
|
|
}
|
|
|
|
[Test]
|
|
public void SetProperty_UnityEvent_EmptyCalls_ClearsEvent()
|
|
{
|
|
var comp = testGo.AddComponent<UnityEventTestComponent>();
|
|
|
|
// First set a call
|
|
int targetId = testGo.GetInstanceID();
|
|
var withCall = JObject.Parse(@"{
|
|
""m_PersistentCalls"": {
|
|
""m_Calls"": [
|
|
{
|
|
""m_Target"": { ""instanceID"": " + targetId + @" },
|
|
""m_TargetAssemblyTypeName"": ""UnityEngine.GameObject, UnityEngine"",
|
|
""m_MethodName"": ""SetActive"",
|
|
""m_Mode"": 6,
|
|
""m_Arguments"": { ""m_BoolArgument"": true },
|
|
""m_CallState"": 2
|
|
}
|
|
]
|
|
}
|
|
}");
|
|
ComponentOps.SetProperty(comp, "onSimpleEvent", withCall, out _);
|
|
|
|
// Now clear it
|
|
var empty = JObject.Parse(@"{
|
|
""m_PersistentCalls"": {
|
|
""m_Calls"": []
|
|
}
|
|
}");
|
|
|
|
bool ok = ComponentOps.SetProperty(comp, "onSimpleEvent", empty, out string error);
|
|
|
|
Assert.IsTrue(ok, $"SetProperty should succeed, got error: {error}");
|
|
|
|
var so = new SerializedObject(comp);
|
|
var callsProp = so.FindProperty("onSimpleEvent.m_PersistentCalls.m_Calls");
|
|
Assert.AreEqual(0, callsProp.arraySize, "Should have 0 persistent calls after clearing");
|
|
}
|
|
|
|
[Test]
|
|
public void SetProperty_PrivateSerializedUnityEvent_RoutesViaSerialization()
|
|
{
|
|
var comp = testGo.AddComponent<UnityEventTestComponent>();
|
|
int targetId = testGo.GetInstanceID();
|
|
|
|
var value = JObject.Parse(@"{
|
|
""m_PersistentCalls"": {
|
|
""m_Calls"": [
|
|
{
|
|
""m_Target"": { ""instanceID"": " + targetId + @" },
|
|
""m_TargetAssemblyTypeName"": ""UnityEngine.GameObject, UnityEngine"",
|
|
""m_MethodName"": ""SetActive"",
|
|
""m_Mode"": 6,
|
|
""m_Arguments"": { ""m_BoolArgument"": true },
|
|
""m_CallState"": 2
|
|
}
|
|
]
|
|
}
|
|
}");
|
|
|
|
bool ok = ComponentOps.SetProperty(comp, "_onPrivateEvent", value, out string error);
|
|
|
|
Assert.IsTrue(ok, $"SetProperty on private [SerializeField] UnityEvent should succeed, got error: {error}");
|
|
|
|
var so = new SerializedObject(comp);
|
|
var callsProp = so.FindProperty("_onPrivateEvent.m_PersistentCalls.m_Calls");
|
|
Assert.IsNotNull(callsProp, "Private event m_Calls should exist");
|
|
Assert.AreEqual(1, callsProp.arraySize, "Should have 1 persistent call");
|
|
}
|
|
|
|
[Test]
|
|
public void SetProperty_SimpleFloat_StillWorksViaReflection()
|
|
{
|
|
var audioSource = testGo.AddComponent<AudioSource>();
|
|
|
|
bool ok = ComponentOps.SetProperty(audioSource, "volume", new JValue(0.5f), out string error);
|
|
|
|
Assert.IsTrue(ok, $"SetProperty for float should succeed, got error: {error}");
|
|
Assert.AreEqual(0.5f, audioSource.volume, 0.001f);
|
|
}
|
|
|
|
[Test]
|
|
public void HandleCommand_EndToEnd_UnityEventWiring()
|
|
{
|
|
testGo.AddComponent<UnityEventTestComponent>();
|
|
int targetId = testGo.GetInstanceID();
|
|
|
|
var p = new JObject
|
|
{
|
|
["action"] = "set_property",
|
|
["target"] = testGo.name,
|
|
["search_method"] = "by_name",
|
|
["component_type"] = "UnityEventTestComponent",
|
|
["property"] = "onSimpleEvent",
|
|
["value"] = JObject.Parse(@"{
|
|
""m_PersistentCalls"": {
|
|
""m_Calls"": [
|
|
{
|
|
""m_Target"": { ""instanceID"": " + targetId + @" },
|
|
""m_TargetAssemblyTypeName"": ""UnityEngine.GameObject, UnityEngine"",
|
|
""m_MethodName"": ""SetActive"",
|
|
""m_Mode"": 6,
|
|
""m_Arguments"": { ""m_BoolArgument"": true },
|
|
""m_CallState"": 2
|
|
}
|
|
]
|
|
}
|
|
}")
|
|
};
|
|
|
|
var result = ManageComponents.HandleCommand(p);
|
|
var resultObj = result as JObject ?? JObject.FromObject(result);
|
|
|
|
Assert.IsTrue(resultObj.Value<bool>("success"), $"HandleCommand should succeed: {resultObj}");
|
|
|
|
// Verify via SerializedObject
|
|
var comp = testGo.GetComponent<UnityEventTestComponent>();
|
|
var so = new SerializedObject(comp);
|
|
var callsProp = so.FindProperty("onSimpleEvent.m_PersistentCalls.m_Calls");
|
|
Assert.AreEqual(1, callsProp.arraySize, "Should have 1 persistent call after end-to-end");
|
|
Assert.AreEqual("SetActive", callsProp.GetArrayElementAtIndex(0).FindPropertyRelative("m_MethodName").stringValue);
|
|
}
|
|
}
|
|
}
|