mana-swift-core/Tests/ManaTokensTests/FontTests.swift
Till JS 9ee01d97e5 feat(ManaTokens): Marken-Schriften nativ (Inter/Source Serif 4/JetBrains Mono)
Bündelt die selbst-gehosteten Variable-TTFs des Vereins (OFL, glyphengleich
zum Web-@mana/themes) + registriert sie idempotent bei CoreText. Neu:
ManaFonts (Registrierung, Familien-Namen per Test verifiziert) und
ManaBrandTypography (spiegelt ManaTypography in den Marken-Schriften,
Dynamic-Type-gekoppelt). Additiv + opt-in — System-SF bleibt Default.

Fonts liegen in ManaTokens (~4 MB pro Konsument); eigenes opt-in-Product
ist die Alternative, falls zu schwer. Kein Tag bis Struktur-Entscheidung.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 17:10:35 +02:00

52 lines
2.1 KiB
Swift

import CoreText
import Foundation
import Testing
@testable import ManaTokens
@Suite("ManaFonts — Bundling & Registrierung")
struct FontTests {
/// Liest den Familien-Namen direkt aus einer gebündelten TTF (vor jeder
/// Registrierung), damit wir wissen, worauf `Font.custom(...)` matchen muss.
private func familyName(ofResource name: String) -> String? {
guard let url = Bundle.module.url(forResource: name, withExtension: "ttf"),
let descs = CTFontManagerCreateFontDescriptorsFromURL(url as CFURL) as? [CTFontDescriptor],
let first = descs.first,
let family = CTFontDescriptorCopyAttribute(first, kCTFontFamilyNameAttribute) as? String
else { return nil }
return family
}
@Test("Alle fünf Variable-TTFs liegen im Bundle")
func fontsArePresent() {
for name in [
"InterVariable", "InterVariable-Italic",
"SourceSerif4Variable", "SourceSerif4Variable-Italic",
"JetBrainsMonoVariable",
] {
#expect(Bundle.module.url(forResource: name, withExtension: "ttf") != nil)
}
}
@Test("Familien-Namen matchen die ManaFonts-Konstanten (= Web-@font-face)")
func familyNamesMatchConstants() {
#expect(familyName(ofResource: "InterVariable") == ManaFonts.sans)
#expect(familyName(ofResource: "SourceSerif4Variable") == ManaFonts.serif)
#expect(familyName(ofResource: "JetBrainsMonoVariable") == ManaFonts.mono)
}
@Test("Registrierung ist idempotent und wirft nicht")
func registrationIsIdempotent() {
ManaFonts.register()
ManaFonts.register()
// Nach Registrierung muss CoreText die Familie kennen.
let names = CTFontManagerCopyAvailablePostScriptNames() as? [String] ?? []
#expect(!names.isEmpty)
}
@Test("OFL-Lizenztexte sind mitgeliefert")
func licensesBundled() {
for fam in ["inter", "sourceserif4", "jetbrainsmono"] {
#expect(Bundle.module.url(forResource: "OFL-\(fam)", withExtension: "txt") != nil)
}
}
}