Something went wrong. Try again.
I'm going to build my own OpenClaw, with blackjack... and bun!
Something went wrong. Try again.
6.8 kB · 225 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226/** * test/agent-control/parser-utils.test.ts – Unit tests for parser utility functions. * * Covers parseToggle(), parseQueueMode(), splitArgs(), parseTreeArgs(), * and stripTrigger() — the low-level helpers used by command-parsers.ts. */
import { describe, test, expect } from "bun:test";import "../helpers.js";
import { parseToggle, parseQueueMode, splitArgs, parseTreeArgs, stripTrigger } from "../../src/agent-control/parser-utils.js";
describe("parseToggle", () => { test("returns true for on variants", () => { expect(parseToggle("on")).toBe(true); expect(parseToggle("true")).toBe(true); expect(parseToggle("yes")).toBe(true); expect(parseToggle("1")).toBe(true); expect(parseToggle("enable")).toBe(true); expect(parseToggle("enabled")).toBe(true); });
test("returns false for off variants", () => { expect(parseToggle("off")).toBe(false); expect(parseToggle("false")).toBe(false); expect(parseToggle("no")).toBe(false); expect(parseToggle("0")).toBe(false); expect(parseToggle("disable")).toBe(false); expect(parseToggle("disabled")).toBe(false); });
test("returns undefined for empty or unknown", () => { expect(parseToggle()).toBeUndefined(); expect(parseToggle("")).toBeUndefined(); expect(parseToggle("maybe")).toBeUndefined(); });
test("case insensitive", () => { expect(parseToggle("ON")).toBe(true); expect(parseToggle("OFF")).toBe(false); expect(parseToggle("True")).toBe(true); });});
describe("parseQueueMode", () => { test("returns 'all'", () => { expect(parseQueueMode("all")).toBe("all"); });
test("returns 'one-at-a-time' for various inputs", () => { expect(parseQueueMode("one")).toBe("one-at-a-time"); expect(parseQueueMode("one-at-a-time")).toBe("one-at-a-time"); expect(parseQueueMode("one_at_a_time")).toBe("one-at-a-time"); expect(parseQueueMode("single")).toBe("one-at-a-time"); });
test("returns undefined for empty or unknown", () => { expect(parseQueueMode()).toBeUndefined(); expect(parseQueueMode("")).toBeUndefined(); expect(parseQueueMode("unknown")).toBeUndefined(); });});
describe("splitArgs", () => { test("splits simple args", () => { expect(splitArgs("a b c")).toEqual(["a", "b", "c"]); });
test("handles quoted strings", () => { expect(splitArgs('a "hello world" c')).toEqual(["a", "hello world", "c"]); expect(splitArgs("a 'hello world' c")).toEqual(["a", "hello world", "c"]); });
test("handles empty input", () => { expect(splitArgs("")).toEqual([]); });
test("handles multiple spaces and tabs", () => { expect(splitArgs(" a b\tc ")).toEqual(["a", "b", "c"]); });
test("handles newlines", () => { expect(splitArgs("a\nb")).toEqual(["a", "b"]); });});
describe("parseTreeArgs", () => { test("empty args", () => { const result = parseTreeArgs(""); expect(result.targetId).toBeUndefined(); expect(result.summarize).toBe(false); expect(result.mode).toBe("tail"); });
test("target id", () => { const result = parseTreeArgs("abc123"); expect(result.targetId).toBe("abc123"); });
test("--summarize flag", () => { const result = parseTreeArgs("--summarize"); expect(result.summarize).toBe(true); });
test("--summary with custom instructions", () => { const result = parseTreeArgs('--summary "keep code only"'); expect(result.summarize).toBe(true); expect(result.customInstructions).toBe("keep code only"); });
test("--replace flag", () => { const result = parseTreeArgs("--replace"); expect(result.replaceInstructions).toBe(true); });
test("--label flag", () => { const result = parseTreeArgs("--label my-label"); expect(result.label).toBe("my-label"); });
test("--label= syntax", () => { const result = parseTreeArgs("--label=my-label"); expect(result.label).toBe("my-label"); });
test("--head with limit", () => { const result = parseTreeArgs("--head 10"); expect(result.mode).toBe("head"); expect(result.limit).toBe(10); });
test("--head= syntax", () => { const result = parseTreeArgs("--head=5"); expect(result.mode).toBe("head"); expect(result.limit).toBe(5); });
test("--first= syntax", () => { const result = parseTreeArgs("--first=3"); expect(result.mode).toBe("head"); expect(result.limit).toBe(3); });
test("--tail with limit", () => { const result = parseTreeArgs("--tail 20"); expect(result.mode).toBe("tail"); expect(result.limit).toBe(20); });
test("--tail= syntax", () => { const result = parseTreeArgs("--tail=7"); expect(result.mode).toBe("tail"); expect(result.limit).toBe(7); });
test("--last= syntax", () => { const result = parseTreeArgs("--last=4"); expect(result.mode).toBe("tail"); expect(result.limit).toBe(4); });
test("--limit sets head mode by default", () => { const result = parseTreeArgs("--limit 15"); expect(result.limit).toBe(15); expect(result.mode).toBe("head"); });
test("--limit= syntax", () => { const result = parseTreeArgs("--limit=8"); expect(result.limit).toBe(8); });
test("--offset sets head mode by default", () => { const result = parseTreeArgs("--offset 5"); expect(result.offset).toBe(5); expect(result.mode).toBe("head"); });
test("--offset= syntax", () => { const result = parseTreeArgs("--offset=3"); expect(result.offset).toBe(3); });
test("--tail overrides --limit's default mode", () => { const result = parseTreeArgs("--tail --limit 10"); expect(result.mode).toBe("tail"); expect(result.limit).toBe(10); });
test("--head without explicit limit", () => { const result = parseTreeArgs("--head"); expect(result.mode).toBe("head"); expect(result.limit).toBeUndefined(); });
test("target + flags combined", () => { const result = parseTreeArgs("abc --summarize --head 5"); expect(result.targetId).toBe("abc"); expect(result.summarize).toBe(true); expect(result.mode).toBe("head"); expect(result.limit).toBe(5); });
test("unknown flags are ignored", () => { const result = parseTreeArgs("--unknown --head 3"); expect(result.mode).toBe("head"); expect(result.limit).toBe(3); });});
describe("stripTrigger", () => { test("strips trigger pattern", () => { const trigger = /(?:^|\s)@PiClaw\b/i; expect(stripTrigger("@PiClaw /model gpt-4", trigger)).toBe("/model gpt-4"); });
test("handles no trigger", () => { const trigger = /(?:^|\s)@PiClaw\b/i; expect(stripTrigger("/model gpt-4", trigger)).toBe("/model gpt-4"); });
test("handles no pattern", () => { expect(stripTrigger(" hello ")).toBe("hello"); });});