using System.Reflection;
using AcDream.App.Rendering;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using Xunit;
namespace AcDream.App.Tests.Rendering;
///
/// The icon resource names are coupled to LogicalName in
/// AcDream.App.csproj by string alone, so a rename on either side compiles
/// cleanly and only fails as a silently icon-less window at runtime. These
/// tests are that coupling's only guard.
///
public class WindowIconLoaderTests
{
private static IReadOnlyList ExpectedResourceNames()
{
var field = typeof(WindowIconLoader).GetField(
"ResourceNames", BindingFlags.NonPublic | BindingFlags.Static);
Assert.NotNull(field);
var names = (string[]?)field!.GetValue(null);
Assert.NotNull(names);
return names!;
}
[Fact]
public void EveryDeclaredIconResource_IsActuallyEmbedded()
{
var assembly = typeof(WindowIconLoader).Assembly;
string[] embedded = assembly.GetManifestResourceNames();
foreach (string name in ExpectedResourceNames())
{
Assert.True(
embedded.Contains(name),
$"WindowIconLoader expects embedded resource '{name}', but the "
+ "assembly does not contain it. Check the EmbeddedResource "
+ "LogicalName entries in AcDream.App.csproj.");
}
}
[Fact]
public void EmbeddedIcons_DecodeToSquareRgbaImagesOfTheDeclaredSize()
{
var assembly = typeof(WindowIconLoader).Assembly;
foreach (string name in ExpectedResourceNames())
{
using Stream? stream = assembly.GetManifestResourceStream(name);
Assert.NotNull(stream);
using var image = Image.Load(stream!);
Assert.Equal(image.Width, image.Height);
// The trailing "-.png" must match the actual pixel size, or
// the window manager picks the wrong image for a surface.
string stem = Path.GetFileNameWithoutExtension(name);
string declared = stem[(stem.LastIndexOf('-') + 1)..];
Assert.Equal(int.Parse(declared), image.Width);
}
}
[Fact]
public void IconSet_CoversBothSmallAndLargeSurfaces()
{
var sizes = new List();
foreach (string name in ExpectedResourceNames())
{
string stem = Path.GetFileNameWithoutExtension(name);
sizes.Add(int.Parse(stem[(stem.LastIndexOf('-') + 1)..]));
}
// Title bars want ~16px and Alt-Tab/taskbar want a large one; shipping
// only one size leaves the window manager resampling badly.
Assert.Contains(16, sizes);
Assert.True(sizes.Max() >= 128, "icon set has no large size for Alt-Tab/taskbar");
}
}