166 lines
6.5 KiB
C#
166 lines
6.5 KiB
C#
using System;
|
|
using System.IO;
|
|
using Newtonsoft.Json.Linq;
|
|
using NUnit.Framework;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using MCPForUnity.Editor.Tools;
|
|
using static MCPForUnityTests.Editor.TestUtilities;
|
|
|
|
namespace MCPForUnityTests.Editor.Tools
|
|
{
|
|
public class MaterialParameterToolTests
|
|
{
|
|
private const string TempRoot = "Assets/Temp/MaterialParameterToolTests";
|
|
private string _matPath; // unique per test run
|
|
private GameObject _sphere;
|
|
|
|
[SetUp]
|
|
public void SetUp()
|
|
{
|
|
_matPath = $"{TempRoot}/BlueURP_{Guid.NewGuid().ToString("N")}.mat";
|
|
if (!AssetDatabase.IsValidFolder("Assets/Temp"))
|
|
{
|
|
AssetDatabase.CreateFolder("Assets", "Temp");
|
|
}
|
|
if (!AssetDatabase.IsValidFolder(TempRoot))
|
|
{
|
|
AssetDatabase.CreateFolder("Assets/Temp", "MaterialParameterToolTests");
|
|
}
|
|
// Ensure any leftover material from previous runs is removed
|
|
if (AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(_matPath) != null)
|
|
{
|
|
AssetDatabase.DeleteAsset(_matPath);
|
|
AssetDatabase.Refresh();
|
|
}
|
|
// Hard-delete any stray files on disk (in case GUID lookup fails)
|
|
var abs = Path.Combine(Directory.GetCurrentDirectory(), _matPath);
|
|
try
|
|
{
|
|
if (File.Exists(abs)) File.Delete(abs);
|
|
if (File.Exists(abs + ".meta")) File.Delete(abs + ".meta");
|
|
}
|
|
catch { /* best-effort cleanup */ }
|
|
AssetDatabase.Refresh();
|
|
}
|
|
|
|
[TearDown]
|
|
public void TearDown()
|
|
{
|
|
if (_sphere != null)
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(_sphere);
|
|
_sphere = null;
|
|
}
|
|
if (AssetDatabase.LoadAssetAtPath<Material>(_matPath) != null)
|
|
{
|
|
AssetDatabase.DeleteAsset(_matPath);
|
|
}
|
|
|
|
// Clean up temp directory after each test
|
|
if (AssetDatabase.IsValidFolder(TempRoot))
|
|
{
|
|
AssetDatabase.DeleteAsset(TempRoot);
|
|
}
|
|
|
|
// Clean up empty parent folders to avoid debris
|
|
CleanupEmptyParentFolders(TempRoot);
|
|
|
|
AssetDatabase.Refresh();
|
|
}
|
|
|
|
[Test]
|
|
public void CreateMaterial_WithObjectProperties_SucceedsAndSetsColor()
|
|
{
|
|
// Ensure a clean state if a previous run left the asset behind (uses _matPath now)
|
|
if (AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(_matPath) != null)
|
|
{
|
|
AssetDatabase.DeleteAsset(_matPath);
|
|
AssetDatabase.Refresh();
|
|
}
|
|
var createParams = new JObject
|
|
{
|
|
["action"] = "create",
|
|
["path"] = _matPath,
|
|
["assetType"] = "Material",
|
|
["properties"] = new JObject
|
|
{
|
|
["shader"] = "Universal Render Pipeline/Lit",
|
|
["color"] = new JArray(0f, 0f, 1f, 1f)
|
|
}
|
|
};
|
|
|
|
var result = ToJObject(ManageAsset.HandleCommand(createParams));
|
|
Assert.IsTrue(result.Value<bool>("success"), result.Value<string>("error"));
|
|
|
|
var mat = AssetDatabase.LoadAssetAtPath<Material>(_matPath);
|
|
Assert.IsNotNull(mat, "Material should exist at path.");
|
|
// Verify color if shader exposes _Color
|
|
if (mat.HasProperty("_Color"))
|
|
{
|
|
Assert.AreEqual(Color.blue, mat.GetColor("_Color"));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void AssignMaterial_ToSphere_UsingManageMaterial_Succeeds()
|
|
{
|
|
// Ensure material exists first
|
|
CreateMaterial_WithObjectProperties_SucceedsAndSetsColor();
|
|
|
|
// Create a sphere via handler
|
|
var createGo = new JObject
|
|
{
|
|
["action"] = "create",
|
|
["name"] = "ToolTestSphere",
|
|
["primitiveType"] = "Sphere"
|
|
};
|
|
var createGoResult = ToJObject(ManageGameObject.HandleCommand(createGo));
|
|
Assert.IsTrue(createGoResult.Value<bool>("success"), createGoResult.Value<string>("error"));
|
|
|
|
_sphere = GameObject.Find("ToolTestSphere");
|
|
Assert.IsNotNull(_sphere, "Sphere should be created.");
|
|
|
|
// Assign material via ManageMaterial tool
|
|
var assignParams = new JObject
|
|
{
|
|
["action"] = "assign_material_to_renderer",
|
|
["target"] = "ToolTestSphere",
|
|
["searchMethod"] = "by_name",
|
|
["materialPath"] = _matPath,
|
|
["slot"] = 0
|
|
};
|
|
|
|
var assignResult = ToJObject(ManageMaterial.HandleCommand(assignParams));
|
|
Assert.IsTrue(assignResult.Value<bool>("success"), assignResult.ToString());
|
|
|
|
var renderer = _sphere.GetComponent<MeshRenderer>();
|
|
Assert.IsNotNull(renderer, "Sphere should have MeshRenderer.");
|
|
Assert.IsNotNull(renderer.sharedMaterial, "sharedMaterial should be assigned.");
|
|
StringAssert.StartsWith("BlueURP_", renderer.sharedMaterial.name);
|
|
}
|
|
|
|
[Test]
|
|
public void ReadRendererData_DoesNotInstantiateMaterial_AndIncludesSharedMaterial()
|
|
{
|
|
// Prepare object and assignment
|
|
AssignMaterial_ToSphere_UsingManageMaterial_Succeeds();
|
|
|
|
var renderer = _sphere.GetComponent<MeshRenderer>();
|
|
int beforeId = renderer.sharedMaterial != null ? renderer.sharedMaterial.GetInstanceID() : 0;
|
|
|
|
var data = MCPForUnity.Editor.Helpers.GameObjectSerializer.GetComponentData(renderer) as System.Collections.Generic.Dictionary<string, object>;
|
|
Assert.IsNotNull(data, "Serializer should return data.");
|
|
|
|
int afterId = renderer.sharedMaterial != null ? renderer.sharedMaterial.GetInstanceID() : 0;
|
|
Assert.AreEqual(beforeId, afterId, "sharedMaterial instance must not change (no instantiation in EditMode).");
|
|
|
|
if (data.TryGetValue("properties", out var propsObj) && propsObj is System.Collections.Generic.Dictionary<string, object> props)
|
|
{
|
|
Assert.IsTrue(
|
|
props.ContainsKey("sharedMaterial") || props.ContainsKey("material") || props.ContainsKey("sharedMaterials") || props.ContainsKey("materials"),
|
|
"Serialized data should include material info.");
|
|
}
|
|
}
|
|
}
|
|
} |