// eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-nocheck import { test, expect } from "vitest"; import { inlangLixPluginV1 } from "./inlangLixPluginV1.js"; import { newLixFile, openLixInMemory, type Change, type NewChange, } from "@lix-js/sdk"; test.skip("a create operation should not report a conflict given that the change does not exist in target", async () => { const targetLix = await openLixInMemory({ blob: await newLixFile() }); const sourceLix = await openLixInMemory({ blob: await newLixFile() }); const changes = await sourceLix.db .insertInto("change") .values([ { id: "1", parent_id: undefined, operation: "create", file_id: "mock", plugin_key: "mock", type: "mock", value: { id: "change 1" }, }, ]) .returningAll() .execute(); const conflicts = await inlangLixPluginV1.detectConflicts!({ sourceLix, targetLix, leafChangesOnlyInSource: changes, }); expect(conflicts).toHaveLength(0); }); test.todo( "it should report deletions as a conflict if the parent of the target and source are not identical", async () => { const targetLix = await openLixInMemory({ blob: await newLixFile() }); await targetLix.db .insertInto("change") .values([ { id: "1", parent_id: undefined, operation: "create", file_id: "mock", plugin_key: "mock", type: "mock", value: { id: "change 1", }, }, ]) .execute(); const sourceLix = await openLixInMemory({ blob: await targetLix.toBlob() }); const changesNotInTarget: NewChange[] = [ { id: "2", parent_id: "1", operation: "delete", file_id: "mock", plugin_key: "mock", type: "mock", value: undefined, }, ]; await sourceLix.db .insertInto("change") .values(changesNotInTarget) .execute(); const conflicts = await inlangLixPluginV1.detectConflicts!({ sourceLix, targetLix, leafChangesOnlyInSource: changesNotInTarget as Change[], }); expect(conflicts).toHaveLength(1); expect(conflicts[0]?.change_id).toBe("1"); expect(conflicts[0]?.conflicting_change_id).toBe("2"); throw new Error("The parent is identicak, fix this test"); } ); test.skip("it should report an UPDATE as a conflict if leaf changes are conflicting", async () => { const targetLix = await openLixInMemory({ blob: await newLixFile() }); const sourceLix = await openLixInMemory({ blob: await targetLix.toBlob() }); const commonChanges: NewChange[] = [ { id: "12s", parent_id: undefined, operation: "create", file_id: "mock", plugin_key: "mock", type: "mock", value: { id: "change 12s", }, }, ]; const changesOnlyInTarget: NewChange[] = [ { id: "3sd", parent_id: "12s", operation: "update", file_id: "mock", plugin_key: "mock", type: "mock", value: { id: "change 3sd", }, }, ]; const changesOnlyInSource: NewChange[] = [ { id: "2qa", parent_id: "12s", operation: "update", file_id: "mock", plugin_key: "mock", type: "mock", value: { id: "change 2qa", }, }, ]; await sourceLix.db .insertInto("change") .values([...commonChanges, ...changesOnlyInSource]) .execute(); await targetLix.db .insertInto("change") .values([...commonChanges, ...changesOnlyInTarget]) .execute(); const conflicts = await inlangLixPluginV1.detectConflicts!({ leafChangesOnlyInSource: changesOnlyInSource as Change[], sourceLix: sourceLix, targetLix: targetLix, }); expect(conflicts).toHaveLength(1); }); /** * If the common ancestor is the leaf change of the target, then the * source change are (likely) not a conflict because no update has * been made to the target change that could conflict with updates * in the source. */ test.skip("it should NOT report an UPDATE as a conflict if the common ancestor is the leaf change of the target", async () => { const targetLix = await openLixInMemory({ blob: await newLixFile() }); const sourceLix = await openLixInMemory({ blob: await targetLix.toBlob() }); const commonChanges: NewChange[] = [ { id: "12s", parent_id: undefined, operation: "create", file_id: "mock", plugin_key: "mock", type: "mock", value: { id: "change 12s", }, }, ]; const changesOnlyInTarget: NewChange[] = [ { id: "3sd", parent_id: "12s", operation: "update", file_id: "mock", plugin_key: "mock", type: "mock", value: { id: "change 3sd", }, }, { id: "23a", parent_id: "3sd", operation: "update", file_id: "mock", plugin_key: "mock", type: "mock", value: { id: "change 23a", }, }, ]; const changesOnlyInSource: NewChange[] = []; await sourceLix.db .insertInto("change") .values([...commonChanges, ...changesOnlyInSource]) .execute(); await targetLix.db .insertInto("change") .values([...commonChanges, ...changesOnlyInTarget]) .execute(); const conflicts = await inlangLixPluginV1.detectConflicts!({ leafChangesOnlyInSource: changesOnlyInSource as Change[], sourceLix: sourceLix, targetLix: targetLix, }); expect(conflicts).toHaveLength(0); }); test.skip("it should NOT report a DELETE as a conflict if the parent of the target and source are identical", async () => { const targetLix = await openLixInMemory({ blob: await newLixFile() }); await targetLix.db .insertInto("change") .values([ { id: "12s", parent_id: undefined, operation: "create", file_id: "mock", plugin_key: "mock", type: "mock", value: { id: "change 12s", }, }, ]) .execute(); const sourceLix = await openLixInMemory({ blob: await targetLix.toBlob() }); const changesNotInTarget: NewChange[] = [ { id: "3sd", parent_id: "12s", operation: "delete", file_id: "mock", plugin_key: "mock", type: "mock", value: undefined, }, ]; const changesNotInSource: NewChange[] = [ { id: "2qa", parent_id: "12s", operation: "update", file_id: "mock", plugin_key: "mock", type: "mock", value: { id: "2qa", }, }, ]; await sourceLix.db.insertInto("change").values(changesNotInTarget).execute(); await targetLix.db.insertInto("change").values(changesNotInSource).execute(); const conflicts = await inlangLixPluginV1.detectConflicts!({ sourceLix, targetLix, leafChangesOnlyInSource: changesNotInTarget as Change[], }); expect(conflicts).toHaveLength(1); expect(conflicts[0]?.change_id).toBe("2qa"); expect(conflicts[0]?.conflicting_change_id).toBe("3sd"); });