Download src/agents/modes/interactive/theme/theme.test.ts from SaylorTwift/openclaw: direct link, hf CLI and curl.
- Browser
- Download file 4.28 kB
-
https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/agents/modes/interactive/theme/theme.test.ts
- Command line
-
hf download hf://SaylorTwift/openclaw/src/agents/modes/interactive/theme/theme.test.ts
-
curl -L -o theme.test.ts https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/agents/modes/interactive/theme/theme.test.ts
4.28 kB
| import { writeFileSync } from "node:fs"; | |
| import { join } from "node:path"; | |
| import { afterEach, describe, expect, it } from "vitest"; | |
| import { useAutoCleanupTempDirTracker } from "../../../../../test/helpers/temp-dir.js"; | |
| import darkTheme from "./dark.json" with { type: "json" }; | |
| import { loadThemeFromPath } from "./theme.js"; | |
| const tempDirs = useAutoCleanupTempDirTracker(afterEach); | |
| function loadColor(color: string | number, mode: "256color" | "truecolor") { | |
| const themePath = join(tempDirs.make("openclaw-theme-"), "theme.json"); | |
| writeFileSync( | |
| themePath, | |
| JSON.stringify({ | |
| ...darkTheme, | |
| colors: { ...darkTheme.colors, accent: color, selectedBg: color }, | |
| }), | |
| ); | |
| return loadThemeFromPath(themePath, mode); | |
| } | |
| describe("loadThemeFromPath", () => { | |
| it.each([ | |
| ["#0000ff", 21], | |
| ["#2f00ff", 21], | |
| ["#3000ff", 57], | |
| ["#7200ff", 57], | |
| ["#7300ff", 57], | |
| ["#7400ff", 93], | |
| ["#9a00ff", 93], | |
| ["#9b00ff", 93], | |
| ["#9c00ff", 129], | |
| ["#c200ff", 129], | |
| ["#c300ff", 129], | |
| ["#c400ff", 165], | |
| ["#ea00ff", 165], | |
| ["#eb00ff", 165], | |
| ["#ec00ff", 201], | |
| ["#ff00ff", 201], | |
| ["#ff7200", 202], | |
| ["#ff7300", 202], | |
| ["#ff7400", 208], | |
| ["#00ff72", 47], | |
| ["#00ff73", 47], | |
| ["#00ff74", 48], | |
| ["#5f87af", 67], | |
| ["#000000", 16], | |
| ["#040404", 16], | |
| ["#050505", 232], | |
| ["#080808", 232], | |
| ["#0c0c0c", 232], | |
| ["#0d0d0d", 232], | |
| ["#0e0e0e", 233], | |
| ["#707070", 242], | |
| ["#717171", 242], | |
| ["#727272", 243], | |
| ["#e8e8e8", 254], | |
| ["#e9e9e9", 254], | |
| ["#eaeaea", 255], | |
| ["#eeeeee", 255], | |
| ["#ffffff", 231], | |
| ["#606060", 59], | |
| ["#616161", 241], | |
| ["#0c0d0e", 232], | |
| ["#0d0d16", 233], | |
| ["#0d0d17", 16], | |
| ])( | |
| "renders %s as palette index %i with separate foreground/background resets", | |
| (color, index) => { | |
| const theme = loadColor(color, "256color"); | |
| expect(theme.fg("accent", "text")).toBe(`\x1b[38;5;${index}mtext\x1b[39m`); | |
| expect(theme.bg("selectedBg", "text")).toBe(`\x1b[48;5;${index}mtext\x1b[49m`); | |
| }, | |
| ); | |
| it("preserves RGB channels in truecolor output", () => { | |
| const theme = loadColor("#5f87af", "truecolor"); | |
| expect(theme.getFgAnsi("accent")).toBe("\x1b[38;2;95;135;175m"); | |
| expect(theme.getBgAnsi("selectedBg")).toBe("\x1b[48;2;95;135;175m"); | |
| expect(theme.fg("accent", "text")).toBe("\x1b[38;2;95;135;175mtext\x1b[39m"); | |
| expect(theme.bg("selectedBg", "text")).toBe("\x1b[48;2;95;135;175mtext\x1b[49m"); | |
| }); | |
| it.each(["256color", "truecolor"] as const)( | |
| "preserves numeric and reset colors in %s", | |
| (mode) => { | |
| for (const index of [0, 123, 255]) { | |
| const theme = loadColor(index, mode); | |
| expect(theme.getFgAnsi("accent")).toBe(`\x1b[38;5;${index}m`); | |
| expect(theme.getBgAnsi("selectedBg")).toBe(`\x1b[48;5;${index}m`); | |
| expect(theme.fg("accent", "text")).toBe(`\x1b[38;5;${index}mtext\x1b[39m`); | |
| expect(theme.bg("selectedBg", "text")).toBe(`\x1b[48;5;${index}mtext\x1b[49m`); | |
| } | |
| const reset = loadColor("", mode); | |
| expect(reset.getFgAnsi("accent")).toBe("\x1b[39m"); | |
| expect(reset.getBgAnsi("selectedBg")).toBe("\x1b[49m"); | |
| expect(reset.fg("accent", "text")).toBe("\x1b[39mtext\x1b[39m"); | |
| expect(reset.bg("selectedBg", "text")).toBe("\x1b[49mtext\x1b[49m"); | |
| }, | |
| ); | |
| it.each([ | |
| ["fg", /^Unknown theme color: missing$/], | |
| ["getFgAnsi", /^Unknown theme color: missing$/], | |
| ["bg", /^Unknown theme background color: missing$/], | |
| ["getBgAnsi", /^Unknown theme background color: missing$/], | |
| ] as const)("rejects unknown colors through %s", (method, message) => { | |
| const theme = loadColor(123, "256color"); | |
| expect(() => Reflect.apply(theme[method], theme, ["missing", "text"])).toThrow(message); | |
| }); | |
| it("keeps formatting independent of supplied raw ANSI getter overrides", () => { | |
| const theme = loadColor(123, "256color"); | |
| theme.getFgAnsi = () => "\x1b[31m"; | |
| theme.getBgAnsi = () => "\x1b[41m"; | |
| expect(theme.getFgAnsi("accent")).toBe("\x1b[31m"); | |
| expect(theme.getBgAnsi("selectedBg")).toBe("\x1b[41m"); | |
| expect(theme.fg("accent", "text")).toBe("\x1b[38;5;123mtext\x1b[39m"); | |
| expect(theme.bg("selectedBg", "text")).toBe("\x1b[48;5;123mtext\x1b[49m"); | |
| }); | |
| }); | |