// 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 应当被生成。"); } } }