Migrate core render util to use xterm.js as part of the rendering loop. (#19044)

This commit is contained in:
Jacob Richman
2026-02-18 16:46:50 -08:00
committed by GitHub
parent 04c52513e7
commit 04f65f3d55
213 changed files with 7065 additions and 3852 deletions
@@ -17,13 +17,17 @@ const mockUnsubscribe = vi.fn();
const mockHandleThemeSelect = vi.fn();
const mockQueryTerminalBackground = vi.fn();
vi.mock('ink', async () => ({
useStdout: () => ({
stdout: {
write: mockWrite,
},
}),
}));
vi.mock('ink', async (importOriginal) => {
const actual = await importOriginal<typeof import('ink')>();
return {
...actual,
useStdout: () => ({
stdout: {
write: mockWrite,
},
}),
};
});
vi.mock('../contexts/TerminalContext.js', () => ({
useTerminalContext: () => ({
@@ -47,8 +51,9 @@ vi.mock('../contexts/SettingsContext.js', () => ({
useSettings: () => mockSettings,
}));
vi.mock('../themes/theme-manager.js', async () => {
const actual = await vi.importActual('../themes/theme-manager.js');
vi.mock('../themes/theme-manager.js', async (importOriginal) => {
const actual =
await importOriginal<typeof import('../themes/theme-manager.js')>();
return {
...actual,
themeManager: {
@@ -91,36 +96,46 @@ describe('useTerminalTheme', () => {
});
it('should subscribe to terminal background events on mount', () => {
renderHook(() => useTerminalTheme(mockHandleThemeSelect, config, vi.fn()));
expect(mockSubscribe).toHaveBeenCalled();
});
it('should unsubscribe on unmount', () => {
const { unmount } = renderHook(() =>
useTerminalTheme(mockHandleThemeSelect, config, vi.fn()),
);
expect(mockSubscribe).toHaveBeenCalled();
unmount();
});
it('should unsubscribe on unmount', async () => {
const { unmount, waitUntilReady } = renderHook(() =>
useTerminalTheme(mockHandleThemeSelect, config, vi.fn()),
);
await waitUntilReady();
unmount();
expect(mockUnsubscribe).toHaveBeenCalled();
});
it('should poll for terminal background', () => {
renderHook(() => useTerminalTheme(mockHandleThemeSelect, config, vi.fn()));
const { unmount } = renderHook(() =>
useTerminalTheme(mockHandleThemeSelect, config, vi.fn()),
);
vi.advanceTimersByTime(60000);
expect(mockQueryTerminalBackground).toHaveBeenCalled();
unmount();
});
it('should not poll if terminal background is undefined at startup', () => {
it('should not poll if terminal background is undefined at startup', async () => {
config.getTerminalBackground = vi.fn().mockReturnValue(undefined);
renderHook(() => useTerminalTheme(mockHandleThemeSelect, config, vi.fn()));
const { unmount } = renderHook(() =>
useTerminalTheme(mockHandleThemeSelect, config, vi.fn()),
);
vi.advanceTimersByTime(60000);
expect(mockQueryTerminalBackground).not.toHaveBeenCalled();
unmount();
});
it('should switch to light theme when background is light and not call refreshStatic directly', () => {
const refreshStatic = vi.fn();
renderHook(() =>
const { unmount } = renderHook(() =>
useTerminalTheme(mockHandleThemeSelect, config, refreshStatic),
);
@@ -135,6 +150,7 @@ describe('useTerminalTheme', () => {
'default-light',
expect.anything(),
);
unmount();
});
it('should switch to dark theme when background is dark', () => {
@@ -143,7 +159,7 @@ describe('useTerminalTheme', () => {
config.setTerminalBackground('#ffffff');
const refreshStatic = vi.fn();
renderHook(() =>
const { unmount } = renderHook(() =>
useTerminalTheme(mockHandleThemeSelect, config, refreshStatic),
);
@@ -160,6 +176,7 @@ describe('useTerminalTheme', () => {
);
mockSettings.merged.ui.theme = 'default';
unmount();
});
it('should not update config or call refreshStatic on repeated identical background reports', () => {
@@ -181,11 +198,14 @@ describe('useTerminalTheme', () => {
it('should not switch theme if autoThemeSwitching is disabled', () => {
mockSettings.merged.ui.autoThemeSwitching = false;
renderHook(() => useTerminalTheme(mockHandleThemeSelect, config, vi.fn()));
const { unmount } = renderHook(() =>
useTerminalTheme(mockHandleThemeSelect, config, vi.fn()),
);
vi.advanceTimersByTime(60000);
expect(mockQueryTerminalBackground).not.toHaveBeenCalled();
mockSettings.merged.ui.autoThemeSwitching = true;
unmount();
});
});