mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-13 14:27:21 +00:00
Changed all icons of AI Studio to Lucide (#1187)
This commit is contained in:
1 parent
9a676101f7
commit
7ef26cd5c8
352 files changed
+6261
-1620
No files matched your search
@@ -0,0 +1,109 @@
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json;
|
||||
|
||||
using AIStudio.Tools;
|
||||
|
||||
namespace AIStudio.Tests.Icons;
|
||||
|
||||
/// <summary>
|
||||
/// Checks the Lucide icons the app was built with against the font it ships.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// LucideIconGeneratorTests runs the generator by hand. These tests ask whether it also ran while the app
|
||||
/// was built, against the code points in the repository, and whether the font those code points belong to
|
||||
/// ships with the app.
|
||||
/// </remarks>
|
||||
[TestFixture]
|
||||
public sealed class LucideIconsTests
|
||||
{
|
||||
private const string FONT_ICON_PREFIX = "lucide/";
|
||||
|
||||
[Test]
|
||||
public void TheAppKnowsEveryIconOfTheShippedCodepointsUnderItsName()
|
||||
{
|
||||
var codepoints = ReadCodepoints();
|
||||
var wrong = codepoints
|
||||
.Where(entry => !LucideIconRegistry.TryGet(entry.Key, out var icon) || icon != FONT_ICON_PREFIX + char.ConvertFromUtf32(entry.Value))
|
||||
.Select(entry => entry.Key)
|
||||
.ToList();
|
||||
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(codepoints, Has.Count.GreaterThan(1000), "The code points of the font were not found or not read.");
|
||||
Assert.That(wrong, Is.Empty, "These icons are missing from the app or point to another glyph.");
|
||||
Assert.That(IconConstants(), Has.Count.EqualTo(codepoints.Count), "Every name, aliases included, gets a constant of its own.");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EveryIconIsAFontIconOfOneGlyph()
|
||||
{
|
||||
var malformed = IconConstants()
|
||||
.Where(icon => !IsFontIconOfOneGlyph(icon.Value))
|
||||
.Select(icon => icon.Key)
|
||||
.ToList();
|
||||
|
||||
Assert.That(malformed, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TheRegistryFindsAnIconOnlyByItsExactName()
|
||||
{
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(LucideIconRegistry.TryGet("trash-2", out var trash), Is.True);
|
||||
Assert.That(trash, Is.EqualTo(LucideIcons.TRASH_2));
|
||||
|
||||
Assert.That(LucideIconRegistry.TryGet("home", out var home), Is.True, "An alias is a name of its own.");
|
||||
Assert.That(home, Is.EqualTo(LucideIcons.HOUSE));
|
||||
|
||||
Assert.That(LucideIconRegistry.TryGet("Trash-2", out _), Is.False);
|
||||
Assert.That(LucideIconRegistry.TryGet("trash 2", out _), Is.False);
|
||||
Assert.That(LucideIconRegistry.TryGet("lucide:trash-2", out _), Is.False, "The prefix of plugins is not part of the name.");
|
||||
Assert.That(LucideIconRegistry.TryGet(string.Empty, out _), Is.False);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TheFontShipsWithTheAppAlongWithItsLicense()
|
||||
{
|
||||
var webRoot = Path.Combine(AppSourceDirectory(), "wwwroot");
|
||||
var css = File.ReadAllText(Path.Combine(webRoot, "app.css"));
|
||||
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(File.Exists(Path.Combine(webRoot, "fonts", "lucide.woff2")), Is.True);
|
||||
Assert.That(File.Exists(Path.Combine(webRoot, "fonts", "LICENSE-lucide.txt")), Is.True);
|
||||
Assert.That(css, Does.Contain("url('fonts/lucide.woff2')"), "app.css has to declare the font.");
|
||||
Assert.That(css, Does.Contain(".mud-icon-root.lucide"), "app.css has to apply the font to the class every icon string names.");
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsFontIconOfOneGlyph(string icon)
|
||||
{
|
||||
if (!icon.StartsWith(FONT_ICON_PREFIX, StringComparison.Ordinal))
|
||||
return false;
|
||||
|
||||
var glyph = icon[FONT_ICON_PREFIX.Length..];
|
||||
var isOneCharacter = glyph.Length is 1 && !char.IsSurrogate(glyph[0]) || glyph.Length is 2 && char.IsSurrogatePair(glyph, 0);
|
||||
|
||||
return isOneCharacter && CharUnicodeInfo.GetUnicodeCategory(glyph, 0) is UnicodeCategory.PrivateUse;
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> IconConstants() => typeof(LucideIcons)
|
||||
.GetFields(BindingFlags.Public | BindingFlags.Static)
|
||||
.Where(field => field.IsLiteral)
|
||||
.ToDictionary(field => field.Name, field => (string)field.GetRawConstantValue()!);
|
||||
|
||||
private static Dictionary<string, int> ReadCodepoints()
|
||||
{
|
||||
var path = Path.Combine(AppSourceDirectory(), "..", "SourceGeneratedMappings", "Lucide", "codepoints.json");
|
||||
using var document = JsonDocument.Parse(File.ReadAllText(path));
|
||||
|
||||
return document.RootElement.EnumerateObject().ToDictionary(property => property.Name, property => property.Value.GetInt32());
|
||||
}
|
||||
|
||||
private static string AppSourceDirectory([CallerFilePath] string sourceFilePath = "") => Path.GetFullPath(Path.Combine(Path.GetDirectoryName(sourceFilePath)!, "..", "..", "MindWork AI Studio"));
|
||||
}
|
||||
Reference in new issue
Block a user