using System.IO;
using System.Linq;
using Newtonsoft.Json.Linq;
using NUnit.Framework;
using Unity.Pipeline.Editor.Authoring;
using Unity.Pipeline.Editor.Commands.Materials;
using Unity.Pipeline.Models;
using UnityEditor;
using UnityEngine;
namespace Unity.Pipeline.Tests.Editor.Materials
{
///
/// Tests for the CLI-213 material authoring commands (get_material_properties /
/// set_material_properties). All assets are generated in-test under a temp folder and torn down
/// afterwards. URP-specific assertions (e.g. _BaseColor / _Metallic Range / _BaseMap) are guarded
/// so the suite still runs (with Assert.Ignore) on a Built-in RP project that lacks URP/Lit.
///
public class MaterialCommandsTests
{
private const string Root = "Assets/__CLI213MaterialTest";
private string m_KnownShader; // a shader guaranteed to resolve on this project
private bool m_HasUrpLit;
[SetUp]
public void SetUp()
{
ProjectPaths.ResetAuthoringRoot();
m_HasUrpLit = Shader.Find("Universal Render Pipeline/Lit") != null;
m_KnownShader = PickKnownShader();
EnsureFolder(Root);
}
[TearDown]
public void TearDown()
{
ProjectPaths.ResetAuthoringRoot();
if (AssetDatabase.IsValidFolder(Root))
{
AssetDatabase.DeleteAsset(Root);
AssetDatabase.Refresh();
}
}
private static string PickKnownShader()
{
if (Shader.Find("Standard") != null)
return "Standard";
if (Shader.Find("Universal Render Pipeline/Lit") != null)
return "Universal Render Pipeline/Lit";
return "Sprites/Default";
}
/// The Color property to exercise: URP/Lit uses _BaseColor; built-in Standard uses _Color.
private string ColorProp => m_HasUrpLit ? "_BaseColor" : "_Color";
private static void EnsureFolder(string folder)
{
if (!AssetDatabase.IsValidFolder(folder))
AssetDatabase.CreateFolder("Assets", Path.GetFileName(folder));
}
/// Create a .mat asset with the given shader and return a path-based handle to it.
private ObjectRef CreateMaterial(string name, string shaderName = null)
{
var shader = Shader.Find(shaderName ?? m_KnownShader);
Assert.IsNotNull(shader, $"Test prerequisite: shader '{shaderName ?? m_KnownShader}' must resolve");
var mat = new Material(shader);
var path = $"{Root}/{name}.mat";
AssetDatabase.CreateAsset(mat, path);
AssetDatabase.SaveAssets();
return new ObjectRef { Path = path };
}
/// Create a tiny 2x2 texture asset on disk and return a handle to it.
private ObjectRef CreateTexture(string name)
{
var tex = new Texture2D(2, 2);
tex.SetPixels(new[] { Color.white, Color.white, Color.white, Color.white });
tex.Apply();
var bytes = tex.EncodeToPNG();
Object.DestroyImmediate(tex);
var path = $"{Root}/{name}.png";
File.WriteAllBytes(Path.Combine(ProjectPaths.ProjectRoot, path), bytes);
AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
return new ObjectRef { Path = path };
}
private static MaterialPropertyValue Prop(MaterialPropertiesResult r, string name)
=> r.Properties.FirstOrDefault(p => p.Name == name);
///
/// Extract the float components of a Color/Vector property value. The direct (in-process) path
/// returns a float[]; tolerate any IEnumerable (e.g. a JArray) so the helper also works
/// if the value was JSON round-tripped.
///
private static float[] Components(object value)
{
Assert.IsNotNull(value, "property value should not be null");
return ((System.Collections.IEnumerable)value)
.Cast