import { describe, it, expect } from "vitest"; import { buildRootPairBlock, hasRootPairMarker, buildPreInitHint, computeInjectionBudget, modeAllowsPreInitHint, modeAllowsInjection, modeRequiresProtocolPath, ROOT_PAIR_START_MARKER, ROOT_PAIR_END_MARKER, TRUST_BOUNDARY_TEXT, } from "../src/prompt-injection.js"; describe("prompt-injection helpers", () => { describe("canonical markers", () => { it("builds a root-pair block with markers", () => { const block = buildRootPairBlock("index content", "map content"); expect(block).toContain(ROOT_PAIR_START_MARKER); expect(block).toContain(ROOT_PAIR_END_MARKER); expect(block).toContain(TRUST_BOUNDARY_TEXT); expect(block).toContain("index content"); expect(block).toContain("map content"); }); it("detects root-pair marker in content", () => { const block = buildRootPairBlock("i", "m"); expect(hasRootPairMarker(block)).toBe(true); expect(hasRootPairMarker("plain text")).toBe(false); }); }); describe("pre-init hint", () => { it("returns a visible hint with no synthetic artifacts", () => { const hint = buildPreInitHint(); expect(hint).toContain("project_map_init"); expect(hint).toContain("📋"); expect(hint).not.toContain(ROOT_PAIR_START_MARKER); expect(hint).not.toContain("### Root index"); expect(hint).not.toContain("### Root map"); }); }); describe("budget calculation", () => { it("uses relative percent when smaller than absolute cap", () => { const budget = computeInjectionBudget( { contextBudgetPercent: 15, contextBudgetMaxTokens: 100_000 }, 200_000, ); expect(budget).toBe(30_000); }); it("uses absolute cap when smaller than relative percent", () => { const budget = computeInjectionBudget( { contextBudgetPercent: 15, contextBudgetMaxTokens: 100_000 }, 10_000_000, ); expect(budget).toBe(100_000); }); it("falls back to absolute cap when context window is unknown", () => { const budget = computeInjectionBudget( { contextBudgetPercent: 15, contextBudgetMaxTokens: 100_000 }, undefined, ); expect(budget).toBe(100_000); }); it("falls back to absolute cap when context window is zero", () => { const budget = computeInjectionBudget( { contextBudgetPercent: 15, contextBudgetMaxTokens: 100_000 }, 0, ); expect(budget).toBe(100_000); }); }); describe("mode helpers", () => { it("allows pre-init hint for all modes except off", () => { expect(modeAllowsPreInitHint("off")).toBe(false); expect(modeAllowsPreInitHint("advisory")).toBe(true); expect(modeAllowsPreInitHint("strong")).toBe(true); expect(modeAllowsPreInitHint("strict")).toBe(true); }); it("allows injection only for strong and strict", () => { expect(modeAllowsInjection("off")).toBe(false); expect(modeAllowsInjection("advisory")).toBe(false); expect(modeAllowsInjection("strong")).toBe(true); expect(modeAllowsInjection("strict")).toBe(true); }); it("requires protocol path only for strict", () => { expect(modeRequiresProtocolPath("off")).toBe(false); expect(modeRequiresProtocolPath("advisory")).toBe(false); expect(modeRequiresProtocolPath("strong")).toBe(false); expect(modeRequiresProtocolPath("strict")).toBe(true); }); }); });