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
160 lines
5.9 KiB
TypeScript
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');
|
|
});
|
|
});
|