扩展 P1 UI 导航和预加载

This commit is contained in:
JSD\13999
2026-05-20 16:22:10 +08:00
parent 1efe6c9974
commit a0508ff630
12 changed files with 615 additions and 6 deletions

View File

@@ -0,0 +1,115 @@
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using FlowScope.UI;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
namespace FlowScope.Tests.PlayMode.UI
{
public sealed class UIPreloadServiceTests
{
private readonly List<GameObject> _objects = new();
[TearDown]
public void TearDown()
{
foreach (var obj in _objects)
{
if (obj != null)
{
UnityEngine.Object.DestroyImmediate(obj);
}
}
_objects.Clear();
}
[UnityTest]
public IEnumerator PreloadAsync_LoadsPanelResourceAndKeepsHandle()
{
var prefab = CreatePrefab<ExplicitPathPanel>("ExplicitPathPrefab");
var resources = new UITestResources();
resources.Register("Custom/Explicit", prefab);
var preload = new UIPreloadService(resources);
yield return UITestAsync.Await(preload.PreloadAsync<ExplicitPathPanel>(CancellationToken.None));
Assert.That(resources.LoadedKeys, Is.EqualTo(new[] { "Custom/Explicit" }));
Assert.That(preload.IsPreloaded<ExplicitPathPanel>(), Is.True);
Assert.That(preload.TryGetPreloadedHandle<ExplicitPathPanel>(out var handle), Is.True);
Assert.That(handle.Asset, Is.SameAs(prefab));
Assert.That(resources.Handles[0].IsDisposed, Is.False);
}
[UnityTest]
public IEnumerator PreloadAsync_WhenRepeated_DoesNotLoadAgain()
{
var prefab = CreatePrefab<ExplicitPathPanel>("ExplicitPathPrefab");
var resources = new UITestResources();
resources.Register("Custom/Explicit", prefab);
var preload = new UIPreloadService(resources);
yield return UITestAsync.Await(preload.PreloadAsync<ExplicitPathPanel>(CancellationToken.None));
yield return UITestAsync.Await(preload.PreloadAsync<ExplicitPathPanel>(CancellationToken.None));
Assert.That(resources.LoadedKeys, Is.EqualTo(new[] { "Custom/Explicit" }));
Assert.That(resources.Handles, Has.Count.EqualTo(1));
}
[UnityTest]
public IEnumerator OpenAsync_WhenPanelIsPreloaded_ReusesPreloadedHandle()
{
var canvas = CreateCanvas("popup");
var prefab = CreatePrefab<ExplicitPathPanel>("ExplicitPathPrefab");
var resources = new UITestResources();
resources.Register("Custom/Explicit", prefab);
var preload = new UIPreloadService(resources);
var manager = new UIManager(resources, preload);
manager.RegisterLayer("popup", canvas, 0);
yield return UITestAsync.Await(preload.PreloadAsync<ExplicitPathPanel>(CancellationToken.None));
yield return UITestAsync.Await(
manager.OpenAsync<ExplicitPathPanel, TestViewModel>(
new TestViewModel("preloaded"),
CancellationToken.None));
manager.Close<ExplicitPathPanel>();
Assert.That(resources.LoadedKeys, Is.EqualTo(new[] { "Custom/Explicit" }));
Assert.That(resources.Handles[0].IsDisposed, Is.False);
Assert.That(preload.IsPreloaded<ExplicitPathPanel>(), Is.True);
}
[UnityTest]
public IEnumerator Release_DisposesPreloadedHandle()
{
var prefab = CreatePrefab<ExplicitPathPanel>("ExplicitPathPrefab");
var resources = new UITestResources();
resources.Register("Custom/Explicit", prefab);
var preload = new UIPreloadService(resources);
yield return UITestAsync.Await(preload.PreloadAsync<ExplicitPathPanel>(CancellationToken.None));
preload.Release<ExplicitPathPanel>();
Assert.That(resources.Handles[0].IsDisposed, Is.True);
Assert.That(preload.IsPreloaded<ExplicitPathPanel>(), Is.False);
}
private Canvas CreateCanvas(string name)
{
var gameObject = new GameObject(name);
_objects.Add(gameObject);
return gameObject.AddComponent<Canvas>();
}
private GameObject CreatePrefab<TPanel>(string name)
where TPanel : Component
{
var gameObject = new GameObject(name);
_objects.Add(gameObject);
gameObject.AddComponent<TPanel>();
return gameObject;
}
}
}