import { describe, expect, it } from "vite-plus/test"; import { DEFAULT_BASE_FONT_SIZE, normalizeBaseFontSize, resolveAppearance, resolveAppearancePreferences, resolveMarkdownFontSizes, resolveMobileCodeSurface, resolveNativeMarkdownTypography, resolveTextScaleVariables, stepTerminalFontSize,} from "./appearancePreferences"; describe("appearancePreferences", () => { it("resolves defaults for empty stored preferences", () => { expect(resolveAppearancePreferences({})).toEqual({ baseFontSize: DEFAULT_BASE_FONT_SIZE, terminalFontSize: null, codeFontSize: null, codeWordBreak: false, }); }); it("migrates the legacy markdownFontSize key to baseFontSize", () => { expect(resolveAppearancePreferences({ markdownFontSize: 18 }).baseFontSize).toBe(18); expect( resolveAppearancePreferences({ baseFontSize: 16, markdownFontSize: 18 }).baseFontSize, ).toBe(16); }); it("keeps explicit overrides and treats missing values as automatic", () => { const preferences = resolveAppearancePreferences({ terminalFontSize: 12, codeFontSize: 14 }); expect(preferences.terminalFontSize).toBe(12); expect(preferences.codeFontSize).toBe(14); expect(resolveAppearancePreferences({ terminalFontSize: null }).terminalFontSize).toBe(null); }); it("derives terminal and code sizes from the base size when not overridden", () => { const appearance = resolveAppearance(resolveAppearancePreferences({ baseFontSize: 15 })); expect(appearance.terminalFontSize).toBe(10); expect(appearance.codeFontSize).toBe(11); expect(appearance.isTerminalFontSizeCustom).toBe(false); expect(appearance.isCodeFontSizeCustom).toBe(false); const scaled = resolveAppearance(resolveAppearancePreferences({ baseFontSize: 22 })); expect(scaled.terminalFontSize).toBe(14); expect(scaled.codeFontSize).toBe(17); }); it("applies explicit overrides over derived values", () => { const appearance = resolveAppearance( resolveAppearancePreferences({ baseFontSize: 22, terminalFontSize: 8, codeFontSize: 9 }), ); expect(appearance.terminalFontSize).toBe(8); expect(appearance.codeFontSize).toBe(9); expect(appearance.isTerminalFontSizeCustom).toBe(true); expect(appearance.isCodeFontSizeCustom).toBe(true); }); it("clamps base and code font sizes", () => { expect(normalizeBaseFontSize(4)).toBe(11); expect(normalizeBaseFontSize(30)).toBe(22); expect(resolveAppearancePreferences({ codeFontSize: 4 }).codeFontSize).toBe(8); expect(resolveAppearancePreferences({ codeFontSize: 30 }).codeFontSize).toBe(18); }); it("steps terminal font size within bounds", () => { expect(stepTerminalFontSize(6, -1)).toBe(6); }); it("scales markdown typography from the base size", () => { expect(resolveMarkdownFontSizes(15)).toMatchObject({ m: 15, h1: 20, bodyLineHeight: 22, codeBlockFontSize: 12, codeBlockLineHeight: 18, }); }); it("scales code surface geometry from the code font size", () => { expect(resolveMobileCodeSurface(11)).toMatchObject({ fontSize: 11, rowHeight: 20, }); }); it("keeps explicit code word break enabled", () => { expect(resolveAppearancePreferences({ codeWordBreak: true }).codeWordBreak).toBe(true); }); it("returns the authored text scale at the 16pt default", () => { expect(DEFAULT_BASE_FONT_SIZE).toBe(16); const variables = resolveTextScaleVariables(DEFAULT_BASE_FONT_SIZE); expect(variables["--text-base"]).toBe(16); expect(variables["--text-base--line-height"]).toBe(23); expect(variables["--text-sm"]).toBe(14); expect(variables["--text-sm--line-height"]).toBe(19); expect(variables["--text-lg"]).toBe(18); expect(variables["--text-3xl"]).toBe(30); }); it("scales every text variable proportionally with the base size", () => { const smallerVariables = resolveTextScaleVariables(15); expect(smallerVariables["--text-base"]).toBe(15); expect(smallerVariables["--text-sm"]).toBe(13); const variables = resolveTextScaleVariables(20); expect(variables["--text-base"]).toBe(20); expect(variables["--text-base--line-height"]).toBe(29); expect(variables["--text-sm"]).toBe(18); expect(variables["--text-xs"]).toBe(16); expect(variables["--text-lg"]).toBe(23); const smaller = resolveTextScaleVariables(11); expect(smaller["--text-base"]).toBe(11); expect(smaller["--text-3xs"]).toBeGreaterThanOrEqual(8); expect(smaller["--text-3xs--line-height"]).toBeGreaterThanOrEqual(10); }); it("derives native markdown typography from the base size", () => { expect(resolveNativeMarkdownTypography(22)).toEqual({ fontSize: 22, lineHeight: 32, headingFontSizes: [29, 26, 23, 21, 21, 21], }); });});
import { describe, expect, it } from "vite-plus/test";
import {
DEFAULT_BASE_FONT_SIZE,
normalizeBaseFontSize,
resolveAppearance,
resolveAppearancePreferences,
resolveMarkdownFontSizes,
resolveMobileCodeSurface,
resolveNativeMarkdownTypography,
resolveTextScaleVariables,
stepTerminalFontSize,
} from "./appearancePreferences";
describe("appearancePreferences", () => {
it("resolves defaults for empty stored preferences", () => {
expect(resolveAppearancePreferences({})).toEqual({
baseFontSize: DEFAULT_BASE_FONT_SIZE,
terminalFontSize: null,
codeFontSize: null,
codeWordBreak: false,
});
});
it("migrates the legacy markdownFontSize key to baseFontSize", () => {
expect(resolveAppearancePreferences({ markdownFontSize: 18 }).baseFontSize).toBe(18);
expect(
resolveAppearancePreferences({ baseFontSize: 16, markdownFontSize: 18 }).baseFontSize,
).toBe(16);
});
it("keeps explicit overrides and treats missing values as automatic", () => {
const preferences = resolveAppearancePreferences({ terminalFontSize: 12, codeFontSize: 14 });
expect(preferences.terminalFontSize).toBe(12);
expect(preferences.codeFontSize).toBe(14);
expect(resolveAppearancePreferences({ terminalFontSize: null }).terminalFontSize).toBe(null);
});
it("derives terminal and code sizes from the base size when not overridden", () => {
const appearance = resolveAppearance(resolveAppearancePreferences({ baseFontSize: 15 }));
expect(appearance.terminalFontSize).toBe(10);
expect(appearance.codeFontSize).toBe(11);
expect(appearance.isTerminalFontSizeCustom).toBe(false);
expect(appearance.isCodeFontSizeCustom).toBe(false);
const scaled = resolveAppearance(resolveAppearancePreferences({ baseFontSize: 22 }));
expect(scaled.terminalFontSize).toBe(14);
expect(scaled.codeFontSize).toBe(17);
});
it("applies explicit overrides over derived values", () => {
const appearance = resolveAppearance(
resolveAppearancePreferences({ baseFontSize: 22, terminalFontSize: 8, codeFontSize: 9 }),
);
expect(appearance.terminalFontSize).toBe(8);
expect(appearance.codeFontSize).toBe(9);
expect(appearance.isTerminalFontSizeCustom).toBe(true);
expect(appearance.isCodeFontSizeCustom).toBe(true);
});
it("clamps base and code font sizes", () => {
expect(normalizeBaseFontSize(4)).toBe(11);
expect(normalizeBaseFontSize(30)).toBe(22);
expect(resolveAppearancePreferences({ codeFontSize: 4 }).codeFontSize).toBe(8);
expect(resolveAppearancePreferences({ codeFontSize: 30 }).codeFontSize).toBe(18);
});
it("steps terminal font size within bounds", () => {
expect(stepTerminalFontSize(6, -1)).toBe(6);
});
it("scales markdown typography from the base size", () => {
expect(resolveMarkdownFontSizes(15)).toMatchObject({
m: 15,
h1: 20,
bodyLineHeight: 22,
codeBlockFontSize: 12,
codeBlockLineHeight: 18,
});
});
it("scales code surface geometry from the code font size", () => {
expect(resolveMobileCodeSurface(11)).toMatchObject({
fontSize: 11,
rowHeight: 20,
});
});
it("keeps explicit code word break enabled", () => {
expect(resolveAppearancePreferences({ codeWordBreak: true }).codeWordBreak).toBe(true);
});
it("returns the authored text scale at the 16pt default", () => {
expect(DEFAULT_BASE_FONT_SIZE).toBe(16);
const variables = resolveTextScaleVariables(DEFAULT_BASE_FONT_SIZE);
expect(variables["--text-base"]).toBe(16);
expect(variables["--text-base--line-height"]).toBe(23);
expect(variables["--text-sm"]).toBe(14);
expect(variables["--text-sm--line-height"]).toBe(19);
expect(variables["--text-lg"]).toBe(18);
expect(variables["--text-3xl"]).toBe(30);
});
it("scales every text variable proportionally with the base size", () => {
const smallerVariables = resolveTextScaleVariables(15);
expect(smallerVariables["--text-base"]).toBe(15);
expect(smallerVariables["--text-sm"]).toBe(13);
const variables = resolveTextScaleVariables(20);
expect(variables["--text-base"]).toBe(20);
expect(variables["--text-base--line-height"]).toBe(29);
expect(variables["--text-sm"]).toBe(18);
expect(variables["--text-xs"]).toBe(16);
expect(variables["--text-lg"]).toBe(23);
const smaller = resolveTextScaleVariables(11);
expect(smaller["--text-base"]).toBe(11);
expect(smaller["--text-3xs"]).toBeGreaterThanOrEqual(8);
expect(smaller["--text-3xs--line-height"]).toBeGreaterThanOrEqual(10);
});
it("derives native markdown typography from the base size", () => {
expect(resolveNativeMarkdownTypography(22)).toEqual({
fontSize: 22,
lineHeight: 32,
headingFontSizes: [29, 26, 23, 21, 21, 21],
});
});
});