a5c71bb775
- Added markdown prose tests to verify maskNonProse preserves plain prose and masks fenced/tilde blocks. - Added keyword-in-prose tests that enforced lowercase token matching and ignored code spans, fences, XML, and comments. - Added highlight-mode tests ensuring only prose keywords are ANSI-highlighted and inline/fenced/XML regions stay unmodified. - Added workflow/orchestrate assertions that uppercase or path-like forms remain unchanged while lowercase token boundaries are handled correctly.
47 lines
2.1 KiB
TypeScript
47 lines
2.1 KiB
TypeScript
import { beforeAll, describe, expect, it } from "bun:test";
|
|
import { highlightMagicKeywords } from "../../src/modes/magic-keywords";
|
|
import { initTheme } from "../../src/modes/theme/theme";
|
|
|
|
beforeAll(async () => {
|
|
// Gradient palettes read the active theme's color mode.
|
|
await initTheme(false);
|
|
});
|
|
|
|
describe("highlightMagicKeywords", () => {
|
|
it("paints every magic keyword in a single prose pass, preserving visible text", () => {
|
|
const input = "first ultrathink then orchestrate the workflow";
|
|
const decorated = highlightMagicKeywords(input);
|
|
expect(decorated).not.toBe(input);
|
|
expect(decorated).toContain("\x1b[38");
|
|
expect(Bun.stripANSI(decorated)).toBe(input);
|
|
// Each keyword is gradient-painted character-by-character, so none survives as a
|
|
// contiguous run in the decorated output.
|
|
for (const keyword of ["ultrathink", "orchestrate", "workflow"]) {
|
|
expect(decorated).not.toContain(keyword);
|
|
expect(Bun.stripANSI(decorated)).toContain(keyword);
|
|
}
|
|
});
|
|
|
|
it("never paints keywords inside code spans, fenced blocks, or XML sections", () => {
|
|
const input = "`ultrathink`\n```\norchestrate\n```\n<x>workflow</x>";
|
|
expect(highlightMagicKeywords(input)).toBe(input);
|
|
});
|
|
|
|
it("paints only the prose occurrence when the keyword also appears in code", () => {
|
|
const decorated = highlightMagicKeywords("`orchestrate` but please orchestrate now");
|
|
// The code-span occurrence stays literal; the prose one is split by gradient escapes.
|
|
expect(decorated).toContain("`orchestrate`");
|
|
expect(Bun.stripANSI(decorated)).toBe("`orchestrate` but please orchestrate now");
|
|
// Exactly one prose occurrence painted ⇒ one contiguous "orchestrate" remains (the code one).
|
|
expect(decorated.split("orchestrate").length - 1).toBe(1);
|
|
});
|
|
|
|
it("restores the supplied foreground after each painted keyword", () => {
|
|
const reset = "\x1b[38;2;1;2;3m";
|
|
const decorated = highlightMagicKeywords("go orchestrate go", reset);
|
|
expect(decorated).toContain(reset);
|
|
// The reset must land before the trailing prose so it keeps the bubble color.
|
|
expect(decorated.endsWith(`${reset} go`)).toBe(true);
|
|
});
|
|
});
|