You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
8.7 KiB

import { DiffGenerator, DiffType } from "../src/utils/diff.js";
import { Node, DiffNode, toPlainObject } from "./utils/tree.js";
function checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree) {
const diffTree = new DiffGenerator(newTree)
.compareWith(oldTree)
.withUniqueNodeId(node => node.id)
.generateDiffTree();
expect(diffTree).toEqual(expectedDiffTree);
}
describe("DiffGenerator", () => {
it("can generate a simple add diff", () => {
const oldTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, []),
new Node({ id: 4 }, []),
]);
const newTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, [
new Node({ id: 5 }, []),
]),
new Node({ id: 4 }, []),
]);
const diffTree = new DiffGenerator(newTree)
.compareWith(oldTree)
.withUniqueNodeId(node => node.id)
.withModifiedCheck(() => false)
.generateDiffTree();
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
new DiffNode({ id: 2 }, DiffType.NONE, []),
new DiffNode({ id: 3 }, DiffType.NONE, [
new DiffNode({ id: 5 }, DiffType.ADDED, []),
]),
new DiffNode({ id: 4 }, DiffType.NONE, []),
])
);
checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree);
});
it("can generate a simple delete diff", () => {
const oldTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, [
new Node({ id: 5 }, []),
]),
new Node({ id: 4 }, []),
]);
const newTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, []),
new Node({ id: 4 }, []),
]);
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
new DiffNode({ id: 2 }, DiffType.NONE, []),
new DiffNode({ id: 3 }, DiffType.NONE, [
new DiffNode({ id: 5 }, DiffType.DELETED, []),
]),
new DiffNode({ id: 4 }, DiffType.NONE, []),
])
);
checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree);
});
it("can generate a simple move diff", () => {
const oldTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, [
new Node({ id: 5 }, []),
]),
new Node({ id: 4 }, []),
]);
const newTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, []),
new Node({ id: 4 }, [
new Node({ id: 5 }, []),
]),
]);
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
new DiffNode({ id: 2 }, DiffType.NONE, []),
new DiffNode({ id: 3 }, DiffType.NONE, [
new DiffNode({ id: 5 }, DiffType.DELETED_MOVE, []),
]),
new DiffNode({ id: 4 }, DiffType.NONE, [
new DiffNode({ id: 5 }, DiffType.ADDED_MOVE, []),
]),
])
);
checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree);
});
it("can generate a simple modified diff", () => {
const oldTree = new Node({ id: 1, data: "xyz" }, [
new Node({ id: 2, data: "abc" }, []),
new Node({ id: 3, data: "123" }, []),
]);
const newTree = new Node({ id: 1, data: "xyz" }, [
new Node({ id: 2, data: "def" }, []),
new Node({ id: 3, data: "123" }, []),
]);
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1, data: "xyz" }, DiffType.NONE, [
new DiffNode({ id: 2, data: "def" }, DiffType.MODIFIED, []),
new DiffNode({ id: 3, data: "123" }, DiffType.NONE, []),
])
);
const diffTree = new DiffGenerator(newTree)
.compareWith(oldTree)
.withUniqueNodeId(node => node.id)
.withModifiedCheck(
(newNode, oldNode) => newNode.data != oldNode.data)
.generateDiffTree();
expect(diffTree).toEqual(expectedDiffTree);
});
it("can handle move and inner addition diff", () => {
const oldTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, [
new Node({ id: 4 }, []),
]),
]);
const newTree = new Node({ id: 1 }, [
new Node({ id: 2 }, [
new Node({ id: 4 }, [
new Node({ id: 5 }, []),
]),
]),
new Node({ id: 3 }, []),
]);
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
new DiffNode({ id: 2 }, DiffType.NONE, [
new DiffNode({ id: 4 }, DiffType.ADDED_MOVE, [
new DiffNode({ id: 5 }, DiffType.ADDED, []),
]),
]),
new DiffNode({ id: 3 }, DiffType.NONE, [
new DiffNode({ id: 4 }, DiffType.DELETED_MOVE, []),
]),
])
);
checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree);
});
it("can handle move within same level", () => {
const oldTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, []),
]);
const newTree = new Node({ id: 1 }, [
new Node({ id: 3 }, []),
new Node({ id: 2 }, []),
]);
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
new DiffNode({ id: 3 }, DiffType.NONE, []),
new DiffNode({ id: 2 }, DiffType.NONE, []),
])
);
checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree);
});
it("can handle addition within middle of level", () => {
const oldTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, []),
]);
const newTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 4 }, []),
new Node({ id: 3 }, []),
]);
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
new DiffNode({ id: 2 }, DiffType.NONE, []),
new DiffNode({ id: 4 }, DiffType.ADDED, []),
new DiffNode({ id: 3 }, DiffType.NONE, []),
])
);
checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree);
});
it("can handle deletion within middle of level", () => {
const oldTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, []),
new Node({ id: 4 }, []),
]);
const newTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 4 }, []),
]);
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
new DiffNode({ id: 2 }, DiffType.NONE, []),
new DiffNode({ id: 3 }, DiffType.DELETED, []),
new DiffNode({ id: 4 }, DiffType.NONE, []),
])
);
checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree);
});
it("fully visits deletes nodes", () => {
const oldTree = new Node({ id: 1 }, [
new Node({ id: 2 }, [
new Node({ id: 3 }, [
new Node({ id: 4 }, []),
]),
]),
]);
const newTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
new Node({ id: 3 }, [
new Node({ id: 4 }, []),
]),
]);
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
new DiffNode({ id: 2 }, DiffType.NONE, [
new DiffNode({ id: 3 }, DiffType.DELETED_MOVE, [
new DiffNode({ id: 4 }, DiffType.DELETED_MOVE, []),
]),
]),
new DiffNode({ id: 3 }, DiffType.ADDED_MOVE, [
new DiffNode({ id: 4 }, DiffType.NONE, []),
]),
])
);
checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree);
});
});