XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEToolBox

【WPF】XFE工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Windows.Media;
using System.Windows.Media.Imaging;
using XFEToolBox.Client.Models;
using XFEToolBox.Client.Utilities;

namespace XFEToolBox.Client.Wpf.Test;

public static class RecentUsageIconCacheTests
{
    [Test]
    public static void RecentUsageIconsAreFrozenReusedAndBounded()
    {
        Exception? failure = null;
        var thread = new Thread(() =>
        {
            try
            {
                RecentUsageIconCache.Clear();
                var icon = CreateIcon(0x98, 0x98, 0xE7);
                Ensure(!icon.IsFrozen, "测试图标在写入缓存前不应被冻结。");

                RecentUsageIconCache.Remember(RecentUsageKind.Tool, "Code-Line-Counter", icon);
                Ensure(icon.IsFrozen, "最近使用图标写入缓存时没有被冻结。");
                Ensure(RecentUsageIconCache.TryGet(
                           RecentUsageKind.Tool,
                           "code-line-counter",
                           out var cachedIcon),
                    "主页没有按不区分大小写的工具 ID 找到会话图标。");
                Ensure(ReferenceEquals(icon, cachedIcon),
                    "主页没有直接复用工具箱已经解码完成的图标实例。");

                for (var index = 0; index < 40; index++)
                    RecentUsageIconCache.Remember(
                        RecentUsageKind.Software,
                        $"software-{index}",
                        CreateIcon((byte)index, 0x98, 0xE7));

                Ensure(!RecentUsageIconCache.TryGet(
                           RecentUsageKind.Tool,
                           "code-line-counter",
                           out _),
                    "图标缓存超过容量后没有淘汰最早的条目。");
                Ensure(RecentUsageIconCache.TryGet(
                           RecentUsageKind.Software,
                           "software-39",
                           out _),
                    "图标缓存错误淘汰了最新条目。");
            }
            catch (Exception exception)
            {
                failure = exception;
            }
            finally
            {
                RecentUsageIconCache.Clear();
            }
        })
        {
            IsBackground = true,
            Name = "Recent usage icon cache test"
        };

        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
        Ensure(thread.Join(TimeSpan.FromSeconds(10)), "最近使用图标缓存测试超时。");
        if (failure is not null)
            throw new InvalidOperationException($"最近使用图标缓存测试失败:{failure.Message}", failure);
    }

    private static BitmapSource CreateIcon(byte red, byte green, byte blue)
    {
        const int size = 4;
        var pixels = new byte[size * size * 4];
        for (var index = 0; index < pixels.Length; index += 4)
        {
            pixels[index] = blue;
            pixels[index + 1] = green;
            pixels[index + 2] = red;
            pixels[index + 3] = 0xFF;
        }
        return BitmapSource.Create(size, size, 96, 96, PixelFormats.Bgra32, null, pixels, size * 4);
    }

    private static void Ensure(bool condition, string message)
    {
        if (!condition)
            throw new InvalidOperationException(message);
    }
}