The DESIGN.md type standard needs the fonts actually present — the machine's installed faces are not a design system. Four Inter weights (400/500/600/700) and two JetBrains Mono weights (500/600) ship as WPF resources from Assets/Fonts; the token families resolve them with the `/Assets/Fonts/#Family` pack form, so nothing depends on an install or a network fetch. Licensing (recorded in docs/ai/product.md): OFL-1.1 is a free licence but is NOT GPL-compatible in the linking sense. These are separate .ttf files loaded through WPF's font stack — an aggregate, not linked code — so they coexist with the GPL-3.0 app. Obligations carried: copyright line in THIRD-PARTY-NOTICES.txt (new items 13-14), the OFL text beside the files (Assets/Fonts/OFL-*.txt), no modification, no reserved-name reuse. Guard: BundledFontsTests — files exist and are real binaries, the csproj ships them, the theme uses pack URIs (a bare family name would silently fall back), the notice and both OFL texts are present, and no third font family sneaks in. Pending visual confirmation: the first launch should render panel text in Inter and telemetry in JetBrains Mono.
62 lines
2.7 KiB
C#
62 lines
2.7 KiB
C#
using System.IO;
|
|
using System.Linq;
|
|
using Xunit;
|
|
|
|
namespace ytLive.Tests;
|
|
|
|
/// <summary>The DESIGN.md type standard names Inter and JetBrains Mono, and the creator ruled
|
|
/// (2026-10-30) that they ship with the app rather than depending on what the machine happens to
|
|
/// have installed. That makes them third-party assets with obligations, so this guard covers the
|
|
/// whole chain: the files are present and unmodified, the project ships them as resources, the
|
|
/// theme resolves them from the pack folder, and the OFL notice + license text travel with them.
|
|
///
|
|
/// <para>A missing font would otherwise fail silently — WPF falls back to a system face and the
|
|
/// design standard quietly stops being true.</para></summary>
|
|
public class BundledFontsTests
|
|
{
|
|
private static readonly string[] Files =
|
|
{
|
|
"Inter-Regular.ttf", "Inter-Medium.ttf", "Inter-SemiBold.ttf", "Inter-Bold.ttf",
|
|
"JetBrainsMono-Medium.ttf", "JetBrainsMono-SemiBold.ttf",
|
|
};
|
|
|
|
[Fact]
|
|
public void The_standard_typefaces_ship_bundled_with_their_OFL_notice()
|
|
{
|
|
// 1. The files are there and are real font binaries, not placeholders.
|
|
foreach (var name in Files)
|
|
{
|
|
var path = SourceAssert.RepoPath("Assets", "Fonts", name);
|
|
Assert.True(new FileInfo(path).Length > 50_000, $"{name} looks like a placeholder");
|
|
}
|
|
|
|
// 2. The project packages them as WPF resources.
|
|
Assert.Contains(@"Assets\Fonts\*.ttf", SourceAssert.Text("ytLive.csproj"));
|
|
|
|
// 3. The theme resolves each family from the pack folder — a bare family name would
|
|
// only work if the user happened to have the font installed.
|
|
var tokens = SourceAssert.Text("Themes", "Tokens.xaml");
|
|
Assert.Contains("/Assets/Fonts/#Inter", tokens);
|
|
Assert.Contains("/Assets/Fonts/#JetBrains Mono", tokens);
|
|
|
|
// 4. The OFL obligations: notice in THIRD-PARTY-NOTICES.txt, license text beside the files.
|
|
var notices = SourceAssert.Text("THIRD-PARTY-NOTICES.txt");
|
|
Assert.Contains("Inter", notices);
|
|
Assert.Contains("JetBrains Mono", notices);
|
|
Assert.Contains("SIL Open Font License 1.1", notices);
|
|
|
|
foreach (var ofl in new[] { "OFL-Inter.txt", "OFL-JetBrainsMono.txt" })
|
|
{
|
|
var text = SourceAssert.Text("Assets", "Fonts", ofl);
|
|
Assert.Contains("SIL OPEN FONT LICENSE", text);
|
|
}
|
|
|
|
// 5. No other font family sneaks in through the token sheet.
|
|
var families = SourceAssert.Text("Themes", "Tokens.xaml")
|
|
.Split('\n')
|
|
.Where(l => l.Contains("FontFamily x:Key=", System.StringComparison.Ordinal))
|
|
.ToList();
|
|
Assert.Equal(2, families.Count);
|
|
}
|
|
}
|