chore(vendor): import pi 1.3.0
Imported as a linear vendor commit so forge rebases do not replay the upstream root tree. git-subtree-dir: third_party/pi git-subtree-split: 71023aec1546d6d677a65669c5665c0927ce0dd0
This commit is contained in:
146
third_party/pi/packages/coding-agent/test/resource-loader-theme.test.ts
vendored
Normal file
146
third_party/pi/packages/coding-agent/test/resource-loader-theme.test.ts
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { resetCapabilitiesCache, setCapabilityOverrides } from "@earendil-works/pi-tui";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { DefaultResourceLoader } from "../src/core/resource-loader.ts";
|
||||
import { SettingsManager } from "../src/core/settings-manager.ts";
|
||||
import { setThemeJsonValidator } from "../src/modes/interactive/theme/theme.ts";
|
||||
import { validateThemeJson } from "../src/modes/interactive/theme/theme-schema.ts";
|
||||
|
||||
setThemeJsonValidator(validateThemeJson);
|
||||
|
||||
interface TestThemeJson {
|
||||
name: string;
|
||||
colors: Record<string, string | number>;
|
||||
unsupported?: boolean;
|
||||
}
|
||||
|
||||
describe("DefaultResourceLoader theme color mode", () => {
|
||||
let tempDir: string;
|
||||
let agentDir: string;
|
||||
let cwd: string;
|
||||
let themePath: string;
|
||||
let themeJson: TestThemeJson;
|
||||
|
||||
beforeEach(() => {
|
||||
tempDir = mkdtempSync(join(tmpdir(), "resource-loader-theme-"));
|
||||
agentDir = join(tempDir, "agent");
|
||||
cwd = join(tempDir, "project");
|
||||
mkdirSync(agentDir, { recursive: true });
|
||||
mkdirSync(cwd, { recursive: true });
|
||||
|
||||
themeJson = JSON.parse(
|
||||
readFileSync(join(process.cwd(), "src", "modes", "interactive", "theme", "dark.json"), "utf-8"),
|
||||
) as TestThemeJson;
|
||||
themeJson.name = "capability-test";
|
||||
themeJson.colors.userMessageBg = "#3c3544";
|
||||
themePath = join(tempDir, "capability-test.json");
|
||||
writeFileSync(themePath, JSON.stringify(themeJson));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllEnvs();
|
||||
setCapabilityOverrides({});
|
||||
resetCapabilitiesCache();
|
||||
rmSync(tempDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
// Regression test for #9973.
|
||||
it.each([
|
||||
{
|
||||
environment: "256-color",
|
||||
environmentOverride: "0",
|
||||
setting: true,
|
||||
expected: "\x1b[48;2;60;53;68mx\x1b[49m",
|
||||
},
|
||||
{
|
||||
environment: "truecolor",
|
||||
environmentOverride: "1",
|
||||
setting: false,
|
||||
expected: "\x1b[48;5;59mx\x1b[49m",
|
||||
},
|
||||
])(
|
||||
"uses the $setting setting over a $environment environment",
|
||||
async ({ environmentOverride, setting, expected }) => {
|
||||
vi.stubEnv("PI_TRUE_COLOR", environmentOverride);
|
||||
setCapabilityOverrides({});
|
||||
resetCapabilitiesCache();
|
||||
|
||||
const loader = new DefaultResourceLoader({
|
||||
cwd,
|
||||
agentDir,
|
||||
settingsManager: SettingsManager.inMemory({ terminal: { trueColor: setting } }),
|
||||
additionalThemePaths: [themePath],
|
||||
noExtensions: true,
|
||||
noSkills: true,
|
||||
noPromptTemplates: true,
|
||||
noContextFiles: true,
|
||||
});
|
||||
await loader.reload();
|
||||
|
||||
const loadedTheme = loader.getThemes().themes.find((theme) => theme.name === "capability-test");
|
||||
expect(loadedTheme?.bg("userMessageBg", "x")).toBe(expected);
|
||||
},
|
||||
);
|
||||
|
||||
it("returns to automatic detection after an explicit setting is removed", async () => {
|
||||
vi.stubEnv("PI_TRUE_COLOR", "1");
|
||||
setCapabilityOverrides({});
|
||||
resetCapabilitiesCache();
|
||||
|
||||
const settingsPath = join(agentDir, "settings.json");
|
||||
writeFileSync(settingsPath, JSON.stringify({ terminal: { trueColor: false } }));
|
||||
const settingsManager = SettingsManager.create(cwd, agentDir);
|
||||
const loader = new DefaultResourceLoader({
|
||||
cwd,
|
||||
agentDir,
|
||||
settingsManager,
|
||||
additionalThemePaths: [themePath],
|
||||
noExtensions: true,
|
||||
noSkills: true,
|
||||
noPromptTemplates: true,
|
||||
noContextFiles: true,
|
||||
});
|
||||
await loader.reload();
|
||||
setCapabilityOverrides(settingsManager.getTerminalCapabilityOverrides());
|
||||
|
||||
writeFileSync(settingsPath, "{}");
|
||||
await loader.reload();
|
||||
|
||||
const loadedTheme = loader.getThemes().themes.find((theme) => theme.name === "capability-test");
|
||||
expect(loadedTheme?.bg("userMessageBg", "x")).toBe("\x1b[48;2;60;53;68mx\x1b[49m");
|
||||
});
|
||||
|
||||
it("applies strict validation on initial load and reload", async () => {
|
||||
const loader = new DefaultResourceLoader({
|
||||
cwd,
|
||||
agentDir,
|
||||
settingsManager: SettingsManager.inMemory(),
|
||||
additionalThemePaths: [themePath],
|
||||
noExtensions: true,
|
||||
noSkills: true,
|
||||
noPromptTemplates: true,
|
||||
noContextFiles: true,
|
||||
});
|
||||
|
||||
themeJson.unsupported = true;
|
||||
writeFileSync(themePath, JSON.stringify(themeJson));
|
||||
await loader.reload();
|
||||
const initialDiagnostics = loader.getThemes().diagnostics;
|
||||
expect(initialDiagnostics).toHaveLength(1);
|
||||
expect(initialDiagnostics[0]).toMatchObject({ type: "warning", path: themePath });
|
||||
expect(initialDiagnostics[0]?.message).toContain("/unsupported");
|
||||
|
||||
delete themeJson.unsupported;
|
||||
writeFileSync(themePath, JSON.stringify(themeJson));
|
||||
await loader.reload();
|
||||
expect(loader.getThemes().diagnostics).toEqual([]);
|
||||
expect(loader.getThemes().themes.some((theme) => theme.name === themeJson.name)).toBe(true);
|
||||
|
||||
themeJson.unsupported = true;
|
||||
writeFileSync(themePath, JSON.stringify(themeJson));
|
||||
await loader.reload();
|
||||
expect(loader.getThemes().diagnostics).toEqual(initialDiagnostics);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user