summaryrefslogtreecommitdiffhomepage
path: root/packages/system-prompt/src/parser.test.ts
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-26 22:03:19 +0900
committerAdam Malczewski <[email protected]>2026-06-26 22:23:39 +0900
commit727c98c9dae516a2070eb950410314380a20c974 (patch)
tree52aa1022c54f11770be7e4e2a324f0a8b8b8deec /packages/system-prompt/src/parser.test.ts
parente59dc11f63b1df51142259bb2c406af8c9c8c2bb (diff)
downloaddispatch-727c98c9dae516a2070eb950410314380a20c974.tar.gz
dispatch-727c98c9dae516a2070eb950410314380a20c974.zip
style: switch from tabs to 2-space indentation
Diffstat (limited to 'packages/system-prompt/src/parser.test.ts')
-rw-r--r--packages/system-prompt/src/parser.test.ts356
1 files changed, 178 insertions, 178 deletions
diff --git a/packages/system-prompt/src/parser.test.ts b/packages/system-prompt/src/parser.test.ts
index 636a50d..3e3cdb6 100644
--- a/packages/system-prompt/src/parser.test.ts
+++ b/packages/system-prompt/src/parser.test.ts
@@ -2,185 +2,185 @@ import { describe, expect, it } from "vitest";
import { extractVariables, parseTemplate } from "./parser.js";
function vars(entries: ReadonlyArray<[string, string | null]>): Map<string, string | null> {
- return new Map(entries);
+ return new Map(entries);
}
describe("parser", () => {
- describe("variable insertion", () => {
- it("simple variable insertion", () => {
- // 1. [system:time] with value → inserts it
- expect(parseTemplate("[system:time]", vars([["system:time", "12:00"]]))).toBe("12:00");
- });
-
- it("unknown variable → blank", () => {
- // 2. [unknown:foo] not in map → ""
- expect(parseTemplate("[unknown:foo]", vars([]))).toBe("");
- });
-
- it("null variable → blank", () => {
- // 3. [file:missing.md] with value null → ""
- expect(parseTemplate("[file:missing.md]", vars([["file:missing.md", null]]))).toBe("");
- });
-
- it("inserts value mid-text", () => {
- expect(parseTemplate("cwd is [prompt:cwd]!", vars([["prompt:cwd", "/proj"]]))).toBe(
- "cwd is /proj!",
- );
- });
-
- it("non-tag brackets stay literal", () => {
- expect(parseTemplate("[not a tag] done", vars([]))).toBe("[not a tag] done");
- });
-
- it("unclosed bracket stays literal", () => {
- expect(parseTemplate("[file:x", vars([]))).toBe("[file:x");
- });
- });
-
- describe("conditionals", () => {
- it("if block renders when variable exists", () => {
- // 4. [if file:AGENTS.md]YES[endif] with value → "YES"
- expect(
- parseTemplate("[if file:AGENTS.md]YES[endif]", vars([["file:AGENTS.md", "content"]])),
- ).toBe("YES");
- });
-
- it("if block skipped when variable is null", () => {
- // 5. same with null → ""
- expect(parseTemplate("[if file:AGENTS.md]YES[endif]", vars([["file:AGENTS.md", null]]))).toBe(
- "",
- );
- });
-
- it("if block skipped when variable absent", () => {
- expect(parseTemplate("[if file:AGENTS.md]YES[endif]", vars([]))).toBe("");
- });
-
- it("if/else renders fallback when null", () => {
- // 6. [if file:X]A[else]B[endif] with null → "B"
- expect(parseTemplate("[if file:X]A[else]B[endif]", vars([["file:X", null]]))).toBe("B");
- });
-
- it("if/else renders then-branch when exists", () => {
- expect(parseTemplate("[if file:X]A[else]B[endif]", vars([["file:X", "v"]]))).toBe("A");
- });
-
- it("negated if renders when variable is null", () => {
- // 7. [if !file:X]A[endif] with null → "A"
- expect(parseTemplate("[if !file:X]A[endif]", vars([["file:X", null]]))).toBe("A");
- });
-
- it("negated if skipped when variable exists", () => {
- expect(parseTemplate("[if !file:X]A[endif]", vars([["file:X", "v"]]))).toBe("");
- });
-
- it("negated if renders when variable absent", () => {
- expect(parseTemplate("[if !file:X]A[endif]", vars([]))).toBe("A");
- });
-
- it("nested if — inner skipped when its var is null", () => {
- // 8. [if system:os][if file:X]A[endif][endif] with os=set, file=null → ""
- expect(
- parseTemplate(
- "[if system:os][if file:X]A[endif][endif]",
- vars([
- ["system:os", "linux"],
- ["file:X", null],
- ]),
- ),
- ).toBe("");
- });
-
- it("nested if — inner renders when both exist", () => {
- expect(
- parseTemplate(
- "[if system:os][if file:X]A[endif][endif]",
- vars([
- ["system:os", "linux"],
- ["file:X", "v"],
- ]),
- ),
- ).toBe("A");
- });
-
- it("nested if/else", () => {
- expect(
- parseTemplate(
- "[if system:os]os[if file:X]A[else]B[endif][endif]",
- vars([
- ["system:os", "linux"],
- ["file:X", null],
- ]),
- ),
- ).toBe("osB");
- });
-
- it("unmatched if → literal text", () => {
- // 9. [if file:X]text (no endif) → "[if file:X]text"
- expect(parseTemplate("[if file:X]text", vars([["file:X", "v"]]))).toBe("[if file:X]text");
- });
-
- it("unmatched if with null var still emits literal tag", () => {
- expect(parseTemplate("[if file:X]text", vars([["file:X", null]]))).toBe("[if file:X]text");
- });
-
- it("stray endif → literal text", () => {
- expect(parseTemplate("a[endif]b", vars([]))).toBe("a[endif]b");
- });
-
- it("stray else → literal text", () => {
- expect(parseTemplate("a[else]b", vars([]))).toBe("a[else]b");
- });
-
- it("multi-line content renders correctly", () => {
- // 10. if block spanning multiple lines
- const template = "[if file:AGENTS.md]line1\nline2\nline3[endif]";
- expect(parseTemplate(template, vars([["file:AGENTS.md", "c"]]))).toBe("line1\nline2\nline3");
- });
-
- it("multi-line if/else block", () => {
- const template = "[if file:X]\nA\n[else]\nB\n[endif]";
- expect(parseTemplate(template, vars([["file:X", null]]))).toBe("\nB\n");
- });
-
- it("default-template-like structure renders", () => {
- const template =
- "You are a helpful coding assistant.\n\n[if file:AGENTS.md]\n[file:AGENTS.md]\n[endif]\n\nThe current working directory is [prompt:cwd].\n";
- expect(
- parseTemplate(
- template,
- vars([
- ["file:AGENTS.md", "RULES"],
- ["prompt:cwd", "/proj"],
- ]),
- ),
- ).toBe(
- "You are a helpful coding assistant.\n\n\nRULES\n\n\nThe current working directory is /proj.\n",
- );
- });
-
- it("default-template-like structure without AGENTS.md", () => {
- const template = "[if file:AGENTS.md]\n[file:AGENTS.md]\n[endif]\nThe cwd is [prompt:cwd].";
- expect(parseTemplate(template, vars([["prompt:cwd", "/proj"]]))).toBe("\nThe cwd is /proj.");
- });
- });
-
- describe("extractVariables", () => {
- it("collects insertion + condition keys", () => {
- const template = "[system:time] [if file:AGENTS.md][file:AGENTS.md][endif] [if !git:branch]";
- expect(extractVariables(template)).toEqual(["system:time", "file:AGENTS.md", "git:branch"]);
- });
-
- it("deduplicates keys", () => {
- expect(extractVariables("[file:X][if file:X][file:X]")).toEqual(["file:X"]);
- });
-
- it("returns empty for plain text", () => {
- expect(extractVariables("no variables here")).toEqual([]);
- });
-
- it("ignores unmatched tags", () => {
- expect(extractVariables("[if file:X]no endif")).toEqual(["file:X"]);
- });
- });
+ describe("variable insertion", () => {
+ it("simple variable insertion", () => {
+ // 1. [system:time] with value → inserts it
+ expect(parseTemplate("[system:time]", vars([["system:time", "12:00"]]))).toBe("12:00");
+ });
+
+ it("unknown variable → blank", () => {
+ // 2. [unknown:foo] not in map → ""
+ expect(parseTemplate("[unknown:foo]", vars([]))).toBe("");
+ });
+
+ it("null variable → blank", () => {
+ // 3. [file:missing.md] with value null → ""
+ expect(parseTemplate("[file:missing.md]", vars([["file:missing.md", null]]))).toBe("");
+ });
+
+ it("inserts value mid-text", () => {
+ expect(parseTemplate("cwd is [prompt:cwd]!", vars([["prompt:cwd", "/proj"]]))).toBe(
+ "cwd is /proj!",
+ );
+ });
+
+ it("non-tag brackets stay literal", () => {
+ expect(parseTemplate("[not a tag] done", vars([]))).toBe("[not a tag] done");
+ });
+
+ it("unclosed bracket stays literal", () => {
+ expect(parseTemplate("[file:x", vars([]))).toBe("[file:x");
+ });
+ });
+
+ describe("conditionals", () => {
+ it("if block renders when variable exists", () => {
+ // 4. [if file:AGENTS.md]YES[endif] with value → "YES"
+ expect(
+ parseTemplate("[if file:AGENTS.md]YES[endif]", vars([["file:AGENTS.md", "content"]])),
+ ).toBe("YES");
+ });
+
+ it("if block skipped when variable is null", () => {
+ // 5. same with null → ""
+ expect(parseTemplate("[if file:AGENTS.md]YES[endif]", vars([["file:AGENTS.md", null]]))).toBe(
+ "",
+ );
+ });
+
+ it("if block skipped when variable absent", () => {
+ expect(parseTemplate("[if file:AGENTS.md]YES[endif]", vars([]))).toBe("");
+ });
+
+ it("if/else renders fallback when null", () => {
+ // 6. [if file:X]A[else]B[endif] with null → "B"
+ expect(parseTemplate("[if file:X]A[else]B[endif]", vars([["file:X", null]]))).toBe("B");
+ });
+
+ it("if/else renders then-branch when exists", () => {
+ expect(parseTemplate("[if file:X]A[else]B[endif]", vars([["file:X", "v"]]))).toBe("A");
+ });
+
+ it("negated if renders when variable is null", () => {
+ // 7. [if !file:X]A[endif] with null → "A"
+ expect(parseTemplate("[if !file:X]A[endif]", vars([["file:X", null]]))).toBe("A");
+ });
+
+ it("negated if skipped when variable exists", () => {
+ expect(parseTemplate("[if !file:X]A[endif]", vars([["file:X", "v"]]))).toBe("");
+ });
+
+ it("negated if renders when variable absent", () => {
+ expect(parseTemplate("[if !file:X]A[endif]", vars([]))).toBe("A");
+ });
+
+ it("nested if — inner skipped when its var is null", () => {
+ // 8. [if system:os][if file:X]A[endif][endif] with os=set, file=null → ""
+ expect(
+ parseTemplate(
+ "[if system:os][if file:X]A[endif][endif]",
+ vars([
+ ["system:os", "linux"],
+ ["file:X", null],
+ ]),
+ ),
+ ).toBe("");
+ });
+
+ it("nested if — inner renders when both exist", () => {
+ expect(
+ parseTemplate(
+ "[if system:os][if file:X]A[endif][endif]",
+ vars([
+ ["system:os", "linux"],
+ ["file:X", "v"],
+ ]),
+ ),
+ ).toBe("A");
+ });
+
+ it("nested if/else", () => {
+ expect(
+ parseTemplate(
+ "[if system:os]os[if file:X]A[else]B[endif][endif]",
+ vars([
+ ["system:os", "linux"],
+ ["file:X", null],
+ ]),
+ ),
+ ).toBe("osB");
+ });
+
+ it("unmatched if → literal text", () => {
+ // 9. [if file:X]text (no endif) → "[if file:X]text"
+ expect(parseTemplate("[if file:X]text", vars([["file:X", "v"]]))).toBe("[if file:X]text");
+ });
+
+ it("unmatched if with null var still emits literal tag", () => {
+ expect(parseTemplate("[if file:X]text", vars([["file:X", null]]))).toBe("[if file:X]text");
+ });
+
+ it("stray endif → literal text", () => {
+ expect(parseTemplate("a[endif]b", vars([]))).toBe("a[endif]b");
+ });
+
+ it("stray else → literal text", () => {
+ expect(parseTemplate("a[else]b", vars([]))).toBe("a[else]b");
+ });
+
+ it("multi-line content renders correctly", () => {
+ // 10. if block spanning multiple lines
+ const template = "[if file:AGENTS.md]line1\nline2\nline3[endif]";
+ expect(parseTemplate(template, vars([["file:AGENTS.md", "c"]]))).toBe("line1\nline2\nline3");
+ });
+
+ it("multi-line if/else block", () => {
+ const template = "[if file:X]\nA\n[else]\nB\n[endif]";
+ expect(parseTemplate(template, vars([["file:X", null]]))).toBe("\nB\n");
+ });
+
+ it("default-template-like structure renders", () => {
+ const template =
+ "You are a helpful coding assistant.\n\n[if file:AGENTS.md]\n[file:AGENTS.md]\n[endif]\n\nThe current working directory is [prompt:cwd].\n";
+ expect(
+ parseTemplate(
+ template,
+ vars([
+ ["file:AGENTS.md", "RULES"],
+ ["prompt:cwd", "/proj"],
+ ]),
+ ),
+ ).toBe(
+ "You are a helpful coding assistant.\n\n\nRULES\n\n\nThe current working directory is /proj.\n",
+ );
+ });
+
+ it("default-template-like structure without AGENTS.md", () => {
+ const template = "[if file:AGENTS.md]\n[file:AGENTS.md]\n[endif]\nThe cwd is [prompt:cwd].";
+ expect(parseTemplate(template, vars([["prompt:cwd", "/proj"]]))).toBe("\nThe cwd is /proj.");
+ });
+ });
+
+ describe("extractVariables", () => {
+ it("collects insertion + condition keys", () => {
+ const template = "[system:time] [if file:AGENTS.md][file:AGENTS.md][endif] [if !git:branch]";
+ expect(extractVariables(template)).toEqual(["system:time", "file:AGENTS.md", "git:branch"]);
+ });
+
+ it("deduplicates keys", () => {
+ expect(extractVariables("[file:X][if file:X][file:X]")).toEqual(["file:X"]);
+ });
+
+ it("returns empty for plain text", () => {
+ expect(extractVariables("no variables here")).toEqual([]);
+ });
+
+ it("ignores unmatched tags", () => {
+ expect(extractVariables("[if file:X]no endif")).toEqual(["file:X"]);
+ });
+ });
});