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

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Text;
using Xunit;
using Xunit.Abstractions;

namespace XFESystem.Documents.Tests;

public sealed class WebsiteAssetCacheTests(ITestOutputHelper output)
{
    [Fact]
    public void EntireTextCatalogPreservesOriginalDecodedTextAndObjectIdentity()
    {
        const string prefix = "Documents/Website/";
        var names = typeof(WebsiteAssets).Assembly.GetManifestResourceNames()
            .Where(name => name.StartsWith(prefix, StringComparison.Ordinal))
            .Where(name => Path.GetExtension(name).ToLowerInvariant() is ".js" or ".css" or ".json" or ".md" or ".txt" or ".html" or ".htm")
            .Select(name => name[prefix.Length..]).ToArray();
        Assert.Equal(names.Length, WebsiteAssets.PrewarmTextResources());
        long characters = 0;
        foreach (string name in names)
        {
            using var original = new StreamReader(WebsiteAssets.Open(name));
            string cached = WebsiteAssets.ReadText(name);
            Assert.Equal(original.ReadToEnd(), cached);
            Assert.Same(cached, WebsiteAssets.ReadText(name));
            characters += cached.Length;
        }
        Assert.InRange(names.Length, 1, 512); Assert.InRange(characters, 1, 16_777_216);
        output.WriteLine("Website text cache: {0} entries, {1} UTF-16 characters; embedded bytes remain unchanged.", names.Length, characters);
    }

    [Fact]
    public void MermaidHitsReuseOneStringAcrossThreadsAndAvoidLargeTransientAllocations()
    {
        string expected = WebsiteAssets.ReadText("Exact/Mermaid.min.js");
        Assert.True(expected.Length > 3_000_000);
        Parallel.For(0, 32, _ => Assert.Same(expected, WebsiteAssets.ReadText("Exact/Mermaid.min.js")));
        long before = GC.GetAllocatedBytesForCurrentThread();
        for (int read = 0; read < 64; read++) Assert.Same(expected, WebsiteAssets.ReadText("Exact/Mermaid.min.js"));
        Assert.InRange(GC.GetAllocatedBytesForCurrentThread() - before, 0, 1_048_576);
        Assert.True(WebsiteAssets.TryReadWebText("/js/docs/mermaid.min.js", out string routed, out string mime));
        Assert.Same(expected, routed); Assert.Equal("application/javascript", mime);
    }

    [Fact]
    public void WebTextRoutesKeepOriginalBinaryFallbackAndRejectInvalidPaths()
    {
        foreach (var resource in WebsiteAssets.WebResources)
        {
            Assert.True(WebsiteAssets.TryReadWebText(resource.UrlPath, out string text, out string mime));
            using var original = new StreamReader(WebsiteAssets.Open(resource.AssetName), Encoding.UTF8, true);
            Assert.Equal(original.ReadToEnd(), text); Assert.Equal(resource.ContentType, mime);
        }
        Assert.False(WebsiteAssets.TryReadWebText("/js/docs/../mermaid.min.js", out _, out _));
        Assert.False(WebsiteAssets.TryReadWebText("/js/docs/mermaid.min.js?changed=1", out _, out _));
        Assert.Throws<ArgumentException>(() => WebsiteAssets.ReadText("../Mermaid.min.js"));
        Assert.Throws<FileNotFoundException>(() => WebsiteAssets.ReadText("Missing.min.js"));
    }
}