// 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 System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
using UnityEngine.TestTools;
using EFramework.Unity.Utility;
using EFramework.Unity.Editor;
using EFramework.Unity.UIPlugin.Editor;
using EFramework.Unity.UIPlugin;
///
/// TestUIAtlasEditor 是 UIAtlasEditor 的单元测试。
///
public class TestUIAtlasEditor
{
const string TestDir = "Assets/Temp/TestUIAtlasEditor";
readonly string TestRawPath = XFile.PathJoin(TestDir, "RawAssets/TestAtlas");
readonly string TestPrefabFile = XFile.PathJoin(TestDir, "TestAtlas.prefab");
[SetUp]
public void Setup()
{
if (!XFile.HasDirectory(TestDir)) XFile.CreateDirectory(TestDir);
if (XFile.HasDirectory(TestRawPath)) XFile.DeleteDirectory(TestRawPath);
XFile.CopyDirectory("Assets/Tests/Runtime/RawAssets", TestRawPath);
}
[TearDown]
public void Reset()
{
if (XFile.HasDirectory(TestDir))
{
XFile.DeleteDirectory(TestDir);
AssetDatabase.Refresh();
}
}
[Test]
public void OnLoad()
{
// Arrange
UIAtlasEditor.icon = null;
var originCount = EditorApplication.projectWindowItemOnGUI == null ? 0 : EditorApplication.projectWindowItemOnGUI.GetInvocationList()?.Length ?? 0;
// Act
(new UIAtlasEditor() as XEditor.Event.Internal.OnEditorLoad).Process();
// Assert
Assert.That(UIAtlasEditor.icon, Is.Not.Null, "icon 应当被加载到。");
var addedCount = EditorApplication.projectWindowItemOnGUI.GetInvocationList().Length;
Assert.That(originCount + 1, Is.EqualTo(addedCount), "回调函数应当被注册。");
}
[Test]
public void Create()
{
LogAssert.ignoreFailingMessages = true; // 忽略所有错误日志
var asset = UIAtlasEditor.Create(TestPrefabFile, TestRawPath);
LogAssert.ignoreFailingMessages = false; // 恢复正常行为
// Assert
Assert.That(asset, Is.Not.Null, "应该成功创建资产。");
var prefab = AssetDatabase.LoadAssetAtPath(TestPrefabFile);
Assert.That(prefab, Is.Not.Null, "预制体应该存在。");
var atlas = prefab.GetComponent();
Assert.That(atlas, Is.Not.Null, "预制体应该包含 UIAtlas 组件。");
Assert.That(TestRawPath, Is.EqualTo(atlas.RawPath), "RawPath 应该被正确设置。");
}
[Test]
public void Import()
{
var task = XEditor.Command.Run(
bin: XEditor.Command.Find("TexturePacker", "C:/Program Files/CodeAndWeb/TexturePacker/bin", "/Applications/TexturePacker.app/Contents/MacOS"),
args: new string[] { "--version" });
task.Wait();
Assert.That(task.Result.Code, Is.EqualTo(0), "TexturePacker 应当安装成功。");
// 测试导入失败
{
LogAssert.Expect(LogType.Error, new Regex(@"UIAtlasEditor\.Import: null atlas at: .*"));
// 使用一个不存在的路径
var nonExistentPath = "Assets/NonExistent/Atlas.prefab";
var result = UIAtlasEditor.Import(nonExistentPath);
Assert.That(result, Is.False, "当图集不存在时应返回 false。");
}
// 测试导入成功
{
// 创建图集预制体但设置不存在的RawPath
var go = new GameObject("TestAtlas");
var atlas = go.AddComponent();
atlas.RawPath = TestRawPath;
LogAssert.ignoreFailingMessages = true;
PrefabUtility.SaveAsPrefabAsset(go, TestPrefabFile); // 保存预制体会触发Import
LogAssert.ignoreFailingMessages = false;
// 验证预制体是否包含精灵引用
var prefab = AssetDatabase.LoadAssetAtPath(TestPrefabFile);
var prefaAtlas = prefab.GetComponent();
Assert.That(prefaAtlas, Is.Not.Null, "预制体应该包含 UIAtlas 组件。");
var sprites = prefaAtlas.Sprites.ToList();
Assert.That(sprites.Count, Is.EqualTo(4), "图片精灵的数量应当为 4。");
Assert.That(sprites.Exists(ele => ele.name == "Square"), Is.True, "指定的图片精灵应当存在。");
Assert.That(sprites.Exists(ele => ele.name == "UnityIcon"), Is.True, "指定的图片精灵应当存在。");
Assert.That(sprites.Exists(ele => ele.name == "UnityIcon2"), Is.True, "指定的图片精灵应当存在。");
Assert.That(sprites.Exists(ele => ele.name == "UnityIcon3"), Is.True, "指定的图片精灵应当存在。");
var atlasDir = Path.GetDirectoryName(TestPrefabFile);
Assert.That(XFile.HasFile(XFile.PathJoin(atlasDir, "TestAtlas.png")), Is.True, "TestAtlas.png 应当被生成。");
}
}
}