// Copyright (c) 2025 EFramework Innovation. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
using NUnit.Framework;
using EFramework.Unity.UIPlugin;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.TestTools;
using System.Collections;
using EFramework.Unity.Utility;
using TMPro;
///
/// TestUIUtility 是 UIUtility 的单元测试。
///
public class TestUIUtility
{
private GameObject rootObj;
private GameObject childObj;
private Canvas canvas;
private RectTransform rectTransform;
[SetUp]
public void Setup()
{
// 创建测试根对象
rootObj = new GameObject("TestRoot");
rectTransform = rootObj.AddComponent();
canvas = rootObj.AddComponent();
// 创建子对象
childObj = new GameObject("TestChild");
childObj.transform.SetParent(rootObj.transform);
childObj.AddComponent();
}
[TearDown]
public void Reset()
{
// 清理测试对象
Object.DestroyImmediate(rootObj);
}
[Test]
public void Index()
{
// 为子对象添加Image组件
var childImage = childObj.AddComponent();
// 使用RectTransform的Index方法查找子对象
var result = rectTransform.Index("TestChild", typeof(Image));
Assert.That(result, Is.Not.Null, "应能找到 Image 组件。");
Assert.That(result, Is.EqualTo(childImage), "应返回正确的 Image 组件。");
// 使用泛型方法
var typedResult1 = rectTransform.Index("TestChild");
Assert.That(typedResult1, Is.Not.Null, "泛型方法应能找到 Image 组件。");
Assert.That(typedResult1, Is.EqualTo(childImage), "泛型方法应返回正确的 Image 组件。");
// 为子对象添加Button组件
var childButton = childObj.AddComponent();
// 使用Canvas的Index方法查找子对象
result = canvas.Index("TestChild", typeof(Button));
Assert.That(result, Is.Not.Null, "应能找到 Button 组件。");
Assert.That(result, Is.EqualTo(childButton), "应返回正确的 Button 组件。");
// 使用泛型方法
var typedResult2 = canvas.Index("TestChild");
Assert.That(typedResult2, Is.Not.Null, "泛型方法应能找到 Button 组件。");
Assert.That(typedResult2, Is.EqualTo(childButton), "泛型方法应返回正确的 Button 组件。");
}
[Test]
public void SetGraphicAlpha()
{
// 添加Image组件
var graphic = rootObj.AddComponent();
graphic.color = Color.white; // 设置初始颜色
// 测试直接设置透明度(整数)
var result1 = UIUtility.SetGraphicAlpha(rootObj, 128);
Assert.That(result1, Is.EqualTo(graphic), "应返回正确的 Graphic 组件。");
Assert.That(graphic.color.a, Is.InRange(0.49f, 0.51f), "透明度应设置为 0.5。");
// 测试直接设置透明度(浮点数)
var result2 = UIUtility.SetGraphicAlpha(rootObj, 0.25f);
Assert.That(result2, Is.EqualTo(graphic), "应返回正确的Graphic组件。");
Assert.That(graphic.color.a, Is.InRange(0.24f, 0.26f), "透明度应设置为 0.25。");
// 为子对象添加Text组件并测试路径方式
var childText = childObj.AddComponent();
childText.color = Color.white;
// 测试路径设置透明度(整数)
var result3 = rootObj.SetGraphicAlpha("TestChild", 64);
Assert.That(result3, Is.EqualTo(childText), "应返回正确的子对象 Graphic 组件。");
Assert.That(childText.color.a, Is.InRange(0.24f, 0.26f), "子对象透明度应设置为 0.25。");
// 测试路径设置透明度(浮点数)
var result4 = rootObj.SetGraphicAlpha("TestChild", 0.75f);
Assert.That(result4, Is.EqualTo(childText), "应返回正确的子对象 Graphic 组件。");
Assert.That(childText.color.a, Is.InRange(0.74f, 0.76f), "子对象透明度应设置为 0.75。");
}
[Test]
public void SetButtonEvent()
{
// 添加Button组件
var button = rootObj.AddComponent();
bool callbackCalled = false;
GameObject callbackObj = null;
// 测试直接设置按钮事件
var result1 = rootObj.SetButtonEvent((go) => { callbackCalled = true; callbackObj = go; });
Assert.That(result1, Is.EqualTo(button), "应返回正确的 Button 组件。");
// 模拟点击
button.onClick.Invoke();
Assert.That(callbackCalled, Is.True, "回调应被调用。");
Assert.That(callbackObj, Is.EqualTo(rootObj), "回调参数应为正确的 GameObject。");
// 为子对象添加Button组件
callbackCalled = false;
callbackObj = null;
var childButton = childObj.AddComponent();
// 测试路径设置按钮事件
var result2 = rootObj.SetButtonEvent("TestChild", (go) => { callbackCalled = true; callbackObj = go; });
Assert.That(result2, Is.EqualTo(childButton), "应返回正确的子对象 Button 组件。");
// 模拟点击
childButton.onClick.Invoke();
Assert.That(callbackCalled, Is.True, "子对象回调应被调用。");
Assert.That(callbackObj, Is.EqualTo(childObj), "子对象回调参数应为正确的 GameObject。");
}
[Test]
public void SetEventEnabled()
{
// 添加Button组件
var button = rootObj.AddComponent();
button.interactable = false;
// 测试直接设置事件启用状态
rootObj.SetEventEnabled(true);
Assert.That(button.interactable, Is.True, "按钮应变为可交互。");
// 测试直接设置事件禁用状态
rootObj.SetEventEnabled(false);
Assert.That(button.interactable, Is.False, "按钮应变为不可交互。");
// 为子对象添加Button组件
var childButton = childObj.AddComponent();
childButton.interactable = false;
// 测试路径设置事件启用状态
rootObj.SetEventEnabled("TestChild", true);
Assert.That(childButton.interactable, Is.True, "子对象按钮应变为可交互。");
// 测试路径设置事件禁用状态
rootObj.SetEventEnabled("TestChild", false);
Assert.That(childButton.interactable, Is.False, "子对象按钮应变为不可交互。");
}
[Test]
public void SetLabelText()
{
// 添加Text组件
var text = rootObj.AddComponent();
text.text = "";
// 测试直接设置文本
var result1 = rootObj.SetLabelText("test content");
Assert.That(result1, Is.EqualTo(text), "应返回正确的 Text 组件。");
Assert.That(text.text, Is.EqualTo("test content"), "文本应正确设置。");
// 测试设置数字
var result2 = rootObj.SetLabelText(123);
Assert.That(result2, Is.EqualTo(text), "应返回正确的 Text 组件。");
Assert.That(text.text, Is.EqualTo("123"), "数字应转换为文本并正确设置。");
// 为子对象添加Text组件
var childText = childObj.AddComponent();
childText.text = "";
// 测试路径设置文本
var result3 = rootObj.SetLabelText("TestChild", "child text content");
Assert.That(result3, Is.EqualTo(childText), "应返回正确的子对象 Text 组件。");
Assert.That(childText.text, Is.EqualTo("child text content"), "子对象文本应正确设置。");
}
[Test]
public void SetMeshProText()
{
// 添加TextMeshProUGUI组件
var tmpText = rootObj.AddComponent();
tmpText.text = "";
// 测试直接设置文本
var result1 = rootObj.SetMeshProText("TMP test content");
Assert.That(result1, Is.EqualTo(tmpText), "应返回正确的 TextMeshProUGUI 组件。");
Assert.That(tmpText.text, Is.EqualTo("TMP test content"), "TMP 文本应正确设置。");
// 为子对象添加TextMeshProUGUI组件
var childTmpText = childObj.AddComponent();
childTmpText.text = "";
// 测试路径设置文本
var result2 = rootObj.SetMeshProText("TestChild", "TMP child text content");
Assert.That(result2, Is.EqualTo(childTmpText), "应返回正确的子对象 TextMeshProUGUI 组件。");
Assert.That(childTmpText.text, Is.EqualTo("TMP child text content"), "子对象 TMP 文本应正确设置。");
}
[Test]
public void SetSpriteAlpha()
{
// 添加Image组件
var image = rootObj.AddComponent();
image.color = Color.white;
// 测试直接设置透明度(整数)
var result1 = rootObj.SetSpriteAlpha(128);
Assert.That(result1, Is.EqualTo(image), "应返回正确的 Image 组件。");
Assert.That(image.color.a, Is.InRange(0.49f, 0.51f), "透明度应设置为 0.5。");
// 测试直接设置透明度(浮点数)
rootObj.SetSpriteAlpha(0.25f);
Assert.That(image.color.a, Is.InRange(0.24f, 0.26f), "透明度应设置为 0.25。");
// 为子对象添加Image组件
var childImage = childObj.AddComponent();
childImage.color = Color.white;
// 测试路径设置透明度(整数)
rootObj.SetSpriteAlpha("TestChild", 64);
Assert.That(childImage.color.a, Is.InRange(0.24f, 0.26f), "子对象透明度应设置为 0.25。");
// 测试路径设置透明度(浮点数)
rootObj.SetSpriteAlpha("TestChild", 0.75f);
Assert.That(childImage.color.a, Is.InRange(0.74f, 0.76f), "子对象透明度应设置为 0.75。");
}
[Test]
public void SetSpriteName()
{
// 创建一个临时的Sprite对象和UIAtlas对象
Sprite sprite1 = Sprite.Create(Texture2D.whiteTexture, new Rect(0, 0, 4, 4), Vector2.zero);
Sprite sprite2 = Sprite.Create(Texture2D.whiteTexture, new Rect(0, 0, 4, 4), Vector2.zero);
sprite1.name = "TestSprite1";
sprite2.name = "TestSprite2";
var atlasObj = new GameObject("TestAtlas");
var atlas = atlasObj.AddComponent();
atlas.Sprites = new Sprite[] { sprite1, sprite2 };
// 为子对象添加Image组件
var childImage = childObj.AddComponent();
// 测试设置精灵名称
var result = rootObj.SetSpriteName("TestChild", "TestSprite1", atlas);
Assert.That(result, Is.EqualTo(childImage), "应返回正确的 Image 组件。");
Assert.That(childImage.sprite, Is.EqualTo(sprite1), "精灵应正确设置。");
// 清理
Object.DestroyImmediate(atlasObj);
}
[UnityTest]
public IEnumerator SetRawImage()
{
// 添加RawImage组件
var rawImage = rootObj.AddComponent();
// 设置一个本地测试URI
var testUri = "file://" + XFile.PathJoin(XEnv.ProjectPath, "Assets/Tests/Runtime/RawAssets/Square.png");
// 测试直接设置图片
var result1 = rootObj.SetRawImage(testUri, false);
Assert.That(result1, Is.EqualTo(rawImage), "应返回正确的 RawImage 组件。");
var childRawImage = childObj.AddComponent();
// 测试路径设置图片
var result2 = rootObj.SetRawImage("TestChild", testUri, false);
Assert.That(result2, Is.EqualTo(childRawImage), "应返回正确的子对象 RawImage 组件。");
// 等待一帧,让协程有机会运行
yield return null;
// 测试GetTexture方法
var texture = UIUtility.GetTexture(testUri);
Assert.That(texture, Is.Not.Null, "应返回正确的 Texture2D 对象。");
}
}