Files
coplaydev--unity-mcp/TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManageGraphicsTests.cs
T
2026-07-13 12:49:17 +08:00

698 lines
26 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
using NUnit.Framework;
using UnityEditor;
using UnityEngine;
using MCPForUnity.Editor.Tools.Graphics;
using static MCPForUnityTests.Editor.TestUtilities;
namespace MCPForUnityTests.Editor.Tools
{
public class ManageGraphicsTests
{
private const string TempRoot = "Assets/Temp/ManageGraphicsTests";
private bool _hasVolumeSystem;
private bool _hasURP;
private bool _hasHDRP;
private bool _hasSceneView;
[SetUp]
public void SetUp()
{
EnsureFolder(TempRoot);
var pingResult = ToJObject(ManageGraphics.HandleCommand(
new JObject { ["action"] = "ping" }));
if (pingResult.Value<bool>("success"))
{
var data = pingResult["data"];
_hasVolumeSystem = data?.Value<bool>("hasVolumeSystem") ?? false;
_hasURP = data?.Value<bool>("hasURP") ?? false;
_hasHDRP = data?.Value<bool>("hasHDRP") ?? false;
}
_hasSceneView = UnityEditor.SceneView.lastActiveSceneView != null;
}
[TearDown]
public void TearDown()
{
#if UNITY_2022_2_OR_NEWER
foreach (var go in UnityEngine.Object.FindObjectsByType<GameObject>(FindObjectsSortMode.None))
#else
foreach (var go in UnityEngine.Object.FindObjectsOfType<GameObject>())
#endif
{
if (go.name.StartsWith("GfxTest_"))
UnityEngine.Object.DestroyImmediate(go);
}
if (AssetDatabase.IsValidFolder(TempRoot))
AssetDatabase.DeleteAsset(TempRoot);
CleanupEmptyParentFolders(TempRoot);
// Reset scene debug mode
ManageGraphics.HandleCommand(new JObject
{
["action"] = "stats_set_scene_debug",
["mode"] = "Textured"
});
}
// =====================================================================
// Dispatch / Error Handling
// =====================================================================
[Test]
public void HandleCommand_NullParams_ReturnsError()
{
var result = ToJObject(ManageGraphics.HandleCommand(null));
Assert.IsFalse(result.Value<bool>("success"));
}
[Test]
public void HandleCommand_MissingAction_ReturnsError()
{
var result = ToJObject(ManageGraphics.HandleCommand(new JObject()));
Assert.IsFalse(result.Value<bool>("success"));
Assert.That(result["error"].ToString(), Does.Contain("action"));
}
[Test]
public void HandleCommand_UnknownAction_ReturnsError()
{
var result = ToJObject(ManageGraphics.HandleCommand(
new JObject { ["action"] = "bogus_action" }));
Assert.IsFalse(result.Value<bool>("success"));
Assert.That(result["error"].ToString(), Does.Contain("Unknown action"));
}
[Test]
public void Ping_ReturnsPipelineInfo()
{
var result = ToJObject(ManageGraphics.HandleCommand(
new JObject { ["action"] = "ping" }));
Assert.IsTrue(result.Value<bool>("success"));
Assert.That(result["message"].ToString(), Does.Contain("Pipeline"));
var data = result["data"];
Assert.IsNotNull(data);
Assert.IsNotNull(data["pipeline"]);
Assert.IsNotNull(data["pipelineName"]);
}
// =====================================================================
// Volume Actions
// =====================================================================
private void AssumeVolumeSystem()
{
Assume.That(_hasVolumeSystem, "Volume system not available — skipping.");
}
[Test]
public void VolumeCreate_Global_CreatesVolume()
{
AssumeVolumeSystem();
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_create",
["name"] = "GfxTest_Volume",
["is_global"] = true,
["priority"] = 10
}));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
Assert.IsTrue(result["data"]["isGlobal"].Value<bool>());
Assert.AreEqual(10, result["data"]["priority"].Value<int>());
}
[Test]
public void VolumeCreate_WithEffects_AddsEffects()
{
AssumeVolumeSystem();
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_create",
["name"] = "GfxTest_VolumeEffects",
["effects"] = new JArray
{
new JObject { ["type"] = "Bloom", ["intensity"] = 2 },
new JObject { ["type"] = "Vignette", ["intensity"] = 0.5 }
}
}));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
var effects = result["data"]["effects"] as JArray;
Assert.IsNotNull(effects);
Assert.AreEqual(2, effects.Count);
}
[Test]
public void VolumeCreate_Local_CreatesNonGlobal()
{
AssumeVolumeSystem();
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_create",
["name"] = "GfxTest_LocalVol",
["is_global"] = false
}));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
Assert.IsFalse(result["data"]["isGlobal"].Value<bool>());
}
[Test]
public void VolumeAddEffect_AddsEffect()
{
AssumeVolumeSystem();
CreateTestVolume("GfxTest_AddFx");
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_add_effect",
["target"] = "GfxTest_AddFx",
["effect"] = "Bloom",
["parameters"] = new JObject { ["intensity"] = 3 }
}));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
Assert.AreEqual("Bloom", result["data"]["effect"].ToString());
}
[Test]
public void VolumeAddEffect_Duplicate_ReturnsError()
{
AssumeVolumeSystem();
CreateTestVolume("GfxTest_DupFx");
ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_add_effect",
["target"] = "GfxTest_DupFx",
["effect"] = "Bloom"
});
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_add_effect",
["target"] = "GfxTest_DupFx",
["effect"] = "Bloom"
}));
Assert.IsFalse(result.Value<bool>("success"));
Assert.That(result["error"].ToString(), Does.Contain("already exists"));
}
[Test]
public void VolumeAddEffect_InvalidEffect_ReturnsError()
{
AssumeVolumeSystem();
CreateTestVolume("GfxTest_BadFx");
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_add_effect",
["target"] = "GfxTest_BadFx",
["effect"] = "FakeEffect"
}));
Assert.IsFalse(result.Value<bool>("success"));
Assert.That(result["error"].ToString(), Does.Contain("not found"));
}
[Test]
public void VolumeSetEffect_SetsParameters()
{
AssumeVolumeSystem();
CreateTestVolume("GfxTest_SetFx");
ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_add_effect",
["target"] = "GfxTest_SetFx",
["effect"] = "Bloom"
});
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_set_effect",
["target"] = "GfxTest_SetFx",
["effect"] = "Bloom",
["parameters"] = new JObject { ["intensity"] = 5, ["scatter"] = 0.8 }
}));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
var setParams = result["data"]["set"] as JArray;
Assert.IsNotNull(setParams);
Assert.That(setParams.Select(t => t.ToString()), Contains.Item("intensity"));
Assert.That(setParams.Select(t => t.ToString()), Contains.Item("scatter"));
}
[Test]
public void VolumeSetEffect_InvalidParam_ReportsFailed()
{
AssumeVolumeSystem();
CreateTestVolume("GfxTest_BadParam");
ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_add_effect",
["target"] = "GfxTest_BadParam",
["effect"] = "Bloom"
});
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_set_effect",
["target"] = "GfxTest_BadParam",
["effect"] = "Bloom",
["parameters"] = new JObject { ["nonExistent"] = 42 }
}));
Assert.IsTrue(result.Value<bool>("success"));
var failed = result["data"]["failed"] as JArray;
Assert.IsNotNull(failed);
Assert.That(failed.Select(t => t.ToString()), Contains.Item("nonExistent"));
}
[Test]
public void VolumeRemoveEffect_RemovesEffect()
{
AssumeVolumeSystem();
CreateTestVolume("GfxTest_RmFx");
ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_add_effect",
["target"] = "GfxTest_RmFx",
["effect"] = "Vignette"
});
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_remove_effect",
["target"] = "GfxTest_RmFx",
["effect"] = "Vignette"
}));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
// Verify it's gone
var info = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_get_info",
["target"] = "GfxTest_RmFx"
}));
var effects = info["data"]["effects"] as JArray;
Assert.IsNotNull(effects);
Assert.AreEqual(0, effects.Count);
}
[Test]
public void VolumeRemoveEffect_NonExistent_ReturnsError()
{
AssumeVolumeSystem();
CreateTestVolume("GfxTest_RmMissing");
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_remove_effect",
["target"] = "GfxTest_RmMissing",
["effect"] = "DepthOfField"
}));
Assert.IsFalse(result.Value<bool>("success"));
Assert.That(result["error"].ToString(), Does.Contain("not found"));
}
[Test]
public void VolumeGetInfo_ReturnsEffectList()
{
AssumeVolumeSystem();
CreateTestVolume("GfxTest_Info");
ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_add_effect",
["target"] = "GfxTest_Info",
["effect"] = "Bloom"
});
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_get_info",
["target"] = "GfxTest_Info"
}));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
var data = result["data"];
Assert.AreEqual("GfxTest_Info", data["name"].ToString());
var effects = data["effects"] as JArray;
Assert.IsNotNull(effects);
Assert.AreEqual(1, effects.Count);
Assert.AreEqual("Bloom", effects[0]["type"].ToString());
}
[Test]
public void VolumeGetInfo_NonExistentTarget_ReturnsError()
{
AssumeVolumeSystem();
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_get_info",
["target"] = "NonExistentVolume"
}));
Assert.IsFalse(result.Value<bool>("success"));
}
[Test]
public void VolumeSetProperties_UpdatesWeightAndPriority()
{
AssumeVolumeSystem();
CreateTestVolume("GfxTest_Props");
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_set_properties",
["target"] = "GfxTest_Props",
["properties"] = new JObject { ["weight"] = 0.5, ["priority"] = 20 }
}));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
var changed = result["data"]["changed"] as JArray;
Assert.IsNotNull(changed);
Assert.That(changed.Select(t => t.ToString()), Contains.Item("weight"));
Assert.That(changed.Select(t => t.ToString()), Contains.Item("priority"));
// Verify via get_info
var info = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_get_info",
["target"] = "GfxTest_Props"
}));
Assert.AreEqual(0.5f, info["data"]["weight"].Value<float>(), 0.01f);
Assert.AreEqual(20f, info["data"]["priority"].Value<float>(), 0.01f);
}
[Test]
public void VolumeListEffects_ReturnsAvailableTypes()
{
AssumeVolumeSystem();
var result = ToJObject(ManageGraphics.HandleCommand(
new JObject { ["action"] = "volume_list_effects" }));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
var effects = result["data"]["effects"] as JArray;
Assert.IsNotNull(effects);
Assert.Greater(effects.Count, 0);
Assert.IsNotNull(effects[0]["name"]);
}
[Test]
public void VolumeCreateProfile_CreatesAsset()
{
AssumeVolumeSystem();
string path = $"{TempRoot}/TestProfile";
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_create_profile",
["path"] = path
}));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
string fullPath = result["data"]["path"].ToString();
Assert.IsTrue(fullPath.EndsWith(".asset"));
Assert.IsNotNull(AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(fullPath));
}
// =====================================================================
// Bake Actions
// =====================================================================
[Test]
public void BakeGetSettings_ReturnsLightmapperInfo()
{
var result = ToJObject(ManageGraphics.HandleCommand(
new JObject { ["action"] = "bake_get_settings" }));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
var data = result["data"];
Assert.IsNotNull(data["lightmapper"]);
Assert.IsNotNull(data["lightmapResolution"]);
}
[Test]
public void BakeSetSettings_ChangesAndRestores()
{
// Read original
var original = ToJObject(ManageGraphics.HandleCommand(
new JObject { ["action"] = "bake_get_settings" }));
int origResolution = original["data"]["lightmapResolution"].Value<int>();
// Change
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "bake_set_settings",
["settings"] = new JObject { ["lightmapResolution"] = 20 }
}));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
var changed = result["data"]["changed"] as JArray;
Assert.That(changed.Select(t => t.ToString()), Contains.Item("lightmapResolution"));
// Verify
var verify = ToJObject(ManageGraphics.HandleCommand(
new JObject { ["action"] = "bake_get_settings" }));
Assert.AreEqual(20, verify["data"]["lightmapResolution"].Value<int>());
// Restore
ManageGraphics.HandleCommand(new JObject
{
["action"] = "bake_set_settings",
["settings"] = new JObject { ["lightmapResolution"] = origResolution }
});
}
[Test]
public void BakeStatus_ReportsNotRunning()
{
var result = ToJObject(ManageGraphics.HandleCommand(
new JObject { ["action"] = "bake_status" }));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
Assert.IsNotNull(result["data"]["isRunning"]);
}
[Test]
public void BakeClear_Succeeds()
{
var result = ToJObject(ManageGraphics.HandleCommand(
new JObject { ["action"] = "bake_clear" }));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
}
[Test]
public void BakeCreateReflectionProbe_CreatesProbe()
{
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "bake_create_reflection_probe",
["name"] = "GfxTest_ReflProbe",
["position"] = new JArray(0, 1, 0),
["size"] = new JArray(10, 10, 10),
["resolution"] = 128
}));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
var go = GameObject.Find("GfxTest_ReflProbe");
Assert.IsNotNull(go);
Assert.IsNotNull(go.GetComponent<ReflectionProbe>());
}
[Test]
public void BakeCreateLightProbeGroup_CreatesGrid()
{
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "bake_create_light_probe_group",
["name"] = "GfxTest_LPGroup",
["position"] = new JArray(0, 0, 0),
["grid_size"] = new JArray(2, 2, 2),
["spacing"] = 2
}));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
Assert.AreEqual(8, result["data"]["probeCount"].Value<int>());
var go = GameObject.Find("GfxTest_LPGroup");
Assert.IsNotNull(go);
Assert.IsNotNull(go.GetComponent<LightProbeGroup>());
}
[Test]
public void BakeSetProbePositions_SetsPositions()
{
ManageGraphics.HandleCommand(new JObject
{
["action"] = "bake_create_light_probe_group",
["name"] = "GfxTest_LPPos",
["grid_size"] = new JArray(1, 1, 1)
});
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "bake_set_probe_positions",
["target"] = "GfxTest_LPPos",
["positions"] = new JArray
{
new JArray(0, 0, 0),
new JArray(1, 0, 0),
new JArray(0, 1, 0)
}
}));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
Assert.AreEqual(3, result["data"]["probeCount"].Value<int>());
}
[Test]
public void BakeSetProbePositions_WrongComponent_ReturnsError()
{
var go = new GameObject("GfxTest_NoProbe");
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "bake_set_probe_positions",
["target"] = "GfxTest_NoProbe",
["positions"] = new JArray { new JArray(0, 0, 0) }
}));
Assert.IsFalse(result.Value<bool>("success"));
Assert.That(result["error"].ToString(), Does.Contain("LightProbeGroup"));
}
// =====================================================================
// Stats Actions
// =====================================================================
[Test]
public void StatsGet_ReturnsCounters()
{
var result = ToJObject(ManageGraphics.HandleCommand(
new JObject { ["action"] = "stats_get" }));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
Assert.IsNotNull(result["data"]["draw_calls"]);
Assert.IsNotNull(result["data"]["batches"]);
Assert.IsNotNull(result["data"]["triangles"]);
}
[Test]
public void StatsListCounters_ReturnsList()
{
var result = ToJObject(ManageGraphics.HandleCommand(
new JObject { ["action"] = "stats_list_counters" }));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
var counters = result["data"]["counters"] as JArray;
Assert.IsNotNull(counters);
Assert.Greater(counters.Count, 0);
}
[Test]
public void StatsGetMemory_ReturnsMemoryInfo()
{
var result = ToJObject(ManageGraphics.HandleCommand(
new JObject { ["action"] = "stats_get_memory" }));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
Assert.IsNotNull(result["data"]["totalAllocatedMB"]);
Assert.IsNotNull(result["data"]["graphicsDriverMB"]);
}
[Test]
public void StatsSetSceneDebug_ValidMode_Succeeds()
{
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "stats_set_scene_debug",
["mode"] = "Wireframe"
}));
if (_hasSceneView)
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
else
Assert.IsFalse(result.Value<bool>("success"));
}
[Test]
public void StatsSetSceneDebug_InvalidMode_ReturnsError()
{
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "stats_set_scene_debug",
["mode"] = "InvalidMode"
}));
Assert.IsFalse(result.Value<bool>("success"));
Assert.That(result["error"].ToString(), Does.Contain("Valid:"));
}
// =====================================================================
// Pipeline Actions
// =====================================================================
[Test]
public void PipelineGetInfo_ReturnsPipelineName()
{
var result = ToJObject(ManageGraphics.HandleCommand(
new JObject { ["action"] = "pipeline_get_info" }));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
Assert.IsNotNull(result["data"]["pipelineName"]);
Assert.IsNotNull(result["data"]["qualityLevelName"]);
}
[Test]
public void PipelineGetSettings_ReturnsSettings()
{
Assume.That(_hasURP || _hasHDRP, "Built-in pipeline has no settings asset — skipping.");
var result = ToJObject(ManageGraphics.HandleCommand(
new JObject { ["action"] = "pipeline_get_settings" }));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
var settings = result["data"]["settings"];
Assert.IsNotNull(settings);
Assert.IsNotNull(settings["renderScale"]);
}
[Test]
public void PipelineSetQuality_InvalidLevel_ReturnsError()
{
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "pipeline_set_quality",
["level"] = "NonExistentLevel"
}));
Assert.IsFalse(result.Value<bool>("success"));
Assert.That(result["error"].ToString(), Does.Contain("Available:"));
}
// =====================================================================
// Renderer Feature Actions (URP only)
// =====================================================================
private void AssumeURP()
{
Assume.That(_hasURP, "URP not available — skipping.");
}
[Test]
public void FeatureList_ReturnsFeatures()
{
AssumeURP();
var result = ToJObject(ManageGraphics.HandleCommand(
new JObject { ["action"] = "feature_list" }));
Assert.IsTrue(result.Value<bool>("success"), result.ToString());
Assert.IsNotNull(result["data"]["features"]);
Assert.IsNotNull(result["data"]["rendererDataName"]);
}
[Test]
public void FeatureAdd_InvalidType_ReturnsError()
{
AssumeURP();
var result = ToJObject(ManageGraphics.HandleCommand(new JObject
{
["action"] = "feature_add",
["type"] = "NonExistentFeature"
}));
Assert.IsFalse(result.Value<bool>("success"));
Assert.That(result["error"].ToString(), Does.Contain("not found"));
Assert.That(result["error"].ToString(), Does.Contain("Available:"));
}
// =====================================================================
// Helpers
// =====================================================================
private void CreateTestVolume(string name)
{
ManageGraphics.HandleCommand(new JObject
{
["action"] = "volume_create",
["name"] = name
});
}
}
}