Squashed 'third_party/pi/' content from commit d981de122
git-subtree-dir: third_party/pi git-subtree-split: d981de1229ef899957bbe968bc8dcda02a21f477
This commit is contained in:
141
packages/coding-agent/test/theme-controller.test.ts
Normal file
141
packages/coding-agent/test/theme-controller.test.ts
Normal file
@@ -0,0 +1,141 @@
|
||||
import type { TUI } from "@earendil-works/pi-tui";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { SettingsManager } from "../src/core/settings-manager.ts";
|
||||
import { initTheme, type TerminalTheme, theme } from "../src/modes/interactive/theme/theme.ts";
|
||||
import { InteractiveThemeController } from "../src/modes/interactive/theme/theme-controller.ts";
|
||||
|
||||
function createUi() {
|
||||
const queryTerminalBackgroundColor = vi.fn();
|
||||
const queryTerminalColorScheme = vi.fn();
|
||||
const setTerminalColorSchemeNotifications = vi.fn();
|
||||
let terminalColorSchemeListener: ((terminalTheme: TerminalTheme) => void) | undefined;
|
||||
const unsubscribeTerminalColorScheme = vi.fn();
|
||||
const ui = {
|
||||
invalidate: vi.fn(),
|
||||
requestRender: vi.fn(),
|
||||
setTerminalColorSchemeNotifications,
|
||||
onTerminalColorSchemeChange: vi.fn((listener: (terminalTheme: TerminalTheme) => void) => {
|
||||
terminalColorSchemeListener = listener;
|
||||
return unsubscribeTerminalColorScheme;
|
||||
}),
|
||||
queryTerminalBackgroundColor,
|
||||
queryTerminalColorScheme,
|
||||
} as unknown as TUI;
|
||||
return {
|
||||
ui,
|
||||
queryTerminalBackgroundColor,
|
||||
queryTerminalColorScheme,
|
||||
setTerminalColorSchemeNotifications,
|
||||
unsubscribeTerminalColorScheme,
|
||||
emitTerminalColorScheme: (terminalTheme: TerminalTheme) => terminalColorSchemeListener?.(terminalTheme),
|
||||
};
|
||||
}
|
||||
|
||||
function createController(ui: TUI, getSettingsManager: () => SettingsManager, initialThemeSetting?: string) {
|
||||
return new InteractiveThemeController(ui, {
|
||||
getSettingsManager,
|
||||
showError: vi.fn(),
|
||||
onChanged: vi.fn(),
|
||||
initialThemeSetting,
|
||||
});
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
initTheme("dark");
|
||||
vi.unstubAllEnvs();
|
||||
});
|
||||
|
||||
describe("InteractiveThemeController", () => {
|
||||
it("uses the initial theme without persisting it", async () => {
|
||||
const { ui, queryTerminalBackgroundColor } = createUi();
|
||||
const manager = SettingsManager.inMemory({ theme: "dark" });
|
||||
const setTheme = vi.spyOn(manager, "setTheme");
|
||||
const flush = vi.spyOn(manager, "flush");
|
||||
const controller = createController(ui, () => manager, "light");
|
||||
|
||||
expect(theme.name).toBe("light");
|
||||
expect(controller.getThemeSelection()).toBe("light");
|
||||
await controller.applyFromSettings();
|
||||
|
||||
expect(queryTerminalBackgroundColor).not.toHaveBeenCalled();
|
||||
expect(setTheme).not.toHaveBeenCalled();
|
||||
expect(flush).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("resolves a theme pair and follows terminal appearance changes", async () => {
|
||||
vi.stubEnv("COLORFGBG", "15;0");
|
||||
const { ui, queryTerminalColorScheme, setTerminalColorSchemeNotifications, emitTerminalColorScheme } = createUi();
|
||||
queryTerminalColorScheme.mockResolvedValue("light");
|
||||
const manager = SettingsManager.inMemory({ theme: "dark/light" });
|
||||
const controller = createController(ui, () => manager, "light/dark");
|
||||
|
||||
expect(theme.name).toBe("dark");
|
||||
await controller.applyFromSettings();
|
||||
expect(theme.name).toBe("light");
|
||||
expect(setTerminalColorSchemeNotifications).toHaveBeenCalledWith(true);
|
||||
|
||||
emitTerminalColorScheme("dark");
|
||||
expect(theme.name).toBe("dark");
|
||||
});
|
||||
|
||||
it("disables terminal appearance updates when disposed", async () => {
|
||||
const { ui, queryTerminalColorScheme, setTerminalColorSchemeNotifications, unsubscribeTerminalColorScheme } =
|
||||
createUi();
|
||||
queryTerminalColorScheme.mockResolvedValue("light");
|
||||
const manager = SettingsManager.inMemory({ theme: "light/dark" });
|
||||
const controller = createController(ui, () => manager);
|
||||
await controller.applyFromSettings();
|
||||
|
||||
controller.dispose();
|
||||
|
||||
expect(setTerminalColorSchemeNotifications).toHaveBeenLastCalledWith(false);
|
||||
expect(unsubscribeTerminalColorScheme).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("detects the current terminal appearance when selecting a theme pair", async () => {
|
||||
vi.stubEnv("COLORFGBG", "");
|
||||
const { ui, queryTerminalColorScheme } = createUi();
|
||||
queryTerminalColorScheme.mockResolvedValue("light");
|
||||
const manager = SettingsManager.inMemory({ theme: "dark" });
|
||||
const controller = createController(ui, () => manager);
|
||||
|
||||
expect(theme.name).toBe("dark");
|
||||
await controller.setThemeSetting("light/dark");
|
||||
expect(theme.name).toBe("light");
|
||||
expect(queryTerminalColorScheme).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("lets an explicit selection replace the initial theme", async () => {
|
||||
const { ui } = createUi();
|
||||
const firstManager = SettingsManager.inMemory({ theme: "dark" });
|
||||
const secondManager = SettingsManager.inMemory({ theme: "light" });
|
||||
let manager = firstManager;
|
||||
const controller = createController(ui, () => manager, "light");
|
||||
await controller.applyFromSettings();
|
||||
|
||||
expect(controller.setThemeName("dark")).toEqual({ success: true });
|
||||
manager = secondManager;
|
||||
await controller.applyFromSettings();
|
||||
|
||||
expect(controller.getThemeSelection()).toBe("dark");
|
||||
expect(theme.name).toBe("dark");
|
||||
});
|
||||
|
||||
it("reloads theme settings when no initial theme was supplied", async () => {
|
||||
const { ui } = createUi();
|
||||
const firstManager = SettingsManager.inMemory({ theme: "dark" });
|
||||
const secondManager = SettingsManager.inMemory({ theme: "light" });
|
||||
let manager = firstManager;
|
||||
const controller = createController(ui, () => manager);
|
||||
await controller.applyFromSettings();
|
||||
|
||||
firstManager.applyOverrides({ theme: "light" });
|
||||
await controller.applyFromSettings();
|
||||
expect(theme.name).toBe("light");
|
||||
|
||||
secondManager.applyOverrides({ theme: "dark" });
|
||||
manager = secondManager;
|
||||
await controller.applyFromSettings();
|
||||
expect(theme.name).toBe("dark");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user