114 lines
4.2 KiB
C#
114 lines
4.2 KiB
C#
#nullable enable
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using Cysharp.Threading.Tasks;
|
|
using NUnit.Framework;
|
|
using ShrinkApp;
|
|
using UnityEngine;
|
|
using Object = UnityEngine.Object;
|
|
|
|
namespace ShrinkContext.AppAdapter.Tests
|
|
{
|
|
public class CompositionProfileTests
|
|
{
|
|
[Test]
|
|
public void JsonRoundTrip_PreservesEntryIsolationAndInterceptMetadata()
|
|
{
|
|
var document = new ShrinkAppCompositionDocument(false, new[]
|
|
{
|
|
new ShrinkAppCompositionEntry(
|
|
"app.a",
|
|
enabled: false,
|
|
isolate: new[] { new ShrinkAppCompositionIsolate("service", "community") },
|
|
intercept: new[]
|
|
{
|
|
new ShrinkAppCompositionIntercept("service", new[]
|
|
{
|
|
new ShrinkAppCompositionMetadata("access", "read-only")
|
|
})
|
|
})
|
|
});
|
|
|
|
var restored = ShrinkAppCompositionDocument.FromJson(document.ToJson());
|
|
|
|
Assert.IsFalse(restored.includeUnlistedEntries);
|
|
Assert.AreEqual(1, restored.entries.Count);
|
|
Assert.IsFalse(restored.entries[0].enabled);
|
|
Assert.AreEqual("community", restored.entries[0].isolate[0].realm);
|
|
Assert.AreEqual("read-only", restored.entries[0].intercept[0].metadata[0].value);
|
|
}
|
|
|
|
[Test]
|
|
public void ApplyComposition_RestrictsEntriesAndKeepsSettingsDisabledModules()
|
|
{
|
|
var settings = ScriptableObject.CreateInstance<ShrinkAppSettings>();
|
|
settings.disabledModuleIds = new[] { "app.a" };
|
|
var host = new ShrinkAppLoaderHost(settings, new IShrinkAppModuleInstaller[]
|
|
{
|
|
new ProfileInstaller("app.a"),
|
|
new ProfileInstaller("app.b")
|
|
});
|
|
|
|
try
|
|
{
|
|
host.ApplyComposition(new ShrinkAppCompositionDocument(false, new[]
|
|
{
|
|
new ShrinkAppCompositionEntry("app.a", enabled: true)
|
|
}));
|
|
TestAwait.Run(host.StartAsync());
|
|
|
|
Assert.IsTrue(host.IsModuleDisabled("app.a"),
|
|
"profile enabled 不应覆盖 ShrinkAppSettings 的显式禁用");
|
|
Assert.IsTrue(host.IsModuleDisabled("app.b"), "未列出的条目应被显式组合排除");
|
|
Assert.IsFalse(host.TryGetModuleFiber("app.a", out _));
|
|
Assert.IsFalse(host.TryGetModuleFiber("app.b", out _));
|
|
Assert.Throws<InvalidOperationException>(() =>
|
|
TestAwait.Run(host.SetModuleDisabledAsync("app.b", false)));
|
|
}
|
|
finally
|
|
{
|
|
if (host.IsRunning)
|
|
TestAwait.Run(host.ShutdownAsync());
|
|
Object.DestroyImmediate(settings);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void ApplyComposition_RejectsUnknownFactoryBeforeStarting()
|
|
{
|
|
var settings = ScriptableObject.CreateInstance<ShrinkAppSettings>();
|
|
try
|
|
{
|
|
var host = new ShrinkAppLoaderHost(settings, new[] { new ProfileInstaller("app.a") });
|
|
var error = Assert.Throws<ShrinkLoaderException>(() => host.ApplyComposition(
|
|
new ShrinkAppCompositionDocument(false, new[]
|
|
{
|
|
new ShrinkAppCompositionEntry("app.unknown")
|
|
})));
|
|
StringAssert.Contains("no registered module/component factory", error!.Message);
|
|
}
|
|
finally
|
|
{
|
|
Object.DestroyImmediate(settings);
|
|
}
|
|
}
|
|
|
|
private sealed class ProfileInstaller : IShrinkAppModuleInstaller
|
|
{
|
|
public ProfileInstaller(string moduleId)
|
|
{
|
|
ModuleId = moduleId;
|
|
}
|
|
|
|
public string ModuleId { get; }
|
|
public int Order => 0;
|
|
public IReadOnlyList<string> DependsOn => Array.Empty<string>();
|
|
public void RegisterServices(ShrinkAppContext context)
|
|
{
|
|
}
|
|
|
|
public UniTask InitializeAsync(ShrinkAppContext context) => UniTask.CompletedTask;
|
|
}
|
|
}
|
|
}
|