Files
NetMesh/infrastructure/config/fonts.test.ts
zhaolei 3c72efcb7f
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
[Init] Initial commit - NetMesh terminal manager
2026-09-13 18:24:01 +08:00

160 lines
5.9 KiB
TypeScript

import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import {
TERMINAL_FONTS,
getDefaultTerminalFontIdForPlatform,
detectFontPlatform,
resolveTerminalFontFamilyId,
isSameResolvedTerminalFont,
TERMINAL_FONT_AUTO,
} from './fonts';
/**
* Proportional (non-monospace) fonts must never appear in the terminal
* primary font dropdown. They produce broken cell-grid alignment because
* xterm.js samples cell width from a single probe glyph, and a font with
* variable-width Latin glyphs renders other characters with inconsistent
* widths around (or beyond) that cell.
*/
const KNOWN_PROPORTIONAL_FONTS = [
// CJK system fonts — proportional sans-serif designed for body text.
'PingFang SC',
'PingFang TC',
'PingFang HK',
'Microsoft YaHei',
'Microsoft YaHei UI',
'Hiragino Sans GB',
'Hiragino Sans',
'Heiti SC',
'Heiti TC',
// Latin proportional fonts that get mistakenly listed as "terminal
// fonts". Comic Sans MS was historically in this dropdown labeled
// "non-traditional terminal font" — picking it produced bloated cell
// widths because Comic Sans is a handwriting-style proportional face.
'Comic Sans MS',
'Arial',
'Helvetica',
'Times New Roman',
'Times',
'Georgia',
'Verdana',
'Trebuchet MS',
'Tahoma',
];
describe('TERMINAL_FONTS dropdown contents', () => {
it('does not list any known proportional font as a primary choice', () => {
for (const banned of KNOWN_PROPORTIONAL_FONTS) {
const matches = TERMINAL_FONTS.filter((f) =>
f.name === banned ||
f.family.includes(`"${banned}"`) ||
f.family.split(',')[0].trim() === banned,
);
assert.deepEqual(
matches,
[],
`${banned} must not appear in TERMINAL_FONTS — it is proportional and breaks terminal grid alignment`,
);
}
});
it('every entry has a non-empty id, name, and family', () => {
for (const font of TERMINAL_FONTS) {
assert.ok(font.id.length > 0, `${JSON.stringify(font)} missing id`);
assert.ok(font.name.length > 0, `${font.id} missing name`);
assert.ok(font.family.length > 0, `${font.id} missing family`);
}
});
it('font ids are unique', () => {
const seen = new Set<string>();
for (const font of TERMINAL_FONTS) {
assert.equal(seen.has(font.id), false, `duplicate id: ${font.id}`);
seen.add(font.id);
}
});
});
describe('getDefaultTerminalFontIdForPlatform', () => {
it('uses a locally-installed Windows font (no webfont swap on cold start)', () => {
assert.equal(getDefaultTerminalFontIdForPlatform('win32'), 'consolas');
});
it('uses the most widely pre-installed Linux monospace font', () => {
assert.equal(getDefaultTerminalFontIdForPlatform('linux'), 'dejavu-sans-mono');
});
it('keeps the macOS system font default', () => {
assert.equal(getDefaultTerminalFontIdForPlatform('darwin'), 'menlo');
});
it('falls back to the macOS default for unknown platforms', () => {
assert.equal(getDefaultTerminalFontIdForPlatform('freebsd'), 'menlo');
});
it('only ever returns ids that exist in TERMINAL_FONTS', () => {
const ids = new Set(TERMINAL_FONTS.map((f) => f.id));
for (const platform of ['darwin', 'win32', 'linux', 'unknown']) {
assert.ok(
ids.has(getDefaultTerminalFontIdForPlatform(platform)),
`default for ${platform} not in TERMINAL_FONTS`,
);
}
});
});
describe('resolveTerminalFontFamilyId', () => {
it('resolves the auto sentinel to the per-platform default', () => {
assert.equal(resolveTerminalFontFamilyId(TERMINAL_FONT_AUTO, 'Win32'), 'consolas');
assert.equal(resolveTerminalFontFamilyId(TERMINAL_FONT_AUTO, 'MacIntel'), 'menlo');
assert.equal(resolveTerminalFontFamilyId(TERMINAL_FONT_AUTO, 'Linux x86_64'), 'dejavu-sans-mono');
});
it('treats empty/nullish ids as auto (resolves per platform)', () => {
assert.equal(resolveTerminalFontFamilyId('', 'Win32'), 'consolas');
assert.equal(resolveTerminalFontFamilyId(null, 'MacIntel'), 'menlo');
assert.equal(resolveTerminalFontFamilyId(undefined, 'Linux'), 'dejavu-sans-mono');
});
it('keeps an explicit font id regardless of platform', () => {
assert.equal(resolveTerminalFontFamilyId('jetbrains-mono', 'Win32'), 'jetbrains-mono');
assert.equal(resolveTerminalFontFamilyId('menlo', 'Win32'), 'menlo');
});
});
describe('isSameResolvedTerminalFont', () => {
it('treats clicking the displayed default while stored=auto as a no-op', () => {
// Prevents the side panel from pinning a concrete per-OS font (which would
// then sync across devices) on a no-op-looking click of the shown default.
assert.equal(isSameResolvedTerminalFont('consolas', TERMINAL_FONT_AUTO, 'Win32'), true);
assert.equal(isSameResolvedTerminalFont('menlo', TERMINAL_FONT_AUTO, 'MacIntel'), true);
assert.equal(isSameResolvedTerminalFont('dejavu-sans-mono', TERMINAL_FONT_AUTO, 'Linux'), true);
});
it('reports a real change when a different font is selected', () => {
assert.equal(isSameResolvedTerminalFont('jetbrains-mono', TERMINAL_FONT_AUTO, 'Win32'), false);
});
it('compares concrete ids directly', () => {
assert.equal(isSameResolvedTerminalFont('fira-code', 'fira-code', 'Win32'), true);
assert.equal(isSameResolvedTerminalFont('fira-code', 'menlo', 'Win32'), false);
});
});
describe('detectFontPlatform', () => {
it('maps navigator.platform Windows values to win32', () => {
assert.equal(detectFontPlatform('Win32'), 'win32');
assert.equal(detectFontPlatform('Windows'), 'win32');
});
it('maps macOS and iOS values to darwin', () => {
assert.equal(detectFontPlatform('MacIntel'), 'darwin');
assert.equal(detectFontPlatform('iPhone'), 'darwin');
});
it('treats everything else (incl. Linux) as linux', () => {
assert.equal(detectFontPlatform('Linux x86_64'), 'linux');
assert.equal(detectFontPlatform(''), 'linux');
});
});