Skip to content

Commit b757224

Browse files
committed
Add unit tests
1 parent a209afc commit b757224

File tree

1 file changed

+85
-5
lines changed

1 file changed

+85
-5
lines changed

lib/src/merger.test.ts

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,26 @@ describe("BuiltInStrategies", () => {
106106
expect(BuiltInStrategies.update({ ...args, ours: undefined, theirs: "y" }).value).toBe(DROP);
107107
});
108108

109+
it("concat arrays", () => {
110+
const r = BuiltInStrategies.concat({ ...args, ours: [1], theirs: [2] });
111+
expect(r).toEqual({ status: StrategyStatus_OK, value: [1, 2] });
112+
});
113+
114+
it("concat non-arrays → CONTINUE", () => {
115+
const r = BuiltInStrategies.concat({ ...args, ours: "a", theirs: "b" });
116+
expect(r.status).toBe(StrategyStatus_CONTINUE);
117+
});
118+
119+
it("unique arrays", () => {
120+
const r = BuiltInStrategies.unique({ ...args, ours: [1, 2], theirs: [2, 3] });
121+
expect(r).toEqual({ status: StrategyStatus_OK, value: [1, 2, 3] });
122+
});
123+
124+
it("unique non-arrays → CONTINUE", () => {
125+
const r = BuiltInStrategies.unique({ ...args, ours: "a", theirs: "b" });
126+
expect(r.status).toBe(StrategyStatus_CONTINUE);
127+
});
128+
109129
it("merge plain objects recurses", async () => {
110130
const objArgs = {
111131
...args,
@@ -175,13 +195,13 @@ describe("mergeObject", () => {
175195
expect(conflicts[0].reason).toMatch(/Skip/);
176196
});
177197

178-
it.skip("adds conflict if all CONTINUE", async () => {
179-
(resolveStrategies as any).mockReturnValueOnce(["non-empty"]);
198+
it("adds conflict if all CONTINUE", async () => {
199+
(resolveStrategies as any).mockReturnValueOnce(["concat"]);
180200
const ctx = makeCtx();
181201
const conflicts: Conflict[] = [];
182202
const v = await mergeObject({
183-
ours: "",
184-
theirs: "",
203+
ours: "a",
204+
theirs: "b",
185205
base: "",
186206
path: "p",
187207
ctx,
@@ -194,4 +214,64 @@ describe("mergeObject", () => {
194214
reason: expect.stringContaining("All strategies failed"),
195215
});
196216
});
197-
});
217+
218+
it("uses custom strategy from ctx.strategies", async () => {
219+
(resolveStrategies as any).mockReturnValueOnce(["custom"]);
220+
const ctx = makeCtx();
221+
ctx.strategies.custom = vi.fn(() => ({ status: StrategyStatus_OK, value: "custom-result" }));
222+
const conflicts: Conflict[] = [];
223+
const v = await mergeObject({
224+
ours: "a",
225+
theirs: "b",
226+
path: "p",
227+
ctx,
228+
conflicts,
229+
logger: mockLogger,
230+
});
231+
expect(v).toBe("custom-result");
232+
expect(ctx.strategies.custom).toHaveBeenCalled();
233+
});
234+
235+
it("throws on FAIL status", async () => {
236+
(resolveStrategies as any).mockReturnValueOnce(["fail-strategy"]);
237+
const ctx = makeCtx();
238+
ctx.strategies["fail-strategy"] = vi.fn(() => ({
239+
status: StrategyStatus_FAIL,
240+
reason: "test fail",
241+
}));
242+
const conflicts: Conflict[] = [];
243+
await expect(
244+
mergeObject({
245+
ours: "a",
246+
theirs: "b",
247+
path: "p",
248+
ctx,
249+
conflicts,
250+
logger: mockLogger,
251+
}),
252+
).rejects.toThrow("Merge failed at p: test fail");
253+
expect(conflicts[0].reason).toBe("test fail");
254+
});
255+
256+
it("enriches conflict with debug info when debug enabled", async () => {
257+
(resolveStrategies as any).mockReturnValueOnce(["concat"]);
258+
const ctx = makeCtx();
259+
ctx.config.debug = true;
260+
const conflicts: Conflict[] = [];
261+
await mergeObject({
262+
ours: "a",
263+
theirs: "b",
264+
base: "c",
265+
path: "p",
266+
ctx,
267+
conflicts,
268+
logger: mockLogger,
269+
});
270+
expect(conflicts[0]).toMatchObject({
271+
path: "p",
272+
ours: "a",
273+
theirs: "b",
274+
base: "c",
275+
});
276+
});
277+
});

0 commit comments

Comments
 (0)