Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions packages/opencode/test/config/markdown.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,102 @@ Always structure your responses using clear markdown formatting:
})
})

describe("ConfigMarkdown.shell", () => {
test("extracts shell commands from template", () => {
const template = "Run !`git status` and then !`npm test`"
const matches = ConfigMarkdown.shell(template)
expect(matches.length).toBe(2)
expect(matches[0][1]).toBe("git status")
expect(matches[1][1]).toBe("npm test")
})

test("does not match regular backticks without bang", () => {
const template = "Use `git status` command"
const matches = ConfigMarkdown.shell(template)
expect(matches.length).toBe(0)
})

test("does not match empty bang-backtick", () => {
const template = "Empty !`` should not match"
const matches = ConfigMarkdown.shell(template)
expect(matches.length).toBe(0)
})

test("extracts command with pipes and flags", () => {
const template = "Run !`cat file.txt | grep error` to find issues"
const matches = ConfigMarkdown.shell(template)
expect(matches.length).toBe(1)
expect(matches[0][1]).toBe("cat file.txt | grep error")
})
})

describe("ConfigMarkdown.fallbackSanitization", () => {
test("converts value with colon to block scalar", () => {
const input = "---\nurl: https://example.com:8080\n---\nContent"
const result = ConfigMarkdown.fallbackSanitization(input)
expect(result).toContain("url: |-")
expect(result).toContain(" https://example.com:8080")
})

test("preserves already double-quoted values with colons", () => {
const input = '---\nurl: "https://example.com:8080"\n---\nContent'
const result = ConfigMarkdown.fallbackSanitization(input)
expect(result).toContain('"https://example.com:8080"')
expect(result).not.toContain("|-")
})

test("preserves already single-quoted values with colons", () => {
const input = "---\nurl: 'https://example.com:8080'\n---\nContent"
const result = ConfigMarkdown.fallbackSanitization(input)
expect(result).toContain("'https://example.com:8080'")
expect(result).not.toContain("|-")
})

test("passes through content without frontmatter unchanged", () => {
const input = "Just some content"
expect(ConfigMarkdown.fallbackSanitization(input)).toBe(input)
})

test("preserves comments in frontmatter", () => {
const input = "---\n# comment\nname: John\n---\nContent"
const result = ConfigMarkdown.fallbackSanitization(input)
expect(result).toContain("# comment")
expect(result).toContain("name: John")
})

test("preserves indented continuation lines", () => {
const input = "---\nsummary: >\n This is multiline\n content\n---\nBody"
const result = ConfigMarkdown.fallbackSanitization(input)
expect(result).toContain(" This is multiline")
expect(result).toContain(" content")
})

test("preserves block scalar indicators", () => {
const input = "---\nnotes: |\n line1\n line2\n---\nContent"
const result = ConfigMarkdown.fallbackSanitization(input)
expect(result).toContain("notes: |")
})

test("handles empty frontmatter values", () => {
const input = "---\nempty:\n---\nContent"
const result = ConfigMarkdown.fallbackSanitization(input)
expect(result).toContain("empty:")
})

test("does not modify content after frontmatter", () => {
const input = "---\nname: John\n---\nContent with url: http://example.com:3000"
const result = ConfigMarkdown.fallbackSanitization(input)
expect(result).toContain("Content with url: http://example.com:3000")
})

test("handles CRLF line endings in frontmatter regex", () => {
const input = "---\r\nurl: https://example.com:8080\r\n---\r\nContent"
const result = ConfigMarkdown.fallbackSanitization(input)
expect(result).toContain("url: |-")
expect(result).toContain(" https://example.com:8080")
})
})

describe("ConfigMarkdown: frontmatter has weird model id", async () => {
const result = await ConfigMarkdown.parse(import.meta.dir + "/fixtures/weird-model-id.md")

Expand Down
63 changes: 62 additions & 1 deletion packages/opencode/test/util/wildcard.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { test, expect } from "bun:test"
import { describe, test, expect } from "bun:test"
import { Wildcard } from "../../src/util/wildcard"

test("match handles glob tokens", () => {
Expand Down Expand Up @@ -88,3 +88,64 @@ test("match handles case-insensitivity on Windows", () => {
expect(Wildcard.match("/users/test/file", "/Users/test/*")).toBe(false)
}
})

// --- Edge cases found during test-discovery audit ---

describe("Wildcard.match — star crosses path separators", () => {
test("star matches across directory boundaries unlike shell glob", () => {
// Wildcard.match uses .* which crosses /, unlike shell globs where * stops at /
// This is relied on by the permission system: "src/*" must match "src/deep/nested/file.ts"
expect(Wildcard.match("src/deep/nested/file.ts", "src/*")).toBe(true)
expect(Wildcard.match("src/a/b/c/d.ts", "src/*/d.ts")).toBe(true)
})
})

describe("Wildcard.match — special regex characters", () => {
test("dots in pattern are literal, not regex any-char", () => {
expect(Wildcard.match("file.txt", "file.txt")).toBe(true)
expect(Wildcard.match("filextxt", "file.txt")).toBe(false)
})

test("parentheses and pipes in pattern are literal", () => {
expect(Wildcard.match("(a|b)", "(a|b)")).toBe(true)
expect(Wildcard.match("a", "(a|b)")).toBe(false)
})

test("brackets in pattern are literal", () => {
expect(Wildcard.match("[abc]", "[abc]")).toBe(true)
expect(Wildcard.match("a", "[abc]")).toBe(false)
})

test("dollar and caret in pattern are literal", () => {
expect(Wildcard.match("$HOME", "$HOME")).toBe(true)
expect(Wildcard.match("^start", "^start")).toBe(true)
})
})

describe("Wildcard.match — empty and boundary cases", () => {
test("empty pattern matches only empty string", () => {
expect(Wildcard.match("", "")).toBe(true)
expect(Wildcard.match("something", "")).toBe(false)
})
})

describe("Wildcard.allStructured — non-contiguous tail matching", () => {
test("non-contiguous tail tokens match if in correct order", () => {
// matchSequence scans non-contiguously: finds "push" then skips "extra" and finds "--force"
const result = Wildcard.allStructured(
{ head: "git", tail: ["push", "extra", "--force"] },
{ "git push --force": "deny" },
)
expect(result).toBe("deny")
})

test("reversed tail tokens do not match when items exhausted", () => {
// Pattern expects push then --force; tail has them reversed
// "push" found at i=1, but no items remain after for "--force"
const result = Wildcard.allStructured(
{ head: "git", tail: ["--force", "push"] },
{ "git push --force": "deny" },
)
expect(result).toBeUndefined()
})
})
Loading