76 lines
3.3 KiB
Swift
76 lines
3.3 KiB
Swift
import Testing
|
|
import AppKit
|
|
@testable import EdmundCore
|
|
|
|
@Suite("HTMLTheme — CSS emission")
|
|
@MainActor
|
|
struct HTMLThemeTests {
|
|
|
|
private func css(dark: Bool) -> String {
|
|
let theme = EditorTheme(fontName: "Iowan Old Style", fontSize: 16,
|
|
linkBlueHex: "#3366E6", codeHex: "#8A2425",
|
|
lineSpacing: 4, paragraphSpacingBefore: 2)
|
|
return HTMLTheme.css(theme, callouts: Callout.defaultStyles, dark: dark)
|
|
}
|
|
|
|
@Test("Derives custom properties from the theme")
|
|
func vars() {
|
|
let out = css(dark: false)
|
|
#expect(out.contains("--accent: #3366E6;"))
|
|
#expect(out.contains("--code: #8A2425;"))
|
|
#expect(out.contains("--body-size: 16px;"))
|
|
// 1.2 + 4/16 = 1.45
|
|
#expect(out.contains("--line-height: 1.45;"))
|
|
// Multi-word family is quoted with a fallback stack.
|
|
#expect(out.contains("\"Iowan Old Style\""))
|
|
}
|
|
|
|
@Test("Reading column max-width matches the editor's physical cap; uncapped by default")
|
|
func pageMaxWidth() {
|
|
let theme = EditorTheme(fontName: "Iowan Old Style", fontSize: 16,
|
|
linkBlueHex: "#3366E6", codeHex: "#8A2425",
|
|
lineSpacing: 4, paragraphSpacingBefore: 2)
|
|
let capped = HTMLTheme.css(theme, callouts: Callout.defaultStyles, dark: false,
|
|
maxContentWidthPoints: 340)
|
|
#expect(capped.contains("--page-max-width: 340px;"))
|
|
|
|
let uncapped = HTMLTheme.css(theme, callouts: Callout.defaultStyles, dark: false)
|
|
#expect(uncapped.contains("--page-max-width: none;"))
|
|
}
|
|
|
|
@Test("Emits per-callout-type colors with derived rgba background")
|
|
func calloutVars() {
|
|
let out = css(dark: false)
|
|
#expect(out.contains(".callout-note {"))
|
|
#expect(out.contains("--c-accent: #086DDD;"))
|
|
// note's background is derived from the accent at backgroundAlpha 0.08.
|
|
#expect(out.contains("rgba(8, 109, 221, 0.08)"))
|
|
}
|
|
|
|
@Test("Dark appearance picks dark color variants")
|
|
func darkVariant() {
|
|
// 'caution' has darkColorHex #F85149.
|
|
#expect(css(dark: true).contains("--c-accent: #F85149;"))
|
|
#expect(css(dark: false).contains("--c-accent: #CF222E;"))
|
|
#expect(css(dark: true).contains("--bg: #1e1e1e;"))
|
|
}
|
|
|
|
@Test("Wide tables scroll horizontally instead of wrapping cell text")
|
|
func tableScrolls() {
|
|
let out = css(dark: false)
|
|
#expect(out.contains(".table-wrap { overflow-x: auto; margin: 1em 0; }"))
|
|
#expect(!out.contains("overflow-wrap"))
|
|
}
|
|
|
|
@Test("Emits code token colors from the shared palette, per appearance")
|
|
func codeTokenColors() {
|
|
let light = css(dark: false)
|
|
#expect(light.contains("pre code .tok-keyword { color: \(CodeSyntaxPalette.hex(.keyword, dark: false)); }"))
|
|
#expect(light.contains("pre code { color: \(CodeSyntaxPalette.hex(nil, dark: false)); }"))
|
|
let dark = css(dark: true)
|
|
#expect(dark.contains("pre code .tok-string { color: \(CodeSyntaxPalette.hex(.string, dark: true)); }"))
|
|
// The palettes differ between appearances.
|
|
#expect(CodeSyntaxPalette.hex(.keyword, dark: false) != CodeSyntaxPalette.hex(.keyword, dark: true))
|
|
}
|
|
}
|