mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-18 14:37:19 +08:00
112 lines
4.3 KiB
C#
112 lines
4.3 KiB
C#
using System.Reflection;
|
|
using AtomUI.Theme;
|
|
using AtomUI.Theme.Compilation;
|
|
using AtomUI.Theme.Configuration;
|
|
using AtomUI.Theme.Schema;
|
|
using AtomUI.Theme.DesignTokens;
|
|
using Shouldly;
|
|
using Xunit;
|
|
|
|
namespace AtomUI.Core.Tests.Theme;
|
|
|
|
public class ControlCompilationCacheTests
|
|
{
|
|
[Fact]
|
|
public void Control_Keys_Share_The_Precomputed_Global_Key()
|
|
{
|
|
var button = CreateControl("Button");
|
|
var input = CreateControl("Input");
|
|
var registry = TypedThemeSnapshotCacheTests.CreateRegistry([button, input]);
|
|
registry.TryGetControl(button.Identity, out button).ShouldBeTrue();
|
|
registry.TryGetControl(input.Identity, out input).ShouldBeTrue();
|
|
var compileInput = TypedThemeSnapshotCacheTests.CreateInput(registry);
|
|
var globalKey = GlobalCompilationCacheKey.Create(compileInput);
|
|
|
|
var buttonKey = ControlCompilationCacheKey.Create(
|
|
globalKey,
|
|
button,
|
|
null,
|
|
ThemeAppearance.Light);
|
|
var inputKey = ControlCompilationCacheKey.Create(
|
|
globalKey,
|
|
input,
|
|
null,
|
|
ThemeAppearance.Light);
|
|
|
|
var field = typeof(ControlCompilationCacheKey).GetField(
|
|
"_global",
|
|
BindingFlags.Instance | BindingFlags.NonPublic)!;
|
|
field.GetValue(buttonKey).ShouldBeSameAs(globalKey);
|
|
field.GetValue(inputKey).ShouldBeSameAs(globalKey);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Different_Snapshots_Reuse_Only_Equivalent_Control_Compilations()
|
|
{
|
|
var button = CreateControl("Button");
|
|
var input = CreateControl("Input");
|
|
var registry = TypedThemeSnapshotCacheTests.CreateRegistry([button, input]);
|
|
registry.TryGetControl(button.Identity, out button).ShouldBeTrue();
|
|
registry.TryGetControl(input.Identity, out input).ShouldBeTrue();
|
|
var buttonConfig = new NormalizedControlThemeConfig(
|
|
button.Identity,
|
|
ControlAlgorithmMode.Disabled,
|
|
Array.Empty<ThemeAlgorithmDescriptor>(),
|
|
Array.Empty<NormalizedTokenValue>(),
|
|
[CreateControlToken(button, "48")]);
|
|
var cache = new ThemeSnapshotCache();
|
|
var compiler = new ThemeCompiler();
|
|
|
|
var baseline = await TypedThemeSnapshotCacheTests.CompileAsync(cache,
|
|
TypedThemeSnapshotCacheTests.CreateInput(registry),
|
|
compiler);
|
|
var changed = await TypedThemeSnapshotCacheTests.CompileAsync(cache,
|
|
TypedThemeSnapshotCacheTests.CreateInput(registry, controls: [buttonConfig]),
|
|
compiler);
|
|
|
|
baseline.Success.ShouldBeTrue();
|
|
changed.Success.ShouldBeTrue();
|
|
changed.Snapshot!.Controls[button.Slot]
|
|
.ShouldNotBeSameAs(baseline.Snapshot!.Controls[button.Slot]);
|
|
changed.Snapshot.Controls[input.Slot]
|
|
.ShouldBeSameAs(baseline.Snapshot.Controls[input.Slot]);
|
|
cache.ControlCount.ShouldBe(3);
|
|
cache.ControlRetainedBytes.ShouldBeGreaterThan(0);
|
|
}
|
|
|
|
private static NormalizedTokenValue CreateControlToken(
|
|
ControlTokenDescriptor control,
|
|
string value)
|
|
{
|
|
var descriptor = control.OwnTokens.ShouldHaveSingleItem();
|
|
var parsed = descriptor.Parse(value);
|
|
return new NormalizedTokenValue(descriptor, parsed, descriptor.Format(parsed));
|
|
}
|
|
|
|
private static ControlTokenDescriptor CreateControl(string id)
|
|
{
|
|
var token = new TokenDescriptor(
|
|
"Height",
|
|
0,
|
|
TokenStage.Control,
|
|
typeof(double),
|
|
$"{id}.Height",
|
|
static value => ThemeTokenValueParser.Parse<double>(value),
|
|
static value => ThemeTokenValueFormatter.Format((double)value!),
|
|
static builder => ((CacheControlToken)builder).Height,
|
|
static (builder, value) => ((CacheControlToken)builder).Height = (double)value!,
|
|
static builder => ((CacheControlToken)builder).Height);
|
|
return new ControlTokenDescriptor(
|
|
ThemeTestControlTypes.For("AtomUI", id),
|
|
new ControlTokenIdentity("AtomUI", id),
|
|
[token],
|
|
static () => new CacheControlToken(),
|
|
static (builder, _) => ((CacheControlToken)builder).Height = 40);
|
|
}
|
|
|
|
private sealed class CacheControlToken : AbstractControlDesignToken
|
|
{
|
|
public double Height { get; set; }
|
|
}
|
|
}
|