feat: introduce local-first SVG workbench
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { CommandHistory, createTransaction } from "../../src/commands/history";
|
||||
|
||||
describe("source transaction history", () => {
|
||||
it("undoes and redoes exact source without normalization", () => {
|
||||
const history = new CommandHistory();
|
||||
const transaction = createTransaction({
|
||||
label: "Set fill",
|
||||
baseRevision: 1,
|
||||
sourceBefore: "<svg><path/></svg>\r\n",
|
||||
sourceAfter: '<svg><path fill="red"/></svg>\r\n',
|
||||
});
|
||||
history.commit(transaction);
|
||||
expect(history.undo(transaction.sourceAfter)?.sourceBefore).toBe(
|
||||
transaction.sourceBefore,
|
||||
);
|
||||
expect(history.redo(transaction.sourceBefore)?.sourceAfter).toBe(
|
||||
transaction.sourceAfter,
|
||||
);
|
||||
});
|
||||
|
||||
it("coalesces rapid source-editor transactions with a shared merge key", () => {
|
||||
vi.spyOn(Date, "now").mockReturnValueOnce(100).mockReturnValueOnce(200);
|
||||
const history = new CommandHistory();
|
||||
history.commit(
|
||||
createTransaction({
|
||||
label: "Type",
|
||||
baseRevision: 0,
|
||||
sourceBefore: "a",
|
||||
sourceAfter: "ab",
|
||||
mergeKey: "typing",
|
||||
}),
|
||||
);
|
||||
history.commit(
|
||||
createTransaction({
|
||||
label: "Type",
|
||||
baseRevision: 1,
|
||||
sourceBefore: "ab",
|
||||
sourceAfter: "abc",
|
||||
mergeKey: "typing",
|
||||
}),
|
||||
);
|
||||
expect(history.snapshot.past).toHaveLength(1);
|
||||
expect(history.snapshot.past[0]).toMatchObject({
|
||||
sourceBefore: "a",
|
||||
sourceAfter: "abc",
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects stale undo and bounds history", () => {
|
||||
const history = new CommandHistory(2, 10_000);
|
||||
history.commit(
|
||||
createTransaction({
|
||||
label: "one",
|
||||
baseRevision: 0,
|
||||
sourceBefore: "a",
|
||||
sourceAfter: "b",
|
||||
}),
|
||||
);
|
||||
expect(() => history.undo("not-b")).toThrow(/stale/u);
|
||||
history.commit(
|
||||
createTransaction({
|
||||
label: "two",
|
||||
baseRevision: 1,
|
||||
sourceBefore: "b",
|
||||
sourceAfter: "c",
|
||||
}),
|
||||
);
|
||||
history.commit(
|
||||
createTransaction({
|
||||
label: "three",
|
||||
baseRevision: 2,
|
||||
sourceBefore: "c",
|
||||
sourceAfter: "d",
|
||||
}),
|
||||
);
|
||||
expect(history.snapshot.past).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user