Files
Kilo-Org_kilocode/packages/opencode/test/kilocode/patch-jsonc.test.ts
2026-03-10 00:32:50 -03:00

75 lines
3.1 KiB
TypeScript

// kilocode_change - new file
import { describe, expect, test } from "bun:test"
import { applyEdits, modify, findNodeAtLocation, parseTree } from "jsonc-parser"
// Replicate patchJsonc logic locally to test it in isolation
function isRecord(value: unknown): value is Record<string, unknown> {
return !!value && typeof value === "object" && !Array.isArray(value)
}
function patchJsonc(input: string, patch: unknown, path: string[] = []): string {
if (!isRecord(patch)) {
const edits = modify(input, path, patch === null ? undefined : patch, {
formattingOptions: { insertSpaces: true, tabSize: 2 },
})
return applyEdits(input, edits)
}
if (path.length > 0) {
const tree = parseTree(input)
const node = tree && findNodeAtLocation(tree, path)
if (node && node.type !== "object") {
const edits = modify(input, path, patch, {
formattingOptions: { insertSpaces: true, tabSize: 2 },
})
return applyEdits(input, edits)
}
}
return Object.entries(patch).reduce((result, [key, value]) => {
if (value === undefined) return result
return patchJsonc(result, value, [...path, key])
}, input)
}
describe("patchJsonc scalar-to-object transition", () => {
test("sets object when node does not yet exist", () => {
const input = `{ "permission": {} }`
const result = patchJsonc(input, { permission: { bash: { "*": "ask", uname: "allow" } } })
const parsed = JSON.parse(result)
expect(parsed.permission.bash).toEqual({ "*": "ask", uname: "allow" })
})
test("transitions permission rule from string to object (the bug scenario)", () => {
// bash is stored as a plain string "ask" in the JSONC file
const input = `{ "permission": { "bash": "ask" } }`
// User adds exception "uname" → "allow"; this would previously throw:
// "Can not add index to parent of type string"
const result = patchJsonc(input, { permission: { bash: { "*": "ask", uname: "allow" } } })
const parsed = JSON.parse(result)
expect(parsed.permission.bash).toEqual({ "*": "ask", uname: "allow" })
})
test("does not disturb sibling keys when replacing scalar", () => {
const input = `{ "permission": { "bash": "ask", "glob": "allow" } }`
const result = patchJsonc(input, { permission: { bash: { "*": "ask", uname: "allow" } } })
const parsed = JSON.parse(result)
expect(parsed.permission.glob).toBe("allow")
expect(parsed.permission.bash).toEqual({ "*": "ask", uname: "allow" })
})
test("updates existing object permission by adding a new key", () => {
const input = `{ "permission": { "bash": { "*": "ask" } } }`
const result = patchJsonc(input, { permission: { bash: { "*": "ask", uname: "allow" } } })
const parsed = JSON.parse(result)
expect(parsed.permission.bash).toEqual({ "*": "ask", uname: "allow" })
})
test("plain string permission update still works", () => {
const input = `{ "permission": { "bash": "allow" } }`
const result = patchJsonc(input, { permission: { bash: "ask" } })
const parsed = JSON.parse(result)
expect(parsed.permission.bash).toBe("ask")
})
})