Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

branch support #3124

Open
wants to merge 1 commit into
base: lix-integration
Choose a base branch
from
Open
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
95 changes: 95 additions & 0 deletions inlang/source-code/sdk2/src/lix-plugin/detectConflicts.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { test, expect } from "vitest";
import { inlangLixPluginV1 } from "./inlangLixPluginV1.js";

import {
newLixFile,
openLixInMemory,
Expand All @@ -11,6 +12,13 @@ import {
test("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 currentBranch = await sourceLix.db
.selectFrom("branch")
.selectAll()
.where("active", "=", true)
.executeTakeFirstOrThrow();

const changes = await sourceLix.db
.insertInto("change")
.values([
Expand All @@ -26,6 +34,16 @@ test("a create operation should not report a conflict given that the change does
])
.returningAll()
.execute();

await sourceLix.db
.insertInto("branch_change")
.values({
branch_id: currentBranch.id,
change_id: "1",
seq: 1,
})
.execute();

const conflicts = await inlangLixPluginV1.detectConflicts!({
sourceLix,
targetLix,
Expand Down Expand Up @@ -90,6 +108,17 @@ test("it should report an UPDATE as a conflict if leaf changes are conflicting",
const targetLix = await openLixInMemory({ blob: await newLixFile() });
const sourceLix = await openLixInMemory({ blob: await targetLix.toBlob() });

const currentTargetBranch = await targetLix.db
.selectFrom("branch")
.selectAll()
.where("active", "=", true)
.executeTakeFirstOrThrow();
const currentSourceBranch = await sourceLix.db
.selectFrom("branch")
.selectAll()
.where("active", "=", true)
.executeTakeFirstOrThrow();

const commonChanges: NewChange[] = [
{
id: "12s",
Expand Down Expand Up @@ -137,11 +166,43 @@ test("it should report an UPDATE as a conflict if leaf changes are conflicting",
.values([...commonChanges, ...changesOnlyInSource])
.execute();

await sourceLix.db
.insertInto("branch_change")
.values([
{
branch_id: currentSourceBranch.id,
change_id: "12s",
seq: 1,
},
{
branch_id: currentSourceBranch.id,
change_id: "2qa",
seq: 2,
},
])
.execute();

await targetLix.db
.insertInto("change")
.values([...commonChanges, ...changesOnlyInTarget])
.execute();

await targetLix.db
.insertInto("branch_change")
.values([
{
branch_id: currentTargetBranch.id,
change_id: "12s",
seq: 1,
},
{
branch_id: currentTargetBranch.id,
change_id: "3sd",
seq: 2,
},
])
.execute();

const conflicts = await inlangLixPluginV1.detectConflicts!({
leafChangesOnlyInSource: changesOnlyInSource as Change[],
sourceLix: sourceLix,
Expand Down Expand Up @@ -223,6 +284,13 @@ test("it should NOT report an UPDATE as a conflict if the common ancestor is the

test("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() });

const currentTargetBranch = await targetLix.db
.selectFrom("branch")
.where("active", "=", true)
.selectAll()
.executeTakeFirstOrThrow();

await targetLix.db
.insertInto("change")
.values([
Expand All @@ -240,6 +308,15 @@ test("it should NOT report a DELETE as a conflict if the parent of the target an
])
.execute();

await targetLix.db
.insertInto("branch_change")
.values({
branch_id: currentTargetBranch.id,
change_id: "12s",
seq: 1,
})
.execute();

const sourceLix = await openLixInMemory({ blob: await targetLix.toBlob() });

const changesNotInTarget: NewChange[] = [
Expand Down Expand Up @@ -270,8 +347,26 @@ test("it should NOT report a DELETE as a conflict if the parent of the target an

await sourceLix.db.insertInto("change").values(changesNotInTarget).execute();

await sourceLix.db
.insertInto("branch_change")
.values({
branch_id: currentTargetBranch.id,
change_id: "3sd",
seq: 2,
})
.execute();

await targetLix.db.insertInto("change").values(changesNotInSource).execute();

await targetLix.db
.insertInto("branch_change")
.values({
branch_id: currentTargetBranch.id,
change_id: "2qa",
seq: 2,
})
.execute();

const conflicts = await inlangLixPluginV1.detectConflicts!({
sourceLix,
targetLix,
Expand Down
64 changes: 59 additions & 5 deletions inlang/source-code/sdk2/src/lix-plugin/merge.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,17 @@ import type { NewBundle, NewMessage, NewVariant } from "../database/schema.js";

test("it should update the variant to the source's value", async () => {
const target = await loadProjectInMemory({ blob: await newProject() });
const currentTargetBranch = await target.lix.db
.selectFrom("branch")
.selectAll()
.where("active", "=", true)
.executeTakeFirstOrThrow();
const source = await loadProjectInMemory({ blob: await target.toBlob() });
const currentSourceBranch = await source.lix.db
.selectFrom("branch")
.selectAll()
.where("active", "=", true)
.executeTakeFirstOrThrow();

const dbFile = await target.lix.db
.selectFrom("file")
Expand All @@ -26,7 +36,6 @@ test("it should update the variant to the source's value", async () => {
value: {
id: "even_hour_mule_drum",
} satisfies NewBundle,
commit_id: "c8ad005b-a834-4ca3-84fb-9627546f2eba",
},
{
id: "24f74fec-fc8a-4c68-b31c-d126417ce3af",
Expand All @@ -41,7 +50,6 @@ test("it should update the variant to the source's value", async () => {
locale: "en",
selectors: [],
} satisfies NewMessage,
commit_id: "c8ad005b-a834-4ca3-84fb-9627546f2eba",
},
{
id: "aaf0ec32-0c7f-4d07-af8c-922ce382aef1",
Expand All @@ -61,7 +69,6 @@ test("it should update the variant to the source's value", async () => {
},
],
} satisfies NewVariant,
commit_id: "c8ad005b-a834-4ca3-84fb-9627546f2eba",
},
];

Expand All @@ -88,7 +95,6 @@ test("it should update the variant to the source's value", async () => {
meta: {
id: "6a860f96-0cf3-477c-80ad-7893d8fde852",
},
commit_id: "df455c78-b5ed-4df0-9259-7bb694c9d755",
},
];

Expand All @@ -97,11 +103,58 @@ test("it should update the variant to the source's value", async () => {
.values([...commonChanges, ...changesOnlyInSource])
.execute();

await source.lix.db
.insertInto("branch_change")
.values([
{
branch_id: currentSourceBranch.id,
change_id: "d92cdc2e-74cc-494c-8d51-958216272a17",
seq: 1,
},
{
branch_id: currentSourceBranch.id,
change_id: "24f74fec-fc8a-4c68-b31c-d126417ce3af",
seq: 2,
},
{
branch_id: currentSourceBranch.id,
change_id: "aaf0ec32-0c7f-4d07-af8c-922ce382aef1",
seq: 3,
},
{
branch_id: currentSourceBranch.id,
change_id: "01c059f9-8476-4aaa-aa6d-53ea3158b374",
seq: 4,
},
])
.execute();

await target.lix.db
.insertInto("change")
.values([...commonChanges, ...changesOnlyInTarget])
.execute();

await target.lix.db
.insertInto("branch_change")
.values([
{
branch_id: currentTargetBranch.id,
change_id: "d92cdc2e-74cc-494c-8d51-958216272a17",
seq: 1,
},
{
branch_id: currentTargetBranch.id,
change_id: "24f74fec-fc8a-4c68-b31c-d126417ce3af",
seq: 2,
},
{
branch_id: currentTargetBranch.id,
change_id: "aaf0ec32-0c7f-4d07-af8c-922ce382aef1",
seq: 3,
},
])
.execute();

await merge({ sourceLix: source.lix, targetLix: target.lix });

await target.lix.settled();
Expand All @@ -112,7 +165,8 @@ test("it should update the variant to the source's value", async () => {
});

const changes = await mergedProject.lix.db
.selectFrom("change")
.selectFrom("change_view")
.where("branch_id", "=", currentTargetBranch.id)
.selectAll()
.execute();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
import { test, expect } from "vitest";
import { newProject } from "../project/newProject.js";
import { loadProjectInMemory } from "../project/loadProjectInMemory.js";
import {
isInSimulatedCurrentBranch,
resolveConflictBySelecting,
} from "@lix-js/sdk";
import { resolveConflictBySelecting } from "@lix-js/sdk";
import { contentFromDatabase } from "sqlite-wasm-kysely";

test("it should resolve a conflict with the selected change", async () => {
Expand Down Expand Up @@ -138,31 +135,61 @@ test("it should resolve a conflict with the selected change", async () => {
.execute();
// ---------------

const currentBranch = await project.lix.db
.selectFrom("branch")
.select("id")
.where("active", "=", true)
.executeTakeFirstOrThrow();

await project.lix.db
.insertInto("branch_change")
.values([
{
id: "branch-change-1",
change_id: changes[0]?.id,
branch_id: currentBranch.id,
seq: 0,
},
{
id: "branch-change-2",
change_id: changes[1]?.id,
branch_id: currentBranch.id,
seq: 1,
},
{
id: "branch-change-3",
change_id: changes[2]?.id,
branch_id: currentBranch.id,
seq: 2,
},
{
id: "branch-change-4",
change_id: "samuels-change",
branch_id: currentBranch.id,
seq: 3,
},
{
id: "branch-change-5",
change_id: "peters-change",
branch_id: currentBranch.id,
seq: 4,
},
])
.execute();

const conflicts = await project.lix.db
.insertInto("conflict")
.values([
{
change_id: "samuels-change",
conflicting_change_id: "peters-change",
reason: "",
branch_id: currentBranch.id,
},
])
.returningAll()
.execute();

const changesInCurrentBranchBefore = await project.lix.db
.selectFrom("change")
.selectAll()
.where(isInSimulatedCurrentBranch)
.execute();

expect(changesInCurrentBranchBefore.map((c) => c.id)).toEqual([
changes[0]?.id,
changes[1]?.id,
changes[2]?.id,
"samuels-change",
]);

await resolveConflictBySelecting({
lix: project.lix,
conflict: conflicts[0]!,
Expand All @@ -172,15 +199,18 @@ test("it should resolve a conflict with the selected change", async () => {
await project.lix.settled();

const changesInCurrentBranch = await project.lix.db
.selectFrom("change")
.selectFrom("branch_change")
.leftJoin("change", "change.id", "branch_change.change_id")
.selectAll()
.where(isInSimulatedCurrentBranch)
.where("branch_id", "=", currentBranch.id)
.orderBy("seq")
.execute();

expect(changesInCurrentBranch.map((c) => c.id)).toEqual([
changes[0]?.id,
changes[1]?.id,
changes[2]?.id,
"samuels-change",
"peters-change",
]);
});
Loading
Loading