json-merge-resolver
Version:
A rules-based JSON conflict resolver that parses Git conflict markers, reconstructs ours/theirs, and merges with deterministic strategies — beyond line-based merges.
22 lines (21 loc) • 3.28 kB
JavaScript
import{a,b as c,c as u,d as l}from"./chunk-54J6PE6E.mjs";import{a as i,b as r,g as e,h as n}from"./chunk-YAHYZFUT.mjs";import"./chunk-76CZ6Z7T.mjs";i("parseConflictContent",()=>{let s=(t,o)=>`
{
"name": "test",
<<<<<<< ours
${t}
=======
${o}
>>>>>>> theirs
}
`.trim();r("parses simple JSON conflict",async()=>{let t=s(' "value": 1',' "value": 2'),o=await a(t,{parsers:"json",filename:""});e(o.format).toBe("json"),e(o.ours).toEqual({name:"test",value:1}),e(o.theirs).toEqual({name:"test",value:2})}),r("respects filename extension hint (yaml)",async()=>{let o=await a(`
key: value
<<<<<<< ours
ours: 1
=======
theirs: 2
>>>>>>> theirs
`,{filename:"config.yaml"});e(o.format).toBe("yaml"),e(o.ours).toHaveProperty("ours",1),e(o.theirs).toHaveProperty("theirs",2)}),r("respects explicit parsers array (json5 fallback)",async()=>{let t=s(" value: 1,"," value: 2,"),o=await a(t,{parsers:["json5"],filename:""});e(o.format).toBe("json5"),e(o.ours).toMatchObject({value:1}),e(o.theirs).toMatchObject({value:2})}),r("supports custom parser",async()=>{let t=s("ours-side","theirs-side"),m=await a(t,{parsers:{name:"custom",parser:p=>({parsed:p.trim()})},filename:""});e(m.format).toBe("custom"),e(m.ours).toMatchObject({parsed:e.stringContaining("ours-side")}),e(m.theirs).toMatchObject({parsed:e.stringContaining("theirs-side")})}),r("throws if parsing fails for all parsers",async()=>{await e(a("invalid",{parsers:["json"],filename:""})).rejects.toThrow(/Failed to parse/)}),r("throws if conflict markers produce empty side",async()=>{await e(a(`
<<<<<<< ours
only ours
>>>>>>> theirs
`,{parsers:"json",filename:""})).rejects.toThrow(/empty content/)})});i("normalizeParsers",()=>{r("returns auto parsers when parsers is 'auto'",()=>{let s=c({parsers:"auto",filename:"test.json"});e(s).toEqual(["json","json5","yaml","toml","xml"])}),r("returns single parser when parsers is string",()=>{let s=c({parsers:"yaml",filename:"test.json"});e(s).toEqual(["yaml"])}),r("falls back to extension-based parser",()=>{let s=c({filename:"config.toml"});e(s).toEqual(["toml"])})});i("runParser",()=>{r("logs debug message on parser failure",async()=>{let s=n.spyOn(console,"debug").mockImplementation(()=>{});await e(u("invalid",["json"])).rejects.toThrow(),e(s).toHaveBeenCalledWith(e.stringContaining("Parser json failed:"),e.any(Error)),s.mockRestore()})});i("parseFormat",()=>{r("throws error for missing json5 dependency",async()=>{n.doMock("json5",()=>{throw new Error("Module not found")}),await e(l("json5","{}")).rejects.toThrow(/json5 parser not installed/)}),r("throws error for missing yaml dependency",async()=>{n.doMock("yaml",()=>{throw new Error("Module not found")}),await e(l("yaml","key: value")).rejects.toThrow(/yaml parser not installed/)}),r("throws error for missing toml dependency",async()=>{n.doMock("smol-toml",()=>{throw new Error("Module not found")}),await e(l("toml","key = 'value'")).rejects.toThrow(/toml parser not installed/)}),r("parses xml successfully",async()=>{let s=await l("xml","<root><key>value</key></root>");e(s).toHaveProperty("root")}),r("throws error for missing xml dependency",async()=>{n.doMock("fast-xml-parser",()=>{throw new Error("Module not found")}),await e(l("xml","<root></root>")).rejects.toThrow(/fast-xml-parser not installed/)})});